diff options
| author | 2018-03-14 12:47:25 -0700 | |
|---|---|---|
| committer | 2018-03-14 14:42:24 -0700 | |
| commit | 05d74917546ee1bfb8d45e6b79c6c433874d6e77 (patch) | |
| tree | ec83446b7562cef40bee5a7f8de6551a674105e6 | |
| parent | d05127172ce1f113230b1774119b6d54475dc158 (diff) | |
Make DropRootUser more container-friendly
When Android is running as a container, it might not have CAP_SYSLOG
(since all the checks in the kernel are performed against the init
namespace). This change makes DropRootUser not raise CAP_SYSLOG if it
wasn't present to begin with.
Bug: 74568776
Test: DropRootUser no longer returns false when run in a container
Change-Id: Ia54ea81f51cc602c6304a81f50a55b2ccde7df36
| -rw-r--r-- | cmds/dumpstate/DumpstateInternal.cpp | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/cmds/dumpstate/DumpstateInternal.cpp b/cmds/dumpstate/DumpstateInternal.cpp index 83e30a22ff..819d5b91f5 100644 --- a/cmds/dumpstate/DumpstateInternal.cpp +++ b/cmds/dumpstate/DumpstateInternal.cpp @@ -98,13 +98,25 @@ bool DropRootUser() { capheader.version = _LINUX_CAPABILITY_VERSION_3; capheader.pid = 0; - capdata[CAP_TO_INDEX(CAP_SYSLOG)].permitted = CAP_TO_MASK(CAP_SYSLOG); - capdata[CAP_TO_INDEX(CAP_SYSLOG)].effective = CAP_TO_MASK(CAP_SYSLOG); - capdata[0].inheritable = 0; - capdata[1].inheritable = 0; + if (capget(&capheader, &capdata[0]) != 0) { + MYLOGE("capget failed: %s\n", strerror(errno)); + return false; + } + + const uint32_t cap_syslog_mask = CAP_TO_MASK(CAP_SYSLOG); + const uint32_t cap_syslog_index = CAP_TO_INDEX(CAP_SYSLOG); + bool has_cap_syslog = (capdata[cap_syslog_index].effective & cap_syslog_mask) != 0; + + memset(&capdata, 0, sizeof(capdata)); + if (has_cap_syslog) { + // Only attempt to keep CAP_SYSLOG if it was present to begin with. + capdata[cap_syslog_index].permitted |= cap_syslog_mask; + capdata[cap_syslog_index].effective |= cap_syslog_mask; + } - if (capset(&capheader, &capdata[0]) < 0) { - MYLOGE("capset failed: %s\n", strerror(errno)); + if (capset(&capheader, &capdata[0]) != 0) { + MYLOGE("capset({%#x, %#x}) failed: %s\n", capdata[0].effective, + capdata[1].effective, strerror(errno)); return false; } |