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

Commit f5d22ef7 authored by Steven Moreland's avatar Steven Moreland
Browse files

init: log when 'user' is unspecified

NOTE: in master, but should be submitted in AOSP.
Waiting to hear from security folks. Also might
need cleanup.

Not currently done. Seems errorprone.

Bug: 276813155
Test: boot, check logs
Change-Id: I7cbc39b282889dd582f06a8eedc38ae637c8edec
parent b2fdbef4
Loading
Loading
Loading
Loading
+18 −18
Original line number Original line Diff line number Diff line
@@ -140,9 +140,10 @@ bool Service::is_exec_service_running_ = false;


Service::Service(const std::string& name, Subcontext* subcontext_for_restart_commands,
Service::Service(const std::string& name, Subcontext* subcontext_for_restart_commands,
                 const std::string& filename, const std::vector<std::string>& args)
                 const std::string& filename, const std::vector<std::string>& args)
    : Service(name, 0, 0, 0, {}, 0, "", subcontext_for_restart_commands, filename, args) {}
    : Service(name, 0, std::nullopt, 0, {}, 0, "", subcontext_for_restart_commands, filename,
              args) {}


Service::Service(const std::string& name, unsigned flags, uid_t uid, gid_t gid,
Service::Service(const std::string& name, unsigned flags, std::optional<uid_t> uid, gid_t gid,
                 const std::vector<gid_t>& supp_gids, int namespace_flags,
                 const std::vector<gid_t>& supp_gids, int namespace_flags,
                 const std::string& seclabel, Subcontext* subcontext_for_restart_commands,
                 const std::string& seclabel, Subcontext* subcontext_for_restart_commands,
                 const std::string& filename, const std::vector<std::string>& args)
                 const std::string& filename, const std::vector<std::string>& args)
