libprocessgroup: Support write to file feature
There may be some use cases that it needs to write string to a
file. This patch support write "Value" to "FilePath", where
both parameters could use special string "<uid>" and "<pid>" to
represent actual uid and pid.
Bug: 170507963
Test: function works
Change-Id: I543846f523518a9bcb3dd1b3437163a1b3157d95
diff --git a/libprocessgroup/task_profiles.cpp b/libprocessgroup/task_profiles.cpp
index a638fca..4e767db 100644
--- a/libprocessgroup/task_profiles.cpp
+++ b/libprocessgroup/task_profiles.cpp
@@ -24,6 +24,7 @@
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
#include <android-base/threads.h>
#include <cutils/android_filesystem_config.h>
@@ -38,6 +39,7 @@
using android::base::GetThreadId;
using android::base::StringPrintf;
+using android::base::StringReplace;
using android::base::unique_fd;
using android::base::WriteStringToFile;
@@ -257,6 +259,39 @@
return true;
}
+bool WriteFileAction::ExecuteForProcess(uid_t uid, pid_t pid) const {
+ std::string filepath(filepath_), value(value_);
+
+ filepath = StringReplace(filepath, "<uid>", std::to_string(uid), true);
+ filepath = StringReplace(filepath, "<pid>", std::to_string(pid), true);
+ value = StringReplace(value, "<uid>", std::to_string(uid), true);
+ value = StringReplace(value, "<pid>", std::to_string(pid), true);
+
+ if (!WriteStringToFile(value, filepath)) {
+ PLOG(ERROR) << "Failed to write '" << value << "' to " << filepath;
+ return false;
+ }
+
+ return true;
+}
+
+bool WriteFileAction::ExecuteForTask(int tid) const {
+ std::string filepath(filepath_), value(value_);
+ int uid = getuid();
+
+ filepath = StringReplace(filepath, "<uid>", std::to_string(uid), true);
+ filepath = StringReplace(filepath, "<pid>", std::to_string(tid), true);
+ value = StringReplace(value, "<uid>", std::to_string(uid), true);
+ value = StringReplace(value, "<pid>", std::to_string(tid), true);
+
+ if (!WriteStringToFile(value, filepath)) {
+ PLOG(ERROR) << "Failed to write '" << value << "' to " << filepath;
+ return false;
+ }
+
+ return true;
+}
+
bool ApplyProfileAction::ExecuteForProcess(uid_t uid, pid_t pid) const {
for (const auto& profile : profiles_) {
if (!profile->ExecuteForProcess(uid, pid)) {
@@ -459,6 +494,18 @@
} else {
LOG(WARNING) << "SetClamps: invalid parameter: " << boost_value;
}
+ } else if (action_name == "WriteFile") {
+ std::string attr_filepath = params_val["FilePath"].asString();
+ std::string attr_value = params_val["Value"].asString();
+ if (!attr_filepath.empty() && !attr_value.empty()) {
+ profile->Add(std::make_unique<WriteFileAction>(attr_filepath, attr_value));
+ } else if (attr_filepath.empty()) {
+ LOG(WARNING) << "WriteFile: invalid parameter: "
+ << "empty filepath";
+ } else if (attr_value.empty()) {
+ LOG(WARNING) << "WriteFile: invalid parameter: "
+ << "empty value";
+ }
} else {
LOG(WARNING) << "Unknown profile action: " << action_name;
}