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