Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use 48-bit address space via 4 level page tables on arm64 by default #284

Open
thestinger opened this issue Apr 22, 2023 · 0 comments
Open

Comments

@thestinger
Copy link

thestinger commented Apr 22, 2023

Linux kernel defaults to 39-bit address space, providing far weaker ASLR entropy than x86_64 and also making it incompatible with hardened_malloc in the default configuration since there's not enough space. It also weakens other mitigations based on using large PROT_NONE gaps. Even a 48-bit address space limits these features quite a lot and 39-bit is barely usable if you want to quarantine address space for freed allocations, add lots of random sized guard regions including userspace allocated regions with high entropy bases, etc.

https://github.com/GrapheneOS/hardened_malloc

We change this in the defconfigs for Android Generic Kernel Images, but the defaults can be changed in the configuration setup instead:

GrapheneOS/kernel_common-5.15@82c2afe
GrapheneOS/kernel_common-5.15@5a4ec3d

Unfortunately, a fair bit of software (particularly proprietary game engines) have ended up incompatible with a 48-bit address space on arm64 due to things like using pointer bits for tagging. GrapheneOS had to develop GrapheneOS/kernel_common-5.15@ff8f099 in order to deploy a 48-bit address space with a user facing toggle in the OS. This is NOT relevant for server side usage or new ecosystems. It's an issue that has developed specifically in the Android app ecosystem and is mostly contained to certain game engines like older versions of Unity.

Changing the default in the upstream kernel doesn't change it for existing downstream setups with an existing configuration, but it would start improving things for existing users.

39 bit means 256GiB of address space for userspace as opposed to 128TiB with 48-bit. That's a huge difference. It is a big deal even just for memory mapped databases on servers, etc.

The performance overhead for the additional page table level isn't very noticeable in most cases and has been accepted on x86_64 for years. In fact, they're starting to introduce 5 level page tables for certain uses. I think it makes sense for arm64 to have parity with x86_64 in this regard by default, especially with it being used more and more on servers, laptops and even workstations. Moving from x86_64 to arm64 shouldn't bring this huge regression. Some people may view 3 level page tables as a better compromise but doesn't it make sense to have consistency by default? Also, the issue of many Android games not being compatible with 48-bit never would have happened if it had simply been used from the start. No need to worry about apps becoming incompatible with 39-bit since so many devices already use it and will remain relevant for at least around 8 years.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant