Can native code cause memory corruption in Java code in Android?

On Android, when we call native code via JNI, can it damage VM Dalvik and the Java code running inside it?

For example, suppose we have this C method and we call it via JNI:

JNIEXPORT void JNICALL Java_MemoryCorruptor_corruptMemory()
{
    while (1) {
        char *p = randomAddress();
        *p = randomChar();
    }
}

      

If the VM is just loading .so files, and the native code is running in the same context / address space as the VM, then I'm guessing the VM might be corrupted.

On the other hand, if the VM creates a child process to store .so files and uses some form of IPC to invoke methods, then Java code cannot be corrupted by native code.

+3


source to share


1 answer


The inner code runs in the same process as the Java code it interacts with via JNI, so yes, it is very capable of corrupting key data structures. More often than not, you can see this as a glitch in the library that implements the VM itself, shortly after returning from the wrong code, but in theory, another thread might be wrong.

To the extent that there is isolation between the native and VM-hosted code of the same process, it is simply that the information needed to usefully and safely modify the implementation data structures is only available to a limited extent on certain JNI support calls - but all of this is subject to a knotty chain. if your own code does it. Of course, it's also possible that your code will crash the process by attempting illegal access. Depending on the implementation details of the virtual machine, some of the "code" of the application may map well to read-only memory pages, and attempting to write them may cause a memory protection error. However, the data and any JIT code written on the fly will presumably be on writable pages. And actively nefarious code can change the protection parameters,replacing read-only read-only files for writable anonymous pages with the same content, if necessary.



You can run Android app components in a separate process, but it will have its own VM wrapper for whatever JNI code is used there. Classes like Activity and Service are mostly Java layer, even if you use JNI glue of stock Java code to work in the native version. For example, some web browser applications may do this to slightly isolate their javascript interpreter mechanisms.

It was also possible (as of today) to run an independent process just for a native and talk to it through IPC, however this is discouraged as it lacks lifecycles to manage Android and there are some tricks of its part you will have to do yourself. In addition, such a program cannot use most of the Java-defined APIs of the Android platform, or at least not in portable mode. Historically, people have resorted to this primarily when using a su root shim on a compromised device to run a helper process running as superuser, or occasionally as a path to port a complex Linux-style tool without re-archiving it as a JNI Library.

+6


source







All Articles