GrapheneOS version 2024083100 came out a few days ago with a lot of new hardening features and enhancements. Here is a quick rundown of what they are:
DCL control lists
Dynamic Code Loading (DCL) is a practice in Android apps to allow loading/executing code that is not part of the initial codebase (i.e. the APK) either from storage or memory. Some apps use this, while the practice is heavily discouraged on official Android documentation.
Apps that perform dynamic code execution have larger attack surface for injection and tampering attacks. It also makes the app more time-consuming to reverse engineer and verify. Being able to forcibly disable them for apps can close some of these risks. We completely forbid dynamic code generation for the base OS including preventing doing it via memory mapped files or the filesystem already as part of GrapheneOS hardening, so this is not relevant to system apps.
GrapheneOS now has a per-app dynamic code loading restriction toggle for dynamic code from memory and from storage, there is also a global toggle for dynamic code from memory, but per-app storage does not have it as many apps depend on Google's dynamite module system for Google Play which still needs phasing out.
WebView JIT Toggle
Any app that uses WebView can now have a per-app toggle for allowing JavaScript JIT in the WebView. Vanadium already has a toggle to block JIT which is on by default.
JavaScript JIT increases attack surface for memory-related vulnerabilities in web browsers. A large portion of known vulnerabilities from browsers come from the JIT engine. Many Chromium (and firefox) exploits in the wild or bugs discovered in contests traditionally come from V8 and JIT (or relevant equivalents).
Exploitation of browsers is popular in targeted campaigns, including this recently uncovered campaign of an alleged North Korean state actor using a then unknown V8 vulnerability: https://www.microsoft.com/en-us/security/blog/2024/08/30/north-korean-threat-actor-citrine-sleet-exploiting-chromium-zero-day/ - not using JIT significantly cuts the attack surface involved in making attacks like these successful.
Toggling JIT in WebView will allow you to disable it if it breaks certain apps, it is better to have it on though.
RANDSTRUCT (Kernel 6.1 and above)
GrapheneOS now enables structure randomization (or
randstruct
) for releases using Kernel 6.1 and later. At the time of writing only the 9th generation Pixels use this, but upstream should migrate eventually.A potential technique for attacking the Linux kernel is using memory boundary flaws to overwrite data of memory structures. When the order of that fields are stored within a structure is known, it is easy to calculate where sensitive fields reside. Sensitive fields can be function pointers, which could be overwritten with a location containing malicious code that the kernel can then execute, or security credentials, which can be used in privilege escalation attacks.
Enabling RANDSTRUCT in kernel randomizes the order of structures and function pointer tables at compile-time based on a seed. This means that kernel exploits leveraging them need to be catered to specific seeds which makes indiscriminate attacks ineffective. Currently, the seed changes every OS release and is the hash of the latest commit. This is to make sure GrapheneOS is still reproducible.
In the future, there will be different seeds for each device, not just each OS version.
Accessing new features
All the user toggles can be accessed via the GrapheneOS Exploit Protection safety center:
RANDSTRUCT is not a toggleable option and is just kernel hardening.