diff --git a/libprocessgroup/task_profiles.cpp b/libprocessgroup/task_profiles.cpp index a638fcac6..4e767db52 100644 --- a/libprocessgroup/task_profiles.cpp +++ b/libprocessgroup/task_profiles.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -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 @@ bool SetCgroupAction::ExecuteForTask(int tid) const { return true; } +bool WriteFileAction::ExecuteForProcess(uid_t uid, pid_t pid) const { + std::string filepath(filepath_), value(value_); + + filepath = StringReplace(filepath, "", std::to_string(uid), true); + filepath = StringReplace(filepath, "", std::to_string(pid), true); + value = StringReplace(value, "", std::to_string(uid), true); + value = StringReplace(value, "", 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, "", std::to_string(uid), true); + filepath = StringReplace(filepath, "", std::to_string(tid), true); + value = StringReplace(value, "", std::to_string(uid), true); + value = StringReplace(value, "", 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 @@ bool TaskProfiles::Load(const CgroupMap& cg_map, const std::string& file_name) { } 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(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; } diff --git a/libprocessgroup/task_profiles.h b/libprocessgroup/task_profiles.h index 2983a09b3..98bcb0ea7 100644 --- a/libprocessgroup/task_profiles.h +++ b/libprocessgroup/task_profiles.h @@ -139,6 +139,19 @@ class SetCgroupAction : public ProfileAction { bool IsFdValid() const { return fd_ > FDS_INACCESSIBLE; } }; +// Write to file action +class WriteFileAction : public ProfileAction { + public: + WriteFileAction(const std::string& filepath, const std::string& value) noexcept + : filepath_(filepath), value_(value) {} + + virtual bool ExecuteForProcess(uid_t uid, pid_t pid) const; + virtual bool ExecuteForTask(int tid) const; + + private: + std::string filepath_, value_; +}; + class TaskProfile { public: TaskProfile() : res_cached_(false) {}