Loading init/capabilities.cpp +7 −9 Original line number Diff line number Diff line Loading @@ -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; } Loading @@ -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; } Loading init/capabilities.h +7 −1 Original line number Diff line number Diff line Loading @@ -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(); Loading init/reboot.cpp +31 −0 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -48,6 +49,7 @@ #include <logwrap/logwrap.h> #include <private/android_filesystem_config.h> #include "capabilities.h" #include "property_service.h" #include "service.h" Loading Loading @@ -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); Loading Loading
init/capabilities.cpp +7 −9 Original line number Diff line number Diff line Loading @@ -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; } Loading @@ -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; } Loading
init/capabilities.h +7 −1 Original line number Diff line number Diff line Loading @@ -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(); Loading
init/reboot.cpp +31 −0 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -48,6 +49,7 @@ #include <logwrap/logwrap.h> #include <private/android_filesystem_config.h> #include "capabilities.h" #include "property_service.h" #include "service.h" Loading Loading @@ -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); Loading