Merge changes I0a95f87a,I36b22986 am: a703202093 am: 835d259e7a

am: 40e88b22f2

Change-Id: I04e3d91d34d2c50d15ab2357db175b1f69796af1
This commit is contained in:
Luis Hector Chavez 2017-06-30 04:33:30 +00:00 committed by android-build-merger
commit 1b42dbf22c
3 changed files with 45 additions and 10 deletions

View File

@ -107,17 +107,15 @@ static bool DropBoundingSet(const CapSet& to_keep) {
}
static bool SetProcCaps(const CapSet& to_keep, bool add_setpcap) {
cap_t caps = cap_init();
auto deleter = [](cap_t* p) { cap_free(*p); };
std::unique_ptr<cap_t, decltype(deleter)> ptr_caps(&caps, deleter);
ScopedCaps caps(cap_init());
cap_clear(caps);
cap_clear(caps.get());
cap_value_t value[1];
for (size_t cap = 0; cap < to_keep.size(); ++cap) {
if (to_keep.test(cap)) {
value[0] = cap;
if (cap_set_flag(caps, CAP_INHERITABLE, arraysize(value), value, CAP_SET) != 0 ||
cap_set_flag(caps, CAP_PERMITTED, arraysize(value), value, CAP_SET) != 0) {
if (cap_set_flag(caps.get(), CAP_INHERITABLE, arraysize(value), value, CAP_SET) != 0 ||
cap_set_flag(caps.get(), CAP_PERMITTED, arraysize(value), value, CAP_SET) != 0) {
PLOG(ERROR) << "cap_set_flag(INHERITABLE|PERMITTED, " << cap << ") failed";
return false;
}
@ -126,14 +124,14 @@ static bool SetProcCaps(const CapSet& to_keep, bool add_setpcap) {
if (add_setpcap) {
value[0] = CAP_SETPCAP;
if (cap_set_flag(caps, CAP_PERMITTED, arraysize(value), value, CAP_SET) != 0 ||
cap_set_flag(caps, CAP_EFFECTIVE, arraysize(value), value, CAP_SET) != 0) {
if (cap_set_flag(caps.get(), CAP_PERMITTED, arraysize(value), value, CAP_SET) != 0 ||
cap_set_flag(caps.get(), CAP_EFFECTIVE, arraysize(value), value, CAP_SET) != 0) {
PLOG(ERROR) << "cap_set_flag(PERMITTED|EFFECTIVE, " << CAP_SETPCAP << ") failed";
return false;
}
}
if (cap_set_proc(caps) != 0) {
if (cap_set_proc(caps.get()) != 0) {
PLOG(ERROR) << "cap_set_proc(" << to_keep.to_ulong() << ") failed";
return false;
}

View File

@ -15,15 +15,21 @@
#ifndef _INIT_CAPABILITIES_H
#define _INIT_CAPABILITIES_H
#include <linux/capability.h>
#include <sys/capability.h>
#include <bitset>
#include <string>
#include <type_traits>
namespace android {
namespace init {
struct CapDeleter {
void operator()(cap_t caps) const { cap_free(caps); }
};
using CapSet = std::bitset<CAP_LAST_CAP + 1>;
using ScopedCaps = std::unique_ptr<std::remove_pointer<cap_t>::type, CapDeleter>;
int LookupCap(const std::string& cap_name);
bool CapAmbientSupported();

View File

@ -21,6 +21,7 @@
#include <linux/fs.h>
#include <mntent.h>
#include <selinux/selinux.h>
#include <sys/capability.h>
#include <sys/cdefs.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
@ -48,6 +49,7 @@
#include <logwrap/logwrap.h>
#include <private/android_filesystem_config.h>
#include "capabilities.h"
#include "property_service.h"
#include "service.h"
@ -162,9 +164,38 @@ static void LogShutdownTime(UmountStat stat, Timer* t) {
LOG(WARNING) << "powerctl_shutdown_time_ms:" << std::to_string(t->duration_ms()) << ":" << stat;
}
// Determines whether the system is capable of rebooting. This is conservative,
// so if any of the attempts to determine this fail, it will still return true.
static bool IsRebootCapable() {
if (!CAP_IS_SUPPORTED(CAP_SYS_BOOT)) {
PLOG(WARNING) << "CAP_SYS_BOOT is not supported";
return true;
}
ScopedCaps caps(cap_get_proc());
if (!caps) {
PLOG(WARNING) << "cap_get_proc() failed";
return true;
}
cap_flag_value_t value = CAP_SET;
if (cap_get_flag(caps.get(), CAP_SYS_BOOT, CAP_EFFECTIVE, &value) != 0) {
PLOG(WARNING) << "cap_get_flag(CAP_SYS_BOOT, EFFECTIVE) failed";
return true;
}
return value == CAP_SET;
}
static void __attribute__((noreturn))
RebootSystem(unsigned int cmd, const std::string& rebootTarget) {
LOG(INFO) << "Reboot ending, jumping to kernel";
if (!IsRebootCapable()) {
// On systems where init does not have the capability of rebooting the
// device, just exit cleanly.
exit(0);
}
switch (cmd) {
case ANDROID_RB_POWEROFF:
reboot(RB_POWER_OFF);