debugd: Pass absolute path to rma_fw_keeper
Original code verifies the absolute path of image_file and ro_db_dir.
But then provides the original image_file and ro_db_dir to rma_fw_keeper
as arguments. This allows for malicious filenames to be passed to the
script as long as it is a symlink which resolves to a valid firmware
file path.
BUG=chromium:1329946, b:234192237
TEST=FEATURES=test emerge-${BOARD} debugd
TEST=Verify the commands in crbug/1329946 used to exploit the bug no
longer works.
Change-Id: I50f9e4b52e8744393e0d970ab9901de7f668b882
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/3691194
Tested-by: Yi-An Chen <chenyian@google.com>
Commit-Queue: Yi-An Chen <chenyian@google.com>
Reviewed-by: Jorge Lucangeli Obes <jorgelo@chromium.org>
Reviewed-by: Aashay Shringarpure <aashay@google.com>
(cherry picked from commit c5f3d339d8f0a05d420e01ba41b339f43301a58d)
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/3717710
Commit-Queue: Aashay Shringarpure <aashay@google.com>
diff --git a/debugd/src/verify_ro_tool.cc b/debugd/src/verify_ro_tool.cc
index b7db0f6..8d9f19d 100644
--- a/debugd/src/verify_ro_tool.cc
+++ b/debugd/src/verify_ro_tool.cc
@@ -39,15 +39,20 @@
const std::string& image_file,
const std::string& ro_db_dir,
std::string* handle) {
- if (!CheckCr50ResourceLocation(image_file, false /* is_dir */)) {
+ base::FilePath image_absolute_path =
+ base::MakeAbsoluteFilePath(base::FilePath(image_file));
+ base::FilePath ro_db_absolute_path =
+ base::MakeAbsoluteFilePath(base::FilePath(ro_db_dir));
+
+ if (!CheckCr50ResourceLocation(image_absolute_path, false /* is_dir */)) {
DEBUGD_ADD_ERROR(error, kVerifyRoToolErrorString,
- "Bad FW image file: " + image_file);
+ "Bad FW image file: " + image_absolute_path.value());
return false;
}
- if (!CheckCr50ResourceLocation(ro_db_dir, true /* is_dir */)) {
+ if (!CheckCr50ResourceLocation(ro_db_absolute_path, true /* is_dir */)) {
DEBUGD_ADD_ERROR(error, kVerifyRoToolErrorString,
- "Bad ro descriptor dir: " + ro_db_dir);
+ "Bad ro descriptor dir: " + ro_db_absolute_path.value());
return false;
}
@@ -61,8 +66,8 @@
}
p->AddArg(kCr50VerifyRoScript);
- p->AddArg(image_file);
- p->AddArg(ro_db_dir);
+ p->AddArg(image_absolute_path.value());
+ p->AddArg(ro_db_absolute_path.value());
p->BindFd(outfd.get(), STDOUT_FILENO);
p->BindFd(outfd.get(), STDERR_FILENO);
@@ -84,10 +89,8 @@
return true;
}
-bool VerifyRoTool::CheckCr50ResourceLocation(const std::string& path,
- bool is_dir) {
- base::FilePath absolute_path =
- base::MakeAbsoluteFilePath(base::FilePath(path));
+bool VerifyRoTool::CheckCr50ResourceLocation(
+ const base::FilePath& absolute_path, bool is_dir) {
if (absolute_path.empty()) {
// |path| doesn't exist.
return false;
diff --git a/debugd/src/verify_ro_tool.h b/debugd/src/verify_ro_tool.h
index be89259..67a249a 100644
--- a/debugd/src/verify_ro_tool.h
+++ b/debugd/src/verify_ro_tool.h
@@ -35,10 +35,11 @@
std::string* handle);
private:
- // Checks and returns if |path| points to a valid cr50 resource location,
- // i.e., a file or dir under /opt/google/cr50. If |is_dir| is set, returns
- // false if |path| isn't a dir.
- bool CheckCr50ResourceLocation(const std::string& path, bool is_dir);
+ // Checks and returns if |absolute_path| points to a valid cr50 resource
+ // location, i.e., a file or dir under /opt/google/cr50. If |is_dir| is set,
+ // returns false if |absolute_path| isn't a dir.
+ bool CheckCr50ResourceLocation(const base::FilePath& absolute_path,
+ bool is_dir);
};
} // namespace debugd