Google Android - systembinsdcard Stack Buffer Overflow (PoC)

Type exploitpack
Reporter Google Security Research
Modified 2016-06-10T00:00:00


Google Android - systembinsdcard Stack Buffer Overflow (PoC)


Android: Stack-buffer-overflow in /system/bin/sdcard

There's an integer overflow issue in get_node_path_locked, which results in 
a buffer overflow. For all of the calling paths, this is going to overflow a 
stack buffer in the parent function:

static ssize_t get_node_path_locked(struct node* node, char* buf, size_t bufsize) {
    const char* name;
    size_t namelen;
    if (node->graft_path) {
        name = node->graft_path;
        namelen = node->graft_pathlen;
    } else if (node->actual_name) {
        name = node->actual_name;
        namelen = node->namelen;
    } else {
        name = node->name;
        namelen = node->namelen;

    // when bufsize == namelen + 1
    if (bufsize < namelen + 1) {
        return -1;

    ssize_t pathlen = 0;
    if (node->parent && node->graft_path == NULL) {
        // bufsize - namelen - 2 overflows to SIZE_MAX
        pathlen = get_node_path_locked(node->parent, buf, bufsize - namelen - 2);
        if (pathlen < 0) {
            return -1;
        buf[pathlen++] = '/';

    memcpy(buf + pathlen, name, namelen + 1); /* include trailing \0 */
    return pathlen + namelen;

This can be triggered by a malicious app creating a directory structure in
/sdcard with a total path length longer than PATH_MAX, which can be achieved by
creating a directory heirarchy starting with several directories with short 
names and later renaming these parent directories to have longer names. See the
attached POC, which can be run from the 'untrusted_app' selinux domain.

It appears that the overflow is close enough to the bottom of the stack that 
with a large overflow we can corrupt thread data that is used before the stack 
cookie is checked, suggesting that this issue is possibly exploitable despite 
the presence of stack cookies.

(gdb) i r
r0             0xb	11
r1             0x1	1
r2             0x41414199	1094795673
r3             0x41414141	1094795585
r4             0x80000000	2147483648
r5             0x0	0
r6             0xb6e40ec0	3068399296
r7             0xb6cbe860	3066816608
r8             0xb6e4930c	3068433164
r9             0xb6e3c594	3068380564
r10            0xbee4c9ac	3202664876
r11            0xb6943180	3063165312
r12            0xb6e3c908	3068381448
sp             0xb6cbe7a0	0xb6cbe7a0
lr             0xb6e1daad	-1226712403
pc             0xb6e06ade	0xb6e06ade <pthread_getspecific(pthread_key_t)+34>
cpsr           0x80070030	-2147024848
(gdb) x/10i $pc
=> 0xb6e06ade <pthread_getspecific(pthread_key_t)+34>:	ldr	r4, [r2, #100]	; 0x64
   0xb6e06ae0 <pthread_getspecific(pthread_key_t)+36>:	cmp	r4, r1
   0xb6e06ae2 <pthread_getspecific(pthread_key_t)+38>:	bne.n	0xb6e06aec <pthread_getspecific(pthread_key_t)+48>
   0xb6e06ae4 <pthread_getspecific(pthread_key_t)+40>:	ldr	r0, [r2, #104]	; 0x68
   0xb6e06ae6 <pthread_getspecific(pthread_key_t)+42>:	pop	{r4, pc}
   0xb6e06ae8 <pthread_getspecific(pthread_key_t)+44>:	movs	r0, #0
   0xb6e06aea <pthread_getspecific(pthread_key_t)+46>:	pop	{r4, pc}
   0xb6e06aec <pthread_getspecific(pthread_key_t)+48>:	adds	r0, #12
   0xb6e06aee <pthread_getspecific(pthread_key_t)+50>:	add.w	r12, r3, r0, lsl #3
   0xb6e06af2 <pthread_getspecific(pthread_key_t)+54>:	movs	r0, #0
(gdb) bt
#0  0xb6e06ade in pthread_getspecific (key=11) at bionic/libc/bionic/pthread_key.cpp:160
#1  0xb6e1daac in je_tsd_wrapper_get () at external/jemalloc/include/jemalloc/internal/tsd.h:609
#2  je_tsd_get () at external/jemalloc/include/jemalloc/internal/tsd.h:609
#3  je_tsd_fetch () at external/jemalloc/include/jemalloc/internal/tsd.h:614
#4  imalloc_body (usize=<synthetic pointer>, tsd=<synthetic pointer>, size=4) at external/jemalloc/src/jemalloc.c:1401
#5  je_malloc (size=4) at external/jemalloc/src/jemalloc.c:1423
#6  0xb6f3bb3e in handle_open (fuse=0xbee478c8, hdr=0xbee4c984, req=<optimized out>, handler=<optimized out>)
    at system/core/sdcard/sdcard.c:1193
#7  0x41414140 in ?? ()

Proof of Concept: