Set mmap_rnd_bits to maximum value.
This is a cherry-pick of internal commit:f611291688
which was a revert of a revert, specifically a revert of commit:c8f026fc9c
. The above revert was meant only for AOSP, since the kernel prebuilts were not yet available there. The revert was reverted internally so that internal builds, which have the appropriate kernel prebuilts, operated properly. The very first commit was originally done in nougat-dev and cherry-picked to AOSP, so it was not picked up again when nougat landed in master. Add it now. Bug: 27681085 Test: Builds and boots. Change-Id: If1cb6308e61aaaabca5b5bd30df78aab49e7b0d5
This commit is contained in:
parent
d619026c07
commit
baccc40841
113
init/init.cpp
113
init/init.cpp
|
@ -18,6 +18,7 @@
|
|||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <fstream>
|
||||
#include <inttypes.h>
|
||||
#include <libgen.h>
|
||||
#include <paths.h>
|
||||
|
@ -256,6 +257,112 @@ ret:
|
|||
return result;
|
||||
}
|
||||
|
||||
static void security_failure() {
|
||||
LOG(ERROR) << "Security failure...";
|
||||
panic();
|
||||
}
|
||||
|
||||
#define MMAP_RND_PATH "/proc/sys/vm/mmap_rnd_bits"
|
||||
#define MMAP_RND_COMPAT_PATH "/proc/sys/vm/mmap_rnd_compat_bits"
|
||||
|
||||
/* __attribute__((unused)) due to lack of mips support: see mips block
|
||||
* in set_mmap_rnd_bits_action */
|
||||
static bool __attribute__((unused)) set_mmap_rnd_bits_min(int start, int min, bool compat) {
|
||||
std::string path;
|
||||
if (compat) {
|
||||
path = MMAP_RND_COMPAT_PATH;
|
||||
} else {
|
||||
path = MMAP_RND_PATH;
|
||||
}
|
||||
std::ifstream inf(path, std::fstream::in);
|
||||
if (!inf) {
|
||||
LOG(ERROR) << "Cannot open for reading: " << path;
|
||||
return false;
|
||||
}
|
||||
while (start >= min) {
|
||||
// try to write out new value
|
||||
std::string str_val = std::to_string(start);
|
||||
std::ofstream of(path, std::fstream::out);
|
||||
if (!of) {
|
||||
LOG(ERROR) << "Cannot open for writing: " << path;
|
||||
return false;
|
||||
}
|
||||
of << str_val << std::endl;
|
||||
of.close();
|
||||
|
||||
// check to make sure it was recorded
|
||||
inf.seekg(0);
|
||||
std::string str_rec;
|
||||
inf >> str_rec;
|
||||
if (str_val.compare(str_rec) == 0) {
|
||||
break;
|
||||
}
|
||||
start--;
|
||||
}
|
||||
inf.close();
|
||||
if (start < min) {
|
||||
LOG(ERROR) << "Unable to set minimum required entropy " << min << " in " << path;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set /proc/sys/vm/mmap_rnd_bits and potentially
|
||||
* /proc/sys/vm/mmap_rnd_compat_bits to the maximum supported values.
|
||||
* Returns -1 if unable to set these to an acceptable value.
|
||||
*
|
||||
* To support this sysctl, the following upstream commits are needed:
|
||||
*
|
||||
* d07e22597d1d mm: mmap: add new /proc tunable for mmap_base ASLR
|
||||
* e0c25d958f78 arm: mm: support ARCH_MMAP_RND_BITS
|
||||
* 8f0d3aa9de57 arm64: mm: support ARCH_MMAP_RND_BITS
|
||||
* 9e08f57d684a x86: mm: support ARCH_MMAP_RND_BITS
|
||||
* ec9ee4acd97c drivers: char: random: add get_random_long()
|
||||
* 5ef11c35ce86 mm: ASLR: use get_random_long()
|
||||
*/
|
||||
static int set_mmap_rnd_bits_action(const std::vector<std::string>& args)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
/* values are arch-dependent */
|
||||
#if defined(__aarch64__)
|
||||
/* arm64 supports 18 - 33 bits depending on pagesize and VA_SIZE */
|
||||
if (set_mmap_rnd_bits_min(33, 24, false)
|
||||
&& set_mmap_rnd_bits_min(16, 16, true)) {
|
||||
ret = 0;
|
||||
}
|
||||
#elif defined(__x86_64__)
|
||||
/* x86_64 supports 28 - 32 bits */
|
||||
if (set_mmap_rnd_bits_min(32, 32, false)
|
||||
&& set_mmap_rnd_bits_min(16, 16, true)) {
|
||||
ret = 0;
|
||||
}
|
||||
#elif defined(__arm__) || defined(__i386__)
|
||||
/* check to see if we're running on 64-bit kernel */
|
||||
bool h64 = !access(MMAP_RND_COMPAT_PATH, F_OK);
|
||||
/* supported 32-bit architecture must have 16 bits set */
|
||||
if (set_mmap_rnd_bits_min(16, 16, h64)) {
|
||||
ret = 0;
|
||||
}
|
||||
#elif defined(__mips__) || defined(__mips64__)
|
||||
// TODO: add mips support b/27788820
|
||||
ret = 0;
|
||||
#else
|
||||
ERROR("Unknown architecture\n");
|
||||
#endif
|
||||
|
||||
#ifdef __BRILLO__
|
||||
// TODO: b/27794137
|
||||
ret = 0;
|
||||
#endif
|
||||
if (ret == -1) {
|
||||
LOG(ERROR) << "Unable to set adequate mmap entropy value!";
|
||||
security_failure();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int keychord_init_action(const std::vector<std::string>& args)
|
||||
{
|
||||
keychord_init();
|
||||
|
@ -414,11 +521,6 @@ static int audit_callback(void *data, security_class_t /*cls*/, char *buf, size_
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void security_failure() {
|
||||
LOG(ERROR) << "Security failure...";
|
||||
panic();
|
||||
}
|
||||
|
||||
static void selinux_initialize(bool in_kernel_domain) {
|
||||
Timer t;
|
||||
|
||||
|
@ -712,6 +814,7 @@ int main(int argc, char** argv) {
|
|||
am.QueueBuiltinAction(wait_for_coldboot_done_action, "wait_for_coldboot_done");
|
||||
// ... so that we can start queuing up actions that require stuff from /dev.
|
||||
am.QueueBuiltinAction(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");
|
||||
am.QueueBuiltinAction(set_mmap_rnd_bits_action, "set_mmap_rnd_bits");
|
||||
am.QueueBuiltinAction(keychord_init_action, "keychord_init");
|
||||
am.QueueBuiltinAction(console_init_action, "console_init");
|
||||
|
||||
|
|
Loading…
Reference in New Issue