1b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik/* Copyright 2008 The Android Open Source Project 2b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik */ 3b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 4b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include <errno.h> 5b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include <fcntl.h> 6b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include <inttypes.h> 7b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include <stdio.h> 8b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include <stdlib.h> 9b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include <string.h> 10b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 11b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include <cutils/multiuser.h> 12b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 13b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include <private/android_filesystem_config.h> 14b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 15b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include <selinux/android.h> 16b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include <selinux/avc.h> 17b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 18b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include "binder.h" 19d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik 20b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#ifdef VENDORSERVICEMANAGER 21b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#define LOG_TAG "VendorServiceManager" 22766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu#else 23afc221499d943386256feb9db46c119ff834bf79Yuqian Li#define LOG_TAG "ServiceManager" 24b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#endif 25b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include <log/log.h> 26b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 27b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikstruct audit_data { 28b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik pid_t pid; 29b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik uid_t uid; 30b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik const char *name; 316f485569fa3d6047dcffd068aebf361e3598783cDerek Sollenberger}; 32b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 33b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikconst char *str8(const uint16_t *x, size_t x_len) 34b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik{ 35003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik static char buf[128]; 36b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik size_t max = 127; 37b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik char *p = buf; 38b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 39c0e7a90f1f5f98e85dbeda021fac0dff79725933Stan Iliev if (x_len < max) { 40003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik max = x_len; 41b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 42003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik 43b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (x) { 44e4db79de127cfe961195f52907af8451026eaa20Chris Craik while ((max > 0) && (*x != '\0')) { 45b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik *p++ = *x++; 46161f54b2d4160b8d3f3da9eba5746da5162e4821Chris Craik max--; 47b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 48b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 49003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik *p++ = 0; 50b87eadda1818034ce03d85f30388384d1ac65916Chris Craik return buf; 51b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 52b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 53b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikint str16eq(const uint16_t *a, const char *b) 54003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik{ 55003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik while (*a && *b) 56b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (*a++ != *b++) return 0; 57003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik if (*a || *b) 58b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return 0; 59b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return 1; 60d645640180c25c2711e99aa82ec629155f8e91baChris Craik} 61d645640180c25c2711e99aa82ec629155f8e91baChris Craik 62d645640180c25c2711e99aa82ec629155f8e91baChris Craikstatic char *service_manager_context; 63d645640180c25c2711e99aa82ec629155f8e91baChris Craikstatic struct selabel_handle* sehandle; 64d645640180c25c2711e99aa82ec629155f8e91baChris Craik 65d645640180c25c2711e99aa82ec629155f8e91baChris Craikstatic bool check_mac_perms(pid_t spid, uid_t uid, const char *tctx, const char *perm, const char *name) 66d645640180c25c2711e99aa82ec629155f8e91baChris Craik{ 67d645640180c25c2711e99aa82ec629155f8e91baChris Craik char *sctx = NULL; 68d645640180c25c2711e99aa82ec629155f8e91baChris Craik const char *class = "service_manager"; 69d645640180c25c2711e99aa82ec629155f8e91baChris Craik bool allowed; 70b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik struct audit_data ad; 71003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik 72b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (getpidcon(spid, &sctx) < 0) { 73b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik ALOGE("SELinux: getpidcon(pid=%d) failed to retrieve pid context.\n", spid); 74b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return false; 75b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 76b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 77b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik ad.pid = spid; 78b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik ad.uid = uid; 79b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik ad.name = name; 80b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 81b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik int result = selinux_check_access(sctx, tctx, class, perm, (void *) &ad); 82b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik allowed = (result == 0); 83b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 84b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik freecon(sctx); 85b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return allowed; 86b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 87b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 886fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craikstatic bool check_mac_perms_from_getcon(pid_t spid, uid_t uid, const char *perm) 896fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik{ 906fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik return check_mac_perms(spid, uid, service_manager_context, perm, NULL); 916fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik} 926fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 936fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craikstatic bool check_mac_perms_from_lookup(pid_t spid, uid_t uid, const char *perm, const char *name) 946fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik{ 956fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik bool allowed; 967df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck char *tctx = NULL; 97b87eadda1818034ce03d85f30388384d1ac65916Chris Craik 987df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck if (!sehandle) { 996fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik ALOGE("SELinux: Failed to find sehandle. Aborting service_manager.\n"); 1006fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik abort(); 1016fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik } 1026fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 103b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (selabel_lookup(sehandle, &tctx, name, 0) != 0) { 104b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik ALOGE("SELinux: No match for %s in service_contexts.\n", name); 105b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return false; 106eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita } 107b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 108b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik allowed = check_mac_perms(spid, uid, tctx, perm, name); 109b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik freecon(tctx); 110b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return allowed; 111b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 112b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 113b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikstatic int svc_can_register(const uint16_t *name, size_t name_len, pid_t spid, uid_t uid) 114b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik{ 115b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik const char *perm = "add"; 116b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 117b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (multiuser_get_app_id(uid) >= AID_APP) { 118b87eadda1818034ce03d85f30388384d1ac65916Chris Craik return 0; /* Don't allow apps to register services */ 119eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita } 1206fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 121eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita return check_mac_perms_from_lookup(spid, uid, perm, str8(name, name_len)) ? 1 : 0; 122eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita} 1236fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 1246fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craikstatic int svc_can_list(pid_t spid, uid_t uid) 1256fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik{ 1266fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik const char *perm = "list"; 1276fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik return check_mac_perms_from_getcon(spid, uid, perm) ? 1 : 0; 1286fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik} 1296fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 130e4f6d968f51ba3bb867e8e124dca97b7e9c3fea5Chris Craikstatic int svc_can_find(const uint16_t *name, size_t name_len, pid_t spid, uid_t uid) 131e4f6d968f51ba3bb867e8e124dca97b7e9c3fea5Chris Craik{ 1326fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik const char *perm = "find"; 1336fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik return check_mac_perms_from_lookup(spid, uid, perm, str8(name, name_len)) ? 1 : 0; 134b87eadda1818034ce03d85f30388384d1ac65916Chris Craik} 1356fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 1366fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craikstruct svcinfo 137b87eadda1818034ce03d85f30388384d1ac65916Chris Craik{ 138b87eadda1818034ce03d85f30388384d1ac65916Chris Craik struct svcinfo *next; 139b87eadda1818034ce03d85f30388384d1ac65916Chris Craik uint32_t handle; 140b87eadda1818034ce03d85f30388384d1ac65916Chris Craik struct binder_death death; 141b87eadda1818034ce03d85f30388384d1ac65916Chris Craik int allow_isolated; 142b87eadda1818034ce03d85f30388384d1ac65916Chris Craik size_t len; 143eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita uint16_t name[0]; 144b87eadda1818034ce03d85f30388384d1ac65916Chris Craik}; 1456fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 1466fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craikstruct svcinfo *svclist = NULL; 1476fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 148b87eadda1818034ce03d85f30388384d1ac65916Chris Craikstruct svcinfo *find_svc(const uint16_t *s16, size_t len) 1496fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik{ 1506fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik struct svcinfo *si; 1516fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 1523c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik for (si = svclist; si; si = si->next) { 1533c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik if ((len == si->len) && 1543c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik !memcmp(s16, si->name, len * sizeof(uint16_t))) { 1553c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik return si; 1563c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik } 1573c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik } 1583c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik return NULL; 1596fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik} 1606fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 1616fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craikvoid svcinfo_death(struct binder_state *bs, void *ptr) 1626fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik{ 163b87eadda1818034ce03d85f30388384d1ac65916Chris Craik struct svcinfo *si = (struct svcinfo* ) ptr; 1643c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik 165b87eadda1818034ce03d85f30388384d1ac65916Chris Craik ALOGI("service '%s' died\n", str8(si->name, si->len)); 1663c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik if (si->handle) { 1673c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik binder_release(bs, si->handle); 1683c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik si->handle = 0; 1693c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik } 1703c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik} 1713c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik 1723c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craikuint16_t svcmgr_id[] = { 1733c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik 'a','n','d','r','o','i','d','.','o','s','.', 1743c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik 'I','S','e','r','v','i','c','e','M','a','n','a','g','e','r' 1753c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik}; 1763c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik 1773c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik 1783c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craikuint32_t do_find_service(const uint16_t *s, size_t len, uid_t uid, pid_t spid) 1793c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik{ 1803c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik struct svcinfo *si = find_svc(s, len); 1813c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik 1823c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik if (!si || !si->handle) { 1833c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik return 0; 1843c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik } 1853c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik 1863c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik if (!si->allow_isolated) { 1873c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik // If this service doesn't allow access from isolated processes, 1883c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik // then check the uid to see if it is isolated. 1893c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik uid_t appid = uid % AID_USER; 1903c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik if (appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END) { 191b87eadda1818034ce03d85f30388384d1ac65916Chris Craik return 0; 1926fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik } 1936fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik } 1943c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik 195b87eadda1818034ce03d85f30388384d1ac65916Chris Craik if (!svc_can_find(s, len, spid, uid)) { 1963c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik return 0; 1973c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik } 198b87eadda1818034ce03d85f30388384d1ac65916Chris Craik 1996fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik return si->handle; 200b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 201b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 202b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikint do_add_service(struct binder_state *bs, 203b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik const uint16_t *s, size_t len, 204b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik uint32_t handle, uid_t uid, int allow_isolated, 205b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik pid_t spid) 206b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik{ 207b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik struct svcinfo *si; 208b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 209b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik //ALOGI("add_service('%s',%x,%s) uid=%d\n", str8(s, len), handle, 210b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik // allow_isolated ? "allow_isolated" : "!allow_isolated", uid); 211b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 212b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (!handle || (len == 0) || (len > 127)) 213b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return -1; 214b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 215b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (!svc_can_register(s, len, spid, uid)) { 216b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik ALOGE("add_service('%s',%x) uid=%d - PERMISSION DENIED\n", 217b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik str8(s, len), handle, uid); 218b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return -1; 219b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 220b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 221b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik si = find_svc(s, len); 222b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (si) { 223b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (si->handle) { 224b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik ALOGE("add_service('%s',%x) uid=%d - ALREADY REGISTERED, OVERRIDE\n", 225b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik str8(s, len), handle, uid); 226b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik svcinfo_death(bs, si); 227e29ce6f51d681af7649c0a7cddee97c471e43eb5Chris Craik } 228b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik si->handle = handle; 229b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } else { 230b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t)); 231b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (!si) { 232b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik ALOGE("add_service('%s',%x) uid=%d - OUT OF MEMORY\n", 233b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik str8(s, len), handle, uid); 234b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return -1; 235b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 236b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik si->handle = handle; 2376e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed si->len = len; 238b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik memcpy(si->name, s, (len + 1) * sizeof(uint16_t)); 239b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik si->name[len] = '\0'; 2406e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed si->death.func = (void*) svcinfo_death; 241b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik si->death.ptr = si; 242b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik si->allow_isolated = allow_isolated; 2436e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reed si->next = svclist; 244b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik svclist = si; 245b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 246b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 247b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik binder_acquire(bs, handle); 248b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik binder_link_to_death(bs, handle, &si->death); 249b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return 0; 250260ab726486317496bc12a57d599ea96dcde3284Mike Reed} 251a204848b1dc63877a12e2d24108e9d8e1e691e28Chris Craik 252a204848b1dc63877a12e2d24108e9d8e1e691e28Chris Craikint svcmgr_handler(struct binder_state *bs, 253a204848b1dc63877a12e2d24108e9d8e1e691e28Chris Craik struct binder_transaction_data *txn, 254a204848b1dc63877a12e2d24108e9d8e1e691e28Chris Craik struct binder_io *msg, 255b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik struct binder_io *reply) 256b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik{ 257b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik struct svcinfo *si; 2584c3980b6e43cc7c0541f54b8e7e2d9d6108be622Chris Craik uint16_t *s; 2594c3980b6e43cc7c0541f54b8e7e2d9d6108be622Chris Craik size_t len; 2604c3980b6e43cc7c0541f54b8e7e2d9d6108be622Chris Craik uint32_t handle; 2614c3980b6e43cc7c0541f54b8e7e2d9d6108be622Chris Craik uint32_t strict_policy; 262b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik int allow_isolated; 263b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 264386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik //ALOGI("target=%p code=%d pid=%d uid=%d\n", 265386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik // (void*) txn->target.ptr, txn->code, txn->sender_pid, txn->sender_euid); 266386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik 267386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik if (txn->target.ptr != BINDER_SERVICE_MANAGER) 268386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik return -1; 269386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik 270386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik if (txn->code == PING_TRANSACTION) 271386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik return 0; 272b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 273386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik // Equivalent to Parcel::enforceInterface(), reading the RPC 274814ee6a9218aa339a4757b2c0ba1ad268f8dbc8aChris Craik // header with the strict mode policy mask and the interface name. 275386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik // Note that we ignore the strict_policy and don't propagate it 276386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik // further (since we do no outbound RPCs anyway). 2777df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck strict_policy = bio_get_uint32(msg); 278386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik s = bio_get_string16(msg, &len); 279386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik if (s == NULL) { 280e4db79de127cfe961195f52907af8451026eaa20Chris Craik return -1; 281386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik } 282b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 283a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik if ((len != (sizeof(svcmgr_id) / 2)) || 284a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik memcmp(svcmgr_id, s, sizeof(svcmgr_id))) { 285814ee6a9218aa339a4757b2c0ba1ad268f8dbc8aChris Craik fprintf(stderr,"invalid id %s\n", str8(s, len)); 286a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik return -1; 287a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik } 2887df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck 289386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik if (sehandle && selinux_status_updated() > 0) { 290a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik struct selabel_handle *tmp_sehandle = selinux_android_service_context_handle(); 291e4db79de127cfe961195f52907af8451026eaa20Chris Craik if (tmp_sehandle) { 292a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik selabel_close(sehandle); 293b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik sehandle = tmp_sehandle; 294a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik } 295b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 296814ee6a9218aa339a4757b2c0ba1ad268f8dbc8aChris Craik 297814ee6a9218aa339a4757b2c0ba1ad268f8dbc8aChris Craik switch(txn->code) { 2987df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck case SVC_MGR_GET_SERVICE: 299b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik case SVC_MGR_CHECK_SERVICE: 300b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik s = bio_get_string16(msg, &len); 301e4db79de127cfe961195f52907af8451026eaa20Chris Craik if (s == NULL) { 302b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return -1; 303b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 304b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik handle = do_find_service(s, len, txn->sender_euid, txn->sender_pid); 305b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (!handle) 306b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik break; 307b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik bio_put_ref(reply, handle); 3087a89600bac7ab889a5ba8a994c57d677de0e45d5Chris Craik return 0; 309b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 310b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik case SVC_MGR_ADD_SERVICE: 311b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik s = bio_get_string16(msg, &len); 312b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (s == NULL) { 313b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return -1; 314b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 315b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik handle = bio_get_ref(msg); 316b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik allow_isolated = bio_get_uint32(msg) ? 1 : 0; 317b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (do_add_service(bs, s, len, handle, txn->sender_euid, 318b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik allow_isolated, txn->sender_pid)) 319b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return -1; 320b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik break; 321b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 322b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik case SVC_MGR_LIST_SERVICES: { 323b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik uint32_t n = bio_get_uint32(msg); 324b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 325b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (!svc_can_list(txn->sender_pid, txn->sender_euid)) { 326b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik ALOGE("list_service() uid=%d - PERMISSION DENIED\n", 327b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik txn->sender_euid); 328b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return -1; 329b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 330b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik si = svclist; 3317df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck while ((n-- > 0) && si) 332b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik si = si->next; 333b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (si) { 334e4db79de127cfe961195f52907af8451026eaa20Chris Craik bio_put_string16(reply, si->name); 335b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return 0; 336b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 337b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return -1; 338b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 339814ee6a9218aa339a4757b2c0ba1ad268f8dbc8aChris Craik default: 340814ee6a9218aa339a4757b2c0ba1ad268f8dbc8aChris Craik ALOGE("unknown code %d\n", txn->code); 341b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return -1; 342b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 343b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 344b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik bio_put_uint32(reply, 0); 345b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return 0; 346b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 347b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 348b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 349b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikstatic int audit_callback(void *data, __unused security_class_t cls, char *buf, size_t len) 350b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik{ 351b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik struct audit_data *ad = (struct audit_data *)data; 352b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 353b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (!ad || !ad->name) { 354b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik ALOGE("No service manager audit data"); 355b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return 0; 356b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 357b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 358b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik snprintf(buf, len, "service=%s pid=%d uid=%d", ad->name, ad->pid, ad->uid); 359b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return 0; 360b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 361b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 362b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikint main(int argc, char** argv) 363b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik{ 364b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik struct binder_state *bs; 365814ee6a9218aa339a4757b2c0ba1ad268f8dbc8aChris Craik union selinux_callback cb; 366b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik char *driver; 367b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 368814ee6a9218aa339a4757b2c0ba1ad268f8dbc8aChris Craik if (argc > 1) { 369814ee6a9218aa339a4757b2c0ba1ad268f8dbc8aChris Craik driver = argv[1]; 3702dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik } else { 3712dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik driver = "/dev/binder"; 3722dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik } 3732dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik 3742dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik bs = binder_open(driver, 128*1024); 3752dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik if (!bs) { 3762dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik#ifdef VENDORSERVICEMANAGER 3772dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik ALOGW("failed to open binder driver %s\n", driver); 3782dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik while (true) { 379b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik sleep(UINT_MAX); 380386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik } 381268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik#else 382268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik ALOGE("failed to open binder driver %s\n", driver); 383268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik#endif 384268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik return -1; 385268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik } 386268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik 387268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik if (binder_become_context_manager(bs)) { 388268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik ALOGE("cannot become context manager (%s)\n", strerror(errno)); 389268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik return -1; 390268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik } 391268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik 392268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik cb.func_audit = audit_callback; 393268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik selinux_set_callback(SELINUX_CB_AUDIT, cb); 3947df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck cb.func_log = selinux_log_callback; 395268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik selinux_set_callback(SELINUX_CB_LOG, cb); 396e4db79de127cfe961195f52907af8451026eaa20Chris Craik 397268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik#ifdef VENDORSERVICEMANAGER 398268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik sehandle = selinux_android_vendor_service_context_handle(); 399268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik#else 400268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik sehandle = selinux_android_service_context_handle(); 401268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik#endif 402b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik selinux_status_open(true); 403268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik 404814ee6a9218aa339a4757b2c0ba1ad268f8dbc8aChris Craik if (sehandle == NULL) { 405814ee6a9218aa339a4757b2c0ba1ad268f8dbc8aChris Craik ALOGE("SELinux: Failed to acquire sehandle. Aborting.\n"); 406386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik abort(); 407b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 408386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik 409268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik if (getcon(&service_manager_context) != 0) { 410268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik ALOGE("SELinux: Failed to acquire service_manager context. Aborting.\n"); 411268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik abort(); 412268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik } 413268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik 414268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik 415268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik binder_loop(bs, svcmgr_handler); 416268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik 4177df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck return 0; 418268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik} 419e4db79de127cfe961195f52907af8451026eaa20Chris Craik