@@ -153,7 +154,7 @@ Service::Service(const std::string& name, unsigned flags, uid_t uid, gid_t gid,
      crash_count_(0),
      crash_count_(0),
      proc_attr_{.ioprio_class = IoSchedClass_NONE,
      proc_attr_{.ioprio_class = IoSchedClass_NONE,
                 .ioprio_pri = 0,
                 .ioprio_pri = 0,
                 .uid = uid,
                 .parsed_uid = uid,
                 .gid = gid,
                 .gid = gid,
                 .supp_gids = supp_gids,
                 .supp_gids = supp_gids,
                 .priority = 0},
                 .priority = 0},
@@ -205,9 +206,9 @@ void Service::KillProcessGroup(int signal, bool report_oneshot) {
        int max_processes = 0;
        int max_processes = 0;
        int r;
        int r;
        if (signal == SIGTERM) {
        if (signal == SIGTERM) {
            r = killProcessGroupOnce(proc_attr_.uid, pid_, signal, &max_processes);
            r = killProcessGroupOnce(uid(), pid_, signal, &max_processes);
        } else {
        } else {
            r = killProcessGroup(proc_attr_.uid, pid_, signal, &max_processes);
            r = killProcessGroup(uid(), pid_, signal, &max_processes);
        }
        }


        if (report_oneshot && max_processes > 0) {
        if (report_oneshot && max_processes > 0) {
@@ -228,7 +229,7 @@ void Service::KillProcessGroup(int signal, bool report_oneshot) {


void Service::SetProcessAttributesAndCaps(InterprocessFifo setsid_finished) {
void Service::SetProcessAttributesAndCaps(InterprocessFifo setsid_finished) {
    // Keep capabilites on uid change.
    // Keep capabilites on uid change.
    if (capabilities_ && proc_attr_.uid) {
    if (capabilities_ && uid()) {
        // If Android is running in a container, some securebits might already
        // If Android is running in a container, some securebits might already
        // be locked, so don't change those.
        // be locked, so don't change those.
        unsigned long securebits = prctl(PR_GET_SECUREBITS);
        unsigned long securebits = prctl(PR_GET_SECUREBITS);
@@ -255,7 +256,7 @@ void Service::SetProcessAttributesAndCaps(InterprocessFifo setsid_finished) {
        if (!SetCapsForExec(*capabilities_)) {
        if (!SetCapsForExec(*capabilities_)) {
            LOG(FATAL) << "cannot set capabilities for " << name_;
            LOG(FATAL) << "cannot set capabilities for " << name_;
        }
        }
    } else if (proc_attr_.uid) {
    } else if (uid()) {
        // Inheritable caps can be non-zero when running in a container.
        // Inheritable caps can be non-zero when running in a container.
        if (!DropInheritableCaps()) {
        if (!DropInheritableCaps()) {
            LOG(FATAL) << "cannot drop inheritable caps for " << name_;
            LOG(FATAL) << "cannot drop inheritable caps for " << name_;
@@ -434,8 +435,8 @@ Result<void> Service::ExecStart() {
    flags_ |= SVC_EXEC;
    flags_ |= SVC_EXEC;
    is_exec_service_running_ = true;
    is_exec_service_running_ = true;


    LOG(INFO) << "SVC_EXEC service '" << name_ << "' pid " << pid_ << " (uid " << proc_attr_.uid
    LOG(INFO) << "SVC_EXEC service '" << name_ << "' pid " << pid_ << " (uid " << uid() << " gid "
              << " gid " << proc_attr_.gid << "+" << proc_attr_.supp_gids.size() << " context "
              << proc_attr_.gid << "+" << proc_attr_.supp_gids.size() << " context "
              << (!seclabel_.empty() ? seclabel_ : "default") << ") started; waiting...";
              << (!seclabel_.empty() ? seclabel_ : "default") << ") started; waiting...";


    reboot_on_failure.Disable();
    reboot_on_failure.Disable();
@@ -475,13 +476,13 @@ Result<void> Service::CheckConsole() {
// Configures the memory cgroup properties for the service.
// Configures the memory cgroup properties for the service.
void Service::ConfigureMemcg() {
void Service::ConfigureMemcg() {
    if (swappiness_ != -1) {
    if (swappiness_ != -1) {
        if (!setProcessGroupSwappiness(proc_attr_.uid, pid_, swappiness_)) {
        if (!setProcessGroupSwappiness(uid(), pid_, swappiness_)) {
            PLOG(ERROR) << "setProcessGroupSwappiness failed";
            PLOG(ERROR) << "setProcessGroupSwappiness failed";
        }
        }
    }
    }


    if (soft_limit_in_bytes_ != -1) {
    if (soft_limit_in_bytes_ != -1) {
        if (!setProcessGroupSoftLimit(proc_attr_.uid, pid_, soft_limit_in_bytes_)) {
        if (!setProcessGroupSoftLimit(uid(), pid_, soft_limit_in_bytes_)) {
            PLOG(ERROR) << "setProcessGroupSoftLimit failed";
            PLOG(ERROR) << "setProcessGroupSoftLimit failed";
        }
        }
    }
    }
@@ -508,7 +509,7 @@ void Service::ConfigureMemcg() {
    }
    }


    if (computed_limit_in_bytes != size_t(-1)) {
    if (computed_limit_in_bytes != size_t(-1)) {
        if (!setProcessGroupLimit(proc_attr_.uid, pid_, computed_limit_in_bytes)) {
        if (!setProcessGroupLimit(uid(), pid_, computed_limit_in_bytes)) {
            PLOG(ERROR) << "setProcessGroupLimit failed";
            PLOG(ERROR) << "setProcessGroupLimit failed";
        }
        }
    }
    }
@@ -705,21 +706,20 @@ Result<void> Service::Start() {
    if (CgroupsAvailable()) {
    if (CgroupsAvailable()) {
        bool use_memcg = swappiness_ != -1 || soft_limit_in_bytes_ != -1 || limit_in_bytes_ != -1 ||
        bool use_memcg = swappiness_ != -1 || soft_limit_in_bytes_ != -1 || limit_in_bytes_ != -1 ||
                         limit_percent_ != -1 || !limit_property_.empty();
                         limit_percent_ != -1 || !limit_property_.empty();
        errno = -createProcessGroup(proc_attr_.uid, pid_, use_memcg);
        errno = -createProcessGroup(uid(), pid_, use_memcg);
        if (errno != 0) {
        if (errno != 0) {
            Result<void> result = cgroups_activated.Write(kActivatingCgroupsFailed);
            Result<void> result = cgroups_activated.Write(kActivatingCgroupsFailed);
            if (!result.ok()) {
            if (!result.ok()) {
                return Error() << "Sending notification failed: " << result.error();
                return Error() << "Sending notification failed: " << result.error();
            }
            }
            return Error() << "createProcessGroup(" << proc_attr_.uid << ", " << pid_ << ", "
            return Error() << "createProcessGroup(" << uid() << ", " << pid_ << ", " << use_memcg
                           << use_memcg << ") failed for service '" << name_
                           << ") failed for service '" << name_ << "': " << strerror(errno);
                           << "': " << strerror(errno);
        }
        }


        // When the blkio controller is mounted in the v1 hierarchy, NormalIoPriority is
        // When the blkio controller is mounted in the v1 hierarchy, NormalIoPriority is
        // the default (/dev/blkio). When the blkio controller is mounted in the v2 hierarchy, the
        // the default (/dev/blkio). When the blkio controller is mounted in the v2 hierarchy, the
        // NormalIoPriority profile has to be applied explicitly.
        // NormalIoPriority profile has to be applied explicitly.
        SetProcessProfiles(proc_attr_.uid, pid_, {"NormalIoPriority"});
        SetProcessProfiles(uid(), pid_, {"NormalIoPriority"});


        if (use_memcg) {
        if (use_memcg) {
            ConfigureMemcg();
            ConfigureMemcg();
@@ -727,7 +727,7 @@ Result<void> Service::Start() {
    }
    }


    if (oom_score_adjust_ != DEFAULT_OOM_SCORE_ADJUST) {
    if (oom_score_adjust_ != DEFAULT_OOM_SCORE_ADJUST) {
        LmkdRegister(name_, proc_attr_.uid, pid_, oom_score_adjust_);
        LmkdRegister(name_, uid(), pid_, oom_score_adjust_);
    }
    }


    if (Result<void> result = cgroups_activated.Write(kCgroupsActivated); !result.ok()) {
    if (Result<void> result = cgroups_activated.Write(kCgroupsActivated); !result.ok()) {
+2 −2
Original line number Original line Diff line number Diff line
@@ -71,7 +71,7 @@ class Service {
    Service(const std::string& name, Subcontext* subcontext_for_restart_commands,
    Service(const std::string& name, Subcontext* subcontext_for_restart_commands,
            const std::string& filename, const std::vector<std::string>& args);
            const std::string& filename, const std::vector<std::string>& args);


    Service(const std::string& name, unsigned flags, uid_t uid, gid_t gid,
    Service(const std::string& name, unsigned flags, std::optional<uid_t> uid, gid_t gid,
            const std::vector<gid_t>& supp_gids, int namespace_flags, const std::string& seclabel,
            const std::vector<gid_t>& supp_gids, int namespace_flags, const std::string& seclabel,
            Subcontext* subcontext_for_restart_commands, const std::string& filename,
            Subcontext* subcontext_for_restart_commands, const std::string& filename,
            const std::vector<std::string>& args);
            const std::vector<std::string>& args);
@@ -115,7 +115,7 @@ class Service {
    pid_t pid() const { return pid_; }
    pid_t pid() const { return pid_; }
    android::base::boot_clock::time_point time_started() const { return time_started_; }
    android::base::boot_clock::time_point time_started() const { return time_started_; }
    int crash_count() const { return crash_count_; }
    int crash_count() const { return crash_count_; }
    uid_t uid() const { return proc_attr_.uid; }
    uid_t uid() const { return proc_attr_.uid(); }
    gid_t gid() const { return proc_attr_.gid; }
    gid_t gid() const { return proc_attr_.gid; }
    int namespace_flags() const { return namespaces_.flags; }
    int namespace_flags() const { return namespaces_.flags; }
    const std::vector<gid_t>& supp_gids() const { return proc_attr_.supp_gids; }
    const std::vector<gid_t>& supp_gids() const { return proc_attr_.supp_gids; }
+6 −1
Original line number Original line Diff line number Diff line
@@ -534,7 +534,7 @@ Result<void> ServiceParser::ParseUser(std::vector<std::string>&& args) {
    if (!uid.ok()) {
    if (!uid.ok()) {
        return Error() << "Unable to find UID for '" << args[1] << "': " << uid.error();
        return Error() << "Unable to find UID for '" << args[1] << "': " << uid.error();
    }
    }
    service_->proc_attr_.uid = *uid;
    service_->proc_attr_.parsed_uid = *uid;
    return {};
    return {};
}
}


@@ -677,6 +677,11 @@ Result<void> ServiceParser::EndSection() {
        return {};
        return {};
    }
    }


    if (service_->proc_attr_.parsed_uid == std::nullopt) {
        LOG(WARNING) << "No user specified for service '" << service_->name()
                     << "'. Defaults to root.";
    }

    if (interface_inheritance_hierarchy_) {
    if (interface_inheritance_hierarchy_) {
        if (const auto& check_hierarchy_result = CheckInterfaceInheritanceHierarchy(
        if (const auto& check_hierarchy_result = CheckInterfaceInheritanceHierarchy(
                    service_->interfaces(), *interface_inheritance_hierarchy_);
                    service_->interfaces(), *interface_inheritance_hierarchy_);
+2 −2
Original line number Original line Diff line number Diff line
@@ -271,8 +271,8 @@ Result<void> SetProcessAttributes(const ProcessAttributes& attr, InterprocessFif
    if (setgroups(attr.supp_gids.size(), const_cast<gid_t*>(&attr.supp_gids[0])) != 0) {
    if (setgroups(attr.supp_gids.size(), const_cast<gid_t*>(&attr.supp_gids[0])) != 0) {
        return ErrnoError() << "setgroups failed";
        return ErrnoError() << "setgroups failed";
    }
    }
    if (attr.uid) {
    if (attr.uid()) {
        if (setuid(attr.uid) != 0) {
        if (setuid(attr.uid()) != 0) {
            return ErrnoError() << "setuid failed";
            return ErrnoError() << "setuid failed";
        }
        }
    }
    }
+3 −1
Original line number Original line Diff line number Diff line
@@ -91,11 +91,13 @@ struct ProcessAttributes {
    IoSchedClass ioprio_class;
    IoSchedClass ioprio_class;
    int ioprio_pri;
    int ioprio_pri;
    std::vector<std::pair<int, rlimit>> rlimits;
    std::vector<std::pair<int, rlimit>> rlimits;
    uid_t uid;
    std::optional<uid_t> parsed_uid;
    gid_t gid;
    gid_t gid;
    std::vector<gid_t> supp_gids;
    std::vector<gid_t> supp_gids;
    int priority;
    int priority;
    bool stdio_to_kmsg;
    bool stdio_to_kmsg;

    uid_t uid() const { return parsed_uid.value_or(0); }
};
};


inline bool RequiresConsole(const ProcessAttributes& attr) {
inline bool RequiresConsole(const ProcessAttributes& attr) {