Merge "adb: Correctly drop caps when ambient capabilities are used"

am: 44f78bed19

Change-Id: Ifd1f6300a027ad994e57b2c070d180f6e867280d
This commit is contained in:
Luis Hector Chavez 2018-04-05 19:38:28 -07:00 committed by android-build-merger
commit 00b2dffd38

View file

@ -24,6 +24,7 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/capability.h>
#include <sys/prctl.h>
#include <memory>
@ -50,13 +51,13 @@
static const char* root_seclabel = nullptr;
static void drop_capabilities_bounding_set_if_needed(struct minijail *j) {
static bool should_drop_capabilities_bounding_set() {
#if defined(ALLOW_ADBD_ROOT)
if (__android_log_is_debuggable()) {
return;
return false;
}
#endif
minijail_capbset_drop(j, CAP_TO_MASK(CAP_SETUID) | CAP_TO_MASK(CAP_SETGID));
return true;
}
static bool should_drop_privileges() {
@ -117,13 +118,37 @@ static void drop_privileges(int server_port) {
// Don't listen on a port (default 5037) if running in secure mode.
// Don't run as root if running in secure mode.
if (should_drop_privileges()) {
drop_capabilities_bounding_set_if_needed(jail.get());
const bool should_drop_caps = should_drop_capabilities_bounding_set();
if (should_drop_caps) {
minijail_use_caps(jail.get(), CAP_TO_MASK(CAP_SETUID) | CAP_TO_MASK(CAP_SETGID));
}
minijail_change_gid(jail.get(), AID_SHELL);
minijail_change_uid(jail.get(), AID_SHELL);
// minijail_enter() will abort if any priv-dropping step fails.
minijail_enter(jail.get());
// Whenever ambient capabilities are being used, minijail cannot
// simultaneously drop the bounding capability set to just
// CAP_SETUID|CAP_SETGID while clearing the inheritable, effective,
// and permitted sets. So we need to do that in two steps.
using ScopedCaps =
std::unique_ptr<std::remove_pointer<cap_t>::type, std::function<void(cap_t)>>;
ScopedCaps caps(cap_get_proc(), &cap_free);
if (cap_clear_flag(caps.get(), CAP_INHERITABLE) == -1) {
PLOG(FATAL) << "cap_clear_flag(INHERITABLE) failed";
}
if (cap_clear_flag(caps.get(), CAP_EFFECTIVE) == -1) {
PLOG(FATAL) << "cap_clear_flag(PEMITTED) failed";
}
if (cap_clear_flag(caps.get(), CAP_PERMITTED) == -1) {
PLOG(FATAL) << "cap_clear_flag(PEMITTED) failed";
}
if (cap_set_proc(caps.get()) != 0) {
PLOG(FATAL) << "cap_set_proc() failed";
}
D("Local port disabled");
} else {
// minijail_enter() will abort if any priv-dropping step fails.