x86_64: mmap rnd bits: Allow min bits of less than 32
With a regular x86 kernel we are always able to get 32
min bits for mmap randomization.
However to emulate 16KB for x86 app developers the kernel
can only provide 30 bits for the randomization due the to
larger page size (PAGE_SHIFT =+ 2).
Allow the min rand bits to be (32 - (PAGE_SHIFT - 12)) in
order to generically support larger than 4KB page sizes.
This should be a no-op change for all devices, except the
x86 16KB emulator, since they will always be able to get
32 random bits.
Bug: 309816695
Test: Boot test 4k x86 device
Test: Boot test emulated 16k x86 device
Change-Id: I48d47d56ac3aecb71a9e0093a7033bb60b89c2b7
Signed-off-by: Kalesh Singh <kaleshsingh@google.com>
diff --git a/init/security.cpp b/init/security.cpp
index 0c73fae..3e15447 100644
--- a/init/security.cpp
+++ b/init/security.cpp
@@ -20,6 +20,7 @@
#include <errno.h>
#include <fcntl.h>
#include <linux/perf_event.h>
+#include <math.h>
#include <selinux/selinux.h>
#include <sys/ioctl.h>
#include <sys/syscall.h>
@@ -121,8 +122,12 @@
}
#elif defined(__x86_64__)
// x86_64 supports 28 - 32 rnd bits, but Android wants to ensure that the
- // theoretical maximum of 32 bits is always supported and used.
- if (SetMmapRndBitsMin(32, 32, false) && (!Has32BitAbi() || SetMmapRndBitsMin(16, 16, true))) {
+ // theoretical maximum of 32 bits is always supported and used; except in
+ // the case of the x86 page size emulator which supports a maximum
+ // of 30 bits for 16k page size, or 28 bits for 64k page size.
+ int max_bits = 32 - (static_cast<int>(log2(getpagesize())) - 12);
+ if (SetMmapRndBitsMin(max_bits, max_bits, false) &&
+ (!Has32BitAbi() || SetMmapRndBitsMin(16, 16, true))) {
return {};
}
#elif defined(__arm__) || defined(__i386__)