|
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
RISE-2007001
Apple Mac OS X 10.4.x kernel shared_region_map_file_np() memory corruption
vulnerability
Released: January 19, 2007
Last updated: January 19, 2007
INTRODUCTION
There exists a vulnerability within a function of the Apple Mac OS X 10.4.x
kernel (Apple Mac OS X 1.4.8 and lower), which when properly exploited
can lead
to local compromise of the vulnerable system.
This vulnerability was confirmed by us in the up-to-date Apple Mac OS X
1.4.8
(8L2127).
DETAILS
The kernel provides a mechanism for system-wide memory sharing, the Shared
Memory Server subsystem. Using this facility, both the kernel and user
programs
can share code and data among all tasks on the system. It is also
possible to
give one or more tasks private versions of the shared memory.
shared_region_map_file_np() is used by dyld to map parts of a split-segment
library in the global shared read-only and read-write regions. dyld
parses the
load commands in the library file and prepares an array of shared region
mapping
structures, each of which specifies the address, size, and protection
values of
a single mapping. It passes this array along with an open file
descriptor for
the library to shared_region_map_file_np(), which attempts to establish
each of
the requested mappings. shared_region_map_file_np() also takes as an
argument a
pointer to an address variable: If the pointer is non-NULL and the requested
mappings cannot fit in the target address space as desired, the kernel will
attempt to slide (move around) the mappings to make them fit. The resultant
slide value is returned in the address variable. If the pointer is NULL
instead,
the call returns an error without attempting to slide.
This vulnerability can be triggered by calling the
shared_region_map_file_np()
system call with a high mapping_count value, which due to lack of bounds
checking will result in the consumption of all available operating system
resources.
This is part of the vulnerable function from Apple Mac OS X 1.4.8.
/*
* Get the list of mappings the caller wants us to establish.
*/
mapping_count = uap->mappingCount; /* the number of mappings */
mappings_size = (vm_size_t) (mapping_count * sizeof (mappings[0]));
if (mapping_count == 0) {
SHARED_REGION_TRACE(
SHARED_REGION_TRACE_INFO,
("shared_region: %p [%d(%s)] map_file(%p:'%s'): "
"no mappings\n",
current_thread(), p->p_pid, p->p_comm,
vp, vp->v_name));
error = 0; /* no mappings: we're done ! */
goto done;
} else if (mapping_count <= SFM_MAX_STACK) {
mappings = &stack_mappings[0];
} else {
if ((mach_vm_size_t) mappings_size ! (mach_vm_size_t) mapping_count * sizeof (mappings[0])) {
/* 32-bit integer overflow */
error = EINVAL;
goto done;
}
kr = kmem_alloc(kernel_map,
(vm_offset_t *) &mappings,
mappings_size);
A little proof of concept code that triggers this vulnerability can be found
in appendix section of this document.
VENDOR
Vendor was notified, as this is not a critical vulnerability, proper
corrections
should be available soon.
CREDITS
This vulnerability was discovered by Adriano Lima