Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a6abd821 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Allow to drop existing fd cache of cgroup path

A process can give up the permission to set cgroup. If we still
keep the fd that was cached before losing the permission, when
the process sets scheduling group, it will write to the cached
fd without checking if is accessible and lead to sepolicy denied.

Bug: 123043091
Test: Build and boot.
Test: A new process from zygote set cgroup and drop fd cache, and
      then specializes to app domain. There is no sepolicy denied
      when the process creates new thread.
      (android::thread_data_t::trampoline)

Change-Id: I285ee91424ea965ea9c670fc0f6662948e3e2ce5
parent ad6f656b
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -39,6 +39,11 @@ static constexpr const char* CGROUPS_RC_PATH = "/dev/cgroup_info/cgroup.rc";

bool UsePerAppMemcg();

// Drop the fd cache of cgroup path. It is used for when resource caching is enabled and a process
// loses the access to the path, the access checking (See SetCgroupAction::EnableResourceCaching)
// should be active again. E.g. Zygote specialization for child process.
void DropTaskProfilesResourceCaching();

// Return 0 and removes the cgroup if there are no longer any processes in it.
// Returns -1 in the case of an error occurring or if there are processes still running
// even after retrying for up to 200ms.
+4 −0
Original line number Diff line number Diff line
@@ -111,6 +111,10 @@ static bool isMemoryCgroupSupported() {
    return memcg_supported;
}

void DropTaskProfilesResourceCaching() {
    TaskProfiles::GetInstance().DropResourceCaching();
}

bool SetProcessProfiles(uid_t uid, pid_t pid, const std::vector<std::string>& profiles,
                        bool use_fd_cache) {
    const TaskProfiles& tp = TaskProfiles::GetInstance();
+27 −0
Original line number Diff line number Diff line
@@ -173,6 +173,15 @@ void SetCgroupAction::EnableResourceCaching() {
    fd_ = std::move(fd);
}

void SetCgroupAction::DropResourceCaching() {
    std::lock_guard<std::mutex> lock(fd_mutex_);
    if (fd_ == FDS_NOT_CACHED) {
        return;
    }

    fd_.reset(FDS_NOT_CACHED);
}

bool SetCgroupAction::AddTidToCgroup(int tid, int fd) {
    if (tid <= 0) {
        return true;
@@ -292,6 +301,24 @@ void TaskProfile::EnableResourceCaching() {
    res_cached_ = true;
}

void TaskProfile::DropResourceCaching() {
    if (!res_cached_) {
        return;
    }

    for (auto& element : elements_) {
        element->DropResourceCaching();
    }

    res_cached_ = false;
}

void TaskProfiles::DropResourceCaching() const {
    for (auto& iter : profiles_) {
        iter.second->DropResourceCaching();
    }
}

TaskProfiles& TaskProfiles::GetInstance() {
    // Deliberately leak this object to avoid a race between destruction on
    // process exit and concurrent access from another thread.
+4 −0
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ class ProfileAction {
    virtual bool ExecuteForTask(int) const { return false; };

    virtual void EnableResourceCaching() {}
    virtual void DropResourceCaching() {}
};

// Profile actions
@@ -114,6 +115,7 @@ class SetCgroupAction : public ProfileAction {
    virtual bool ExecuteForProcess(uid_t uid, pid_t pid) const;
    virtual bool ExecuteForTask(int tid) const;
    virtual void EnableResourceCaching();
    virtual void DropResourceCaching();

    const CgroupController* controller() const { return &controller_; }
    std::string path() const { return path_; }
@@ -145,6 +147,7 @@ class TaskProfile {
    bool ExecuteForProcess(uid_t uid, pid_t pid) const;
    bool ExecuteForTask(int tid) const;
    void EnableResourceCaching();
    void DropResourceCaching();

  private:
    bool res_cached_;
@@ -158,6 +161,7 @@ class TaskProfiles {

    TaskProfile* GetProfile(const std::string& name) const;
    const ProfileAttribute* GetAttribute(const std::string& name) const;
    void DropResourceCaching() const;

  private:
    std::map<std::string, std::unique_ptr<TaskProfile>> profiles_;