CVE-2016-2494

high
Published 2016-06-13 ยท Modified 2026-05-06
CVSS v3
7.8
CVSS:3.0/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
CVSS v4 NEW
โ€”
not yet in upstream
VIR risk
8.8

Description

Off-by-one error in sdcard/sdcard.c in Android 4.x before 4.4.4, 5.0.x before 5.0.2, 5.1.x before 5.1.1, and 6.x before 2016-06-01 allows attackers to gain privileges via a crafted application, as demonstrated by obtaining Signature or SignatureOrSystem access, aka internal bug 28085658.

Predictions

Exploit likelihood
75%
Patch ETA
โ€”

Heuristic predictions, AS-IS, for prioritization only.

Mitigations

No mitigations published for this CVE yet.

The vendor-content worker queues fetches as references arrive (check back in a few minutes). Or โ€” if you've already worked around this in production โ€” publish your fix to the community-verified tier.

โœš Propose a mitigation on Community โ†’ Mitigations published via the community go through AI scoring + 2 human reviewers + 7-day silent objection window before landing here with source_tier=community-verified.

Exploits

Public proof-of-concept code below. AS-IS, for defenders and authorised testing only.

Exploit-DB

EDB-39921 dos android verified text ยท 4 KB
Google Security Research ยท 2016-06-10

Google Android - '/system/bin/sdcard' Stack Buffer Overflow (PoC)

text exploit Source: Exploit-DB
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=798

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:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/39921.zip

References

CWEs

CWE-264

Community-verified mitigations for this CVE will appear above when contributors publish them.

Verify integrity in audit chain (admin only). AS-IS.