From e419a79329819ee49c184d29acf626f1b2599537 Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Wed, 6 Mar 2019 15:18:46 -0800 Subject: [PATCH] ueventd: populate /dev/block/mapper link Since DM_NAME= is not sent (delete bug) or interpreted with ueventd message, instead probe /sys/devices/virtual/block/dm-X/dm/name when instantiating. Cache the value for later delete. By creating the /dev/block/mapper/ nodes, this will give selabel_lookup_best_match an alias to hang its hat on so that the associated /dev/block/dm-X nodes will be suitably labelled and differentiated. NB: For Android, the deletion of the nodes will only happen in the context of fastbootd, update_engine and gsid; otherwise the links and properties created can be considered set-once and persistent. Test: manual inspect /dev/block/mapper/ links Bug: 124072565 Change-Id: I6d9e467970dfdad7b67754ad61084964251eb05f --- init/devices.cpp | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/init/devices.cpp b/init/devices.cpp index 1a77ba19d..159c75e03 100644 --- a/init/devices.cpp +++ b/init/devices.cpp @@ -21,8 +21,14 @@ #include #include +#include +#include #include +#include +#include +#include +#include #include #include #include @@ -37,12 +43,16 @@ #error "Do not include init.h in files used by ueventd; it will expose init's globals" #endif +using namespace std::chrono_literals; + using android::base::Basename; using android::base::Dirname; +using android::base::ReadFileToString; using android::base::Readlink; using android::base::Realpath; using android::base::StartsWith; using android::base::StringPrintf; +using android::base::Trim; namespace android { namespace init { @@ -101,6 +111,31 @@ static bool FindVbdDevicePrefix(const std::string& path, std::string* result) { return true; } +// Given a path that may start with a virtual dm block device, populate +// the supplied buffer with the dm module's instantiated name. +// If it doesn't start with a virtual block device, or there is some +// error, return false. +static bool FindDmDevicePartition(const std::string& path, std::string* result) { + result->clear(); + if (!StartsWith(path, "/devices/virtual/block/dm-")) return false; + if (getpid() == 1) return false; // first_stage_init has no sepolicy needs + + static std::map cache; + // wait_for_file will not work, the content is also delayed ... + for (android::base::Timer t; t.duration() < 200ms; std::this_thread::sleep_for(10ms)) { + if (ReadFileToString("/sys" + path + "/dm/name", result) && !result->empty()) { + // Got it, set cache with result, when node arrives + cache[path] = *result = Trim(*result); + return true; + } + } + auto it = cache.find(path); + if ((it == cache.end()) || (it->second.empty())) return false; + // Return cached results, when node goes away + *result = it->second; + return true; +} + Permissions::Permissions(const std::string& name, mode_t perm, uid_t uid, gid_t gid) : name_(name), perm_(perm), uid_(uid), gid_(gid), prefix_(false), wildcard_(false) { // Set 'prefix_' or 'wildcard_' based on the below cases: @@ -293,6 +328,7 @@ void SanitizePartitionName(std::string* string) { std::vector DeviceHandler::GetBlockDeviceSymlinks(const Uevent& uevent) const { std::string device; std::string type; + std::string partition; if (FindPlatformDevice(uevent.path, &device)) { // Skip /devices/platform or /devices/ if present @@ -310,6 +346,8 @@ std::vector DeviceHandler::GetBlockDeviceSymlinks(const Uevent& uev type = "pci"; } else if (FindVbdDevicePrefix(uevent.path, &device)) { type = "vbd"; + } else if (FindDmDevicePartition(uevent.path, &partition)) { + return {"/dev/block/mapper/" + partition}; } else { return {}; }