| Alex Vakulenko | e4eec20 | 2017-01-27 14:41:04 -0800 | [diff] [blame] | 1 | #include <errno.h> | 
 | 2 | #include <sys/capability.h> | 
 | 3 | #include <sys/prctl.h> | 
 | 4 | #include <sys/stat.h> | 
 | 5 |  | 
| Alex Vakulenko | e4eec20 | 2017-01-27 14:41:04 -0800 | [diff] [blame] | 6 | #include <cutils/properties.h> | 
 | 7 | #include <cutils/sched_policy.h> | 
| Alex Vakulenko | 4fe6058 | 2017-02-02 11:35:59 -0800 | [diff] [blame] | 8 | #include <log/log.h> | 
| Alex Vakulenko | e4eec20 | 2017-01-27 14:41:04 -0800 | [diff] [blame] | 9 | #include <sys/resource.h> | 
 | 10 | #include <utils/threads.h> | 
 | 11 |  | 
| Alex Vakulenko | 5a244ed | 2017-06-09 16:29:04 -0700 | [diff] [blame] | 12 | #include <pdx/service_dispatcher.h> | 
| Alex Vakulenko | e4eec20 | 2017-01-27 14:41:04 -0800 | [diff] [blame] | 13 | #include <private/android_filesystem_config.h> | 
 | 14 |  | 
 | 15 | #include "performance_service.h" | 
 | 16 |  | 
 | 17 | namespace { | 
 | 18 |  | 
 | 19 | // Annoying that sys/capability.h doesn't define this directly. | 
 | 20 | constexpr int kMaxCapNumber = (CAP_TO_INDEX(CAP_LAST_CAP) + 1); | 
 | 21 |  | 
 | 22 | }  // anonymous namespace | 
 | 23 |  | 
 | 24 | int main(int /*argc*/, char** /*argv*/) { | 
 | 25 |   int ret = -1; | 
 | 26 |  | 
 | 27 |   struct __user_cap_header_struct capheader; | 
 | 28 |   struct __user_cap_data_struct capdata[kMaxCapNumber]; | 
 | 29 |  | 
 | 30 |   std::shared_ptr<android::pdx::Service> service; | 
 | 31 |   std::unique_ptr<android::pdx::ServiceDispatcher> dispatcher; | 
 | 32 |  | 
 | 33 |   ALOGI("Starting up..."); | 
 | 34 |  | 
 | 35 |   // We need to be able to create endpoints with full perms. | 
 | 36 |   umask(0000); | 
 | 37 |  | 
 | 38 |   // Keep capabilities when switching UID to AID_SYSTEM. | 
 | 39 |   ret = prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0); | 
 | 40 |   CHECK_ERROR(ret < 0, error, "Failed to set KEEPCAPS: %s", strerror(errno)); | 
 | 41 |  | 
 | 42 |   // Set UID and GID to system. | 
 | 43 |   ret = setresgid(AID_SYSTEM, AID_SYSTEM, AID_SYSTEM); | 
 | 44 |   CHECK_ERROR(ret < 0, error, "Failed to set GID: %s", strerror(errno)); | 
 | 45 |   ret = setresuid(AID_SYSTEM, AID_SYSTEM, AID_SYSTEM); | 
 | 46 |   CHECK_ERROR(ret < 0, error, "Failed to set UID: %s", strerror(errno)); | 
 | 47 |  | 
 | 48 |   // Keep CAP_SYS_NICE, allowing control of scheduler class, priority, and | 
 | 49 |   // cpuset for other tasks in the system. | 
 | 50 |   memset(&capheader, 0, sizeof(capheader)); | 
 | 51 |   memset(&capdata, 0, sizeof(capdata)); | 
 | 52 |   capheader.version = _LINUX_CAPABILITY_VERSION_3; | 
 | 53 |   capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_SYS_NICE); | 
 | 54 |   capdata[CAP_TO_INDEX(CAP_SYS_NICE)].permitted |= CAP_TO_MASK(CAP_SYS_NICE); | 
 | 55 |  | 
 | 56 |   // Drop all caps but the ones configured above. | 
 | 57 |   ret = capset(&capheader, capdata); | 
 | 58 |   CHECK_ERROR(ret < 0, error, "Could not set capabilities: %s", | 
 | 59 |               strerror(errno)); | 
 | 60 |  | 
| Alex Vakulenko | 5a244ed | 2017-06-09 16:29:04 -0700 | [diff] [blame] | 61 |   dispatcher = android::pdx::ServiceDispatcher::Create(); | 
| Alex Vakulenko | e4eec20 | 2017-01-27 14:41:04 -0800 | [diff] [blame] | 62 |   CHECK_ERROR(!dispatcher, error, "Failed to create service dispatcher."); | 
 | 63 |  | 
 | 64 |   service = android::dvr::PerformanceService::Create(); | 
 | 65 |   CHECK_ERROR(!service, error, "Failed to create performance service service."); | 
 | 66 |   dispatcher->AddService(service); | 
 | 67 |  | 
 | 68 |   ALOGI("Entering message loop."); | 
 | 69 |  | 
 | 70 |   ret = dispatcher->EnterDispatchLoop(); | 
 | 71 |   CHECK_ERROR(ret < 0, error, "Dispatch loop exited because: %s\n", | 
 | 72 |               strerror(-ret)); | 
 | 73 |  | 
 | 74 | error: | 
 | 75 |   return ret; | 
 | 76 | } |