Search code examples
javaandroidcjava-native-interfaceroot

Give root access to C/C++ native side of an Android application using JNI, it seems to be impossible


I'd like to make the native code gain root access, even if the Java side correctly has root privileges... and it seems to be quite challenging.

Example app:

Java side

[...]
Log.d(TAG, "JAVA ROOT? " + rootManager.runCommand("id -u").getMessage()); // has the process 
root access?
rootTest(); // this is the native C function
Log.d(TAG, "JAVA ROOT? " + rootManager.runCommand("id -u").getMessage()); // check again
[...]

C side

JNIEXPORT jlong JNICALL Java_com_example_MainActivity_testRoot(JNIEnv* env, jobject obj) {

    FILE *fp;
    char path[1035];

    fp = popen("id -u", "r");
    while (fgets(path, sizeof(path), fp) != NULL) {
        printf("C ROOT?: %s\r\n", path);
    }
    pclose(fp);
    return 0;
}

Output

JAVA ROOT? 0 // -> Yeah, root!
C ROOT?: 10114 // -> :(
JAVA ROOT? 0 // -> Java side still has root.

I don't know why, but when the process executes his native code, it loses root permissions. Is this for a sort-of security reason? If yes, can it be disabled?


Solution

  • You cannot use rootManager.runCommand to magically elevate your process or thread to root. The best you can do is spawn a different process (that's what runCommand does) as root and talk to it using various IPC mechanisms.