diff --git a/init/Android.bp b/init/Android.bp index 3ff17672c..1381c1d25 100644 --- a/init/Android.bp +++ b/init/Android.bp @@ -143,6 +143,7 @@ cc_defaults { "libcgrouprc_format", "liblmkd_utils", "libmodprobe", + "libprocinfo", "libprotobuf-cpp-lite", "libpropertyinfoserializer", "libpropertyinfoparser", @@ -308,6 +309,7 @@ cc_binary { "libsnapshot_cow", "libsnapshot_init", "update_metadata-protos", + "libprocinfo", ], static_executable: true, diff --git a/init/Android.mk b/init/Android.mk index 65ee385de..3c7d95acf 100644 --- a/init/Android.mk +++ b/init/Android.mk @@ -130,6 +130,7 @@ LOCAL_STATIC_LIBRARIES := \ libsnapshot_cow \ libsnapshot_init \ update_metadata-protos \ + libprocinfo \ LOCAL_SANITIZE := signed-integer-overflow # First stage init is weird: it may start without stdout/stderr, and no /proc. diff --git a/init/snapuserd_transition.cpp b/init/snapuserd_transition.cpp index 19b5c57a0..40467b7d3 100644 --- a/init/snapuserd_transition.cpp +++ b/init/snapuserd_transition.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -34,6 +35,7 @@ #include #include #include +#include #include #include "block_dev_initializer.h" @@ -157,6 +159,33 @@ SnapuserdSelinuxHelper::SnapuserdSelinuxHelper(std::unique_ptr& }); } +static void LockAllSystemPages() { + bool ok = true; + auto callback = [&](const android::procinfo::MapInfo& map) -> void { + if (!ok || android::base::StartsWith(map.name, "/dev/") || + !android::base::StartsWith(map.name, "/")) { + return; + } + auto start = reinterpret_cast(map.start); + auto len = map.end - map.start; + if (!len) { + return; + } + if (mlock(start, len) < 0) { + LOG(ERROR) << "mlock failed, " << start << " for " << len << " bytes."; + ok = false; + } + }; + + if (!android::procinfo::ReadProcessMaps(getpid(), callback) || !ok) { + LOG(FATAL) << "Could not process /proc/" << getpid() << "/maps file for init, " + << "falling back to mlockall()."; + if (mlockall(MCL_CURRENT) < 0) { + LOG(FATAL) << "mlockall failed"; + } + } +} + void SnapuserdSelinuxHelper::StartTransition() { LOG(INFO) << "Starting SELinux transition of snapuserd"; @@ -170,9 +199,7 @@ void SnapuserdSelinuxHelper::StartTransition() { // We cannot access /system after the transition, so make sure init is // pinned in memory. - if (mlockall(MCL_CURRENT) < 0) { - LOG(FATAL) << "mlockall failed"; - } + LockAllSystemPages(); argv_.emplace_back("snapuserd"); argv_.emplace_back("-no_socket");