JNI and native libraries introduce their own memory-safety and input-validation responsibilities. Protection in the Java or Kotlin layer does not establish coverage of native code.
Evaluation approach
Review types, lifetimes and error handling across the JNI boundary. Include the library built for every ABI in protection and testing coverage.
Application example
Compare package and device tests to verify that protection working on ARM64 behaves as expected on other distributed architectures.
Limits and considerations
Moving business logic into C or C++ does not automatically make it secure.
Changing languages does not remove a trust boundary
Moving critical code to C or C++ can make analysis harder, but it does not create security automatically. Different failure classes can arise, including memory-safety, input-size and lifecycle defects. Review data conversions at the JNI boundary separately.
A native module runs in the same application process, so do not assume it forms a trust zone completely independent of managed code. Analysis and testing should cover both Java or Kotlin flows and native functions. Symbols and architecture information help reproduce failures.
Checks and decisions
- Validate JNI inputs
- Compare ABI outputs
- Test memory defects separately
Verify native-file versions and protection coverage for every ABI.
Sources
The primary references above provide the technical basis. Example workflows and evaluation suggestions are this publication’s explanations, not independent test results for a particular product.