It is well known that the use of native methods in Java defeats Java's guarantees of safety and security, which is why the default policy of Java applets, for example, does not allow loading non-local native code. However, there is already a large amount of trusted native C/C++ code that comprises a significant portion of the Java Development Kit (JDK). We have carried out an empirical security study on a portion of the native code in Sun's JDK 1.6. By applying static analysis tools and manual inspection, we have identified in this security-critical code previously undiscovered bugs. Based on our study, we describe a taxonomy to classify bugs. Our taxonomy provides guidance to construction of automated and accurate bug-finding tools. We also suggest systematic remedies that can mediate the threats posed by the native code.
Yann-Gaël Guéhéneuc, 2013/10/15
The authors make a good case for the need to study multi-language systems, arguing that large amount of trusted native C/C++ code are currently in use in versions of the JDK but that interactions between the Java code and the C/C++ code have not been studied in depth. They observed that there are 800,000 lines of C/C++ code in JDK v1.6 (v6u2). They divide this code in two: library code (typically the functional code) and interface code (allowing the passing of control- and data-flow between Java code and C/C++ code).
Then, the authors describe their study of the JNI code using existing tools and some ad hoc scripts, mostly based on grep. What is missing with respect to the tools is a comprehensive survey of the existing tools and their usefulness in the context of multi-language systems. It seems that the authors used only tools targeting the C/C++ code and they developed ad hoc scripts to find bug patterns between Java and C/C++ code.
Then, the authors introduce six bug patterns that are due to the interactions between the Java and C/C++ code, mostly due to mismatch between the computation models of Java and C/C++ or wrong assumptions from the developers. These bug patterns are:
Some of the bug patterns require fairly complex scenarios, for example the use of reflection to modify private fields. Although an attacker could try to perform modify private fields, it is unclear how often such scenario really could and would occur in practice. Yet, the authors provide some directions to fix the bug patterns. However, some of these solutions are ad hoc and leave doubt as their efficiency, like the use of indirection tables of pointers to avoid an attacker changing a Java integer value used as a pointer. Indeed, what would prevent the very same attacker to change the content of the indirection table? The authors nonetheless point at interesting direction, like the use of software fault isolation.
The conclusion is that many bug patterns exist, probably more than discussed in the paper, but that their current detection are at best ad hoc. It would be interesting to study how to describe and detect systematically (1) missing bound checks, (2) missing JNI release memory calls, (3) missing access controls to private Java fields/methods from the C/C++ code, etc. Also, tools supporting multi-language systems are necessary because most tools “analyze C code alone, without consideration how the Java side interacts with the C side”. The tools should handle real programming languages, not some “well-defined subset of C such as Cminor” because then they become useless with real code.