0

Amazing discovery of the day: JNI on Android lets you access object fields that you're not supposed to, according to Java rules.

Is this capability to bypass access restrictions documented anywhere? Is this an official JNI behavior or specific to the Android flavor of JNI? Is this an undefined behavior? Will the OOP police come for me any moment now?

I understand that relying on unpublished object fields is inherently dangerous and may break anytime; that's not the question here.

UPDATE: looks like applications that target API28 no longer have this capability.

Seva Alekseyev
  • 59,826
  • 25
  • 160
  • 281
  • 1
    You know that you can do same thing without help of JNI? Just use the reflection to set/get private fields in objects: http://stackoverflow.com/questions/1196192/how-do-i-read-a-private-field-in-java – Mārtiņš Možeiko Oct 13 '12 at 03:27
  • Yes, that's normal in Java, but we can block out things like that with a `SecurityManager` if you need that level of security. – Samuel Audet Oct 13 '12 at 06:28
  • @SamuelAudet Can `SecurityManager` block also breaking the encapsulation from JNI layer? – yohjp Oct 13 '12 at 06:34
  • You can prevent loading arbitrary libraries, and only allow the use of approved libraries. This is how Java applets do it BTW. – Samuel Audet Oct 13 '12 at 08:15

2 Answers2

1

The problem has been described and even addressed in an article, or rather proposal published back in 2006.

Note that Javs defines SecurityManager class, but it considers all JNI calls as security breach and thus your question is a non-issue from their standpoint, like asking "why can I get elevation to Administrator when I only install some driver/service?".

But on Android, things are even more explicit. The official documentation describes this class with the following preface:

Legacy security code; do not use.

Security managers do not provide a secure environment for executing untrusted code. Untrusted code cannot be safely isolated within the Dalvik VM.

(the emphasis is theirs)

If you are looking for stronger words that guarantee that access to native fields and methods from JNI will not go away in a next version of Android, good luck to you.

On the other hand, the chances are higher that some future version of Android will change the names or signatures of some private fields and methods. Moreover, they can change the implementation such that the filed remains, but must be used differently.

Finally note, that all these considerations apply not only to private or package private methods, but also to public methods and fields that did not make it into the official documentation!

Alex Cohn
  • 56,089
  • 9
  • 113
  • 307
0

Amazing discovery of the day: JNI on Android lets you access object fields that you're not supposed to, according to Java rules.

The abbreviation JNI does not appear anywhere in the question and answers that you linked to, except as a dynamically-generated link to this very question.

Is this documented anywhere?

Any decent book on Java development should cover public, private, etc.

Is this an official JNI behavior or Android-specific?

Neither.

What is Android-specific is compile-time steps to make it difficult for you to add code in some android, java, and javax packages.

Is this an undefined behavior?

That depends on what underlying noun or concept you are tying to tying to the pronoun "this".

If "this" is "accessing private, etc. stuff", then the behavior is not undefined.

If "this" is "accessing something specific private, etc. in the Android framework", that is undefined. There are many, many versions of Android around, and many, many versions of framework classes. Their internal implementations are not identical. Anything not exposed via the Android SDK is eligible for change by Google, device manufacturers, ROM mod maintainers, etc.

Community
  • 1
  • 1
CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • The [android-ndk] both here and in the linked question tag clearly points at JNI. By "this" I mean "successfully accessing private or package-private fileds of a class from native methods of another, unrelated class in another package". I'll edit the question for posterity. – Seva Alekseyev Oct 13 '12 at 13:47
  • @SevaAlekseyev: FWIW, there is no `android-ndk` tag on the question that you linked to and that I cited in my opening paragraph ("Accessing package-private fields in Java"). There *is* an `android-ndk` tag on the other question that you linked to ("Shared memory region in NDK"), but that was not the one that I cited and not the one where you discovered this Java capability. I apologize for the confusion over my citations. – CommonsWare Oct 13 '12 at 13:56
  • No, I've discovered the capability in the first one. The second one is where I was making sure I shouldn't be able to do that, either via JNI or via Java :) – Seva Alekseyev Oct 13 '12 at 14:28