Fix uses-after-free
The code was previously taking the address of the device_name
string and passing it to execve (via an argument vector passed to
logwrap_fork_execvp) after device_name goes out of scope. Moreover,
the code for adding the length argument pushed the address of a
temporary to the vector. Fix it by having the code create a vector of
std::string for the arguments and only creating the vector of const
char * before calling logwrap_fork_execvp.
Bug: 376533537
Change-Id: Ic066cd9a1d3be5a1a7e6ad997f81166c039bbcaf
diff --git a/fs/F2fs.cpp b/fs/F2fs.cpp
index 4cdddec..c52e80e 100644
--- a/fs/F2fs.cpp
+++ b/fs/F2fs.cpp
@@ -75,7 +75,7 @@
status_t Format(const std::string& source, bool is_zoned,
const std::vector<std::string>& user_devices,
const std::vector<bool>& device_aliased, int64_t length) {
- std::vector<char const*> cmd;
+ std::vector<std::string> cmd;
/* '-g android' parameter passed here which defaults the sector size to 4096 */
static constexpr int kSectorSize = 4096;
cmd.emplace_back(kMkfsPath);
@@ -112,19 +112,23 @@
std::filesystem::path path = device_name;
device_name += "@" + path.filename().string();
}
- cmd.emplace_back(device_name.c_str());
+ cmd.emplace_back(device_name);
}
- std::string block_size = std::to_string(getpagesize());
cmd.emplace_back("-b");
- cmd.emplace_back(block_size.c_str());
+ cmd.emplace_back(std::to_string(getpagesize()));
cmd.emplace_back(source.c_str());
if (length) {
- cmd.emplace_back(std::to_string(length / kSectorSize).c_str());
+ cmd.emplace_back(std::to_string(length / kSectorSize));
}
- return logwrap_fork_execvp(cmd.size(), cmd.data(), nullptr, false, LOG_KLOG,
- false, nullptr);
+
+ std::vector<char const*> cmd_cstrs;
+ for (auto& arg : cmd) {
+ cmd_cstrs.emplace_back(arg.c_str());
+ }
+ return logwrap_fork_execvp(cmd_cstrs.size(), cmd_cstrs.data(), nullptr, false, LOG_KLOG, false,
+ nullptr);
}
} // namespace f2fs