diff options
author | Suchang Woo <suchang.woo@samsung.com> | 2021-04-06 11:22:49 +0900 |
---|---|---|
committer | David Anderson <dvander@google.com> | 2021-04-16 13:35:10 -0700 |
commit | 22fdd0ae13c566527cedc7caf5c96f0a4e5536d4 (patch) | |
tree | 4e01496e2e1dfc8379337932172de962cd444e79 /init/firmware_handler.cpp | |
parent | 78e26beb0278bc4b1ec185bf4ab4c041a4e53ac5 (diff) |
ueventd: Allow pattern matching to find external firmware handler
Only the exact same devpath uevent can launch external handler specified
in ueventd.rc. So, you should specify all possible devpaths, even
firmware with different filenames on the same device. Pattern mactching
can be used to simplify this.
Test: atest CtsInitTestCases
Signed-off-by: Suchang Woo <suchang.woo@samsung.com>
Change-Id: If3b7a2cabb8055bf4b768d928f0fc0012da3c177
Diffstat (limited to 'init/firmware_handler.cpp')
-rw-r--r-- | init/firmware_handler.cpp | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/init/firmware_handler.cpp b/init/firmware_handler.cpp index ba7e6bd63..bdc292275 100644 --- a/init/firmware_handler.cpp +++ b/init/firmware_handler.cpp @@ -17,6 +17,7 @@ #include "firmware_handler.h" #include <fcntl.h> +#include <fnmatch.h> #include <glob.h> #include <pwd.h> #include <signal.h> @@ -46,6 +47,20 @@ using android::base::WriteFully; namespace android { namespace init { +namespace { +bool PrefixMatch(const std::string& pattern, const std::string& path) { + return android::base::StartsWith(path, pattern); +} + +bool FnMatch(const std::string& pattern, const std::string& path) { + return fnmatch(pattern.c_str(), path.c_str(), 0) == 0; +} + +bool EqualMatch(const std::string& pattern, const std::string& path) { + return pattern == path; +} +} // namespace + static void LoadFirmware(const std::string& firmware, const std::string& root, int fw_fd, size_t fw_size, int loading_fd, int data_fd) { // Start transfer. @@ -66,6 +81,22 @@ static bool IsBooting() { return access("/dev/.booting", F_OK) == 0; } +ExternalFirmwareHandler::ExternalFirmwareHandler(std::string devpath, uid_t uid, + std::string handler_path) + : devpath(std::move(devpath)), uid(uid), handler_path(std::move(handler_path)) { + auto wildcard_position = this->devpath.find('*'); + if (wildcard_position != std::string::npos) { + if (wildcard_position == this->devpath.length() - 1) { + this->devpath.pop_back(); + match = std::bind(PrefixMatch, this->devpath, std::placeholders::_1); + } else { + match = std::bind(FnMatch, this->devpath, std::placeholders::_1); + } + } else { + match = std::bind(EqualMatch, this->devpath, std::placeholders::_1); + } +} + FirmwareHandler::FirmwareHandler(std::vector<std::string> firmware_directories, std::vector<ExternalFirmwareHandler> external_firmware_handlers) : firmware_directories_(std::move(firmware_directories)), @@ -160,7 +191,7 @@ Result<std::string> FirmwareHandler::RunExternalHandler(const std::string& handl std::string FirmwareHandler::GetFirmwarePath(const Uevent& uevent) const { for (const auto& external_handler : external_firmware_handlers_) { - if (external_handler.devpath == uevent.path) { + if (external_handler.match(uevent.path)) { LOG(INFO) << "Launching external firmware handler '" << external_handler.handler_path << "' for devpath: '" << uevent.path << "' firmware: '" << uevent.firmware << "'"; |