194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood/* Copyright 2008 The Android Open Source Project 294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood */ 394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <errno.h> 594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <fcntl.h> 60b41ad5d6ec86cd2d481969dcff7e88f2805324fElliott Hughes#include <inttypes.h> 713df5f5f8fbc5a3fdfdd5d1ba5dc853cf3f017f0Mark Salyzyn#include <stdio.h> 813df5f5f8fbc5a3fdfdd5d1ba5dc853cf3f017f0Mark Salyzyn#include <stdlib.h> 913df5f5f8fbc5a3fdfdd5d1ba5dc853cf3f017f0Mark Salyzyn#include <string.h> 1094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 11212c88143ebdeabbab364fca7680d8cd2caff256Yifan Hong#include <cutils/android_filesystem_config.h> 126b9c6d23f69a64f76fc26cda6989183042b0621cArve Hjønnevåg#include <cutils/multiuser.h> 136b9c6d23f69a64f76fc26cda6989183042b0621cArve Hjønnevåg 1469154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn#include <selinux/android.h> 157d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich#include <selinux/avc.h> 1669154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 1794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "binder.h" 1894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 1931361232e1e7965d00c638ead2903f08f168f1c9Martijn Coenen#ifdef VENDORSERVICEMANAGER 2031361232e1e7965d00c638ead2903f08f168f1c9Martijn Coenen#define LOG_TAG "VendorServiceManager" 2194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#else 2294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#define LOG_TAG "ServiceManager" 2394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#endif 2431361232e1e7965d00c638ead2903f08f168f1c9Martijn Coenen#include <log/log.h> 2594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 268fb0f92e0fe3c286ebb120bae9e1570ee109fa12William Robertsstruct audit_data { 278fb0f92e0fe3c286ebb120bae9e1570ee109fa12William Roberts pid_t pid; 288fb0f92e0fe3c286ebb120bae9e1570ee109fa12William Roberts uid_t uid; 298fb0f92e0fe3c286ebb120bae9e1570ee109fa12William Roberts const char *name; 308fb0f92e0fe3c286ebb120bae9e1570ee109fa12William Roberts}; 318fb0f92e0fe3c286ebb120bae9e1570ee109fa12William Roberts 327d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevichconst char *str8(const uint16_t *x, size_t x_len) 3394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 3494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood static char buf[128]; 357d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich size_t max = 127; 3694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood char *p = buf; 3794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 387d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich if (x_len < max) { 397d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich max = x_len; 407d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich } 417d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich 4294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (x) { 437d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich while ((max > 0) && (*x != '\0')) { 4494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood *p++ = *x++; 457d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich max--; 4694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 4794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 4894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood *p++ = 0; 4994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return buf; 5094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 5194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 529b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescuint str16eq(const uint16_t *a, const char *b) 5394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 5494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood while (*a && *b) 5594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (*a++ != *b++) return 0; 5694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (*a || *b) 5794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 5894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 1; 5994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 6094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 61c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahnstatic char *service_manager_context; 6269154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahnstatic struct selabel_handle* sehandle; 6369154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 648fb0f92e0fe3c286ebb120bae9e1570ee109fa12William Robertsstatic bool check_mac_perms(pid_t spid, uid_t uid, const char *tctx, const char *perm, const char *name) 6569154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn{ 6669154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn char *sctx = NULL; 67c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn const char *class = "service_manager"; 68c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn bool allowed; 698fb0f92e0fe3c286ebb120bae9e1570ee109fa12William Roberts struct audit_data ad; 7069154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 71c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn if (getpidcon(spid, &sctx) < 0) { 72c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn ALOGE("SELinux: getpidcon(pid=%d) failed to retrieve pid context.\n", spid); 7369154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn return false; 7469154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn } 7569154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 768fb0f92e0fe3c286ebb120bae9e1570ee109fa12William Roberts ad.pid = spid; 778fb0f92e0fe3c286ebb120bae9e1570ee109fa12William Roberts ad.uid = uid; 788fb0f92e0fe3c286ebb120bae9e1570ee109fa12William Roberts ad.name = name; 798fb0f92e0fe3c286ebb120bae9e1570ee109fa12William Roberts 808fb0f92e0fe3c286ebb120bae9e1570ee109fa12William Roberts int result = selinux_check_access(sctx, tctx, class, perm, (void *) &ad); 81c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn allowed = (result == 0); 82c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn 83c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn freecon(sctx); 84c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn return allowed; 85c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn} 86c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn 878fb0f92e0fe3c286ebb120bae9e1570ee109fa12William Robertsstatic bool check_mac_perms_from_getcon(pid_t spid, uid_t uid, const char *perm) 88c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn{ 898fb0f92e0fe3c286ebb120bae9e1570ee109fa12William Roberts return check_mac_perms(spid, uid, service_manager_context, perm, NULL); 90c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn} 91c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn 928fb0f92e0fe3c286ebb120bae9e1570ee109fa12William Robertsstatic bool check_mac_perms_from_lookup(pid_t spid, uid_t uid, const char *perm, const char *name) 93c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn{ 94c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn bool allowed; 95c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn char *tctx = NULL; 96c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn 97c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn if (!sehandle) { 98c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn ALOGE("SELinux: Failed to find sehandle. Aborting service_manager.\n"); 99c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn abort(); 10069154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn } 10169154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 102c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn if (selabel_lookup(sehandle, &tctx, name, 0) != 0) { 103c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn ALOGE("SELinux: No match for %s in service_contexts.\n", name); 10469154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn return false; 10569154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn } 10669154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 1078fb0f92e0fe3c286ebb120bae9e1570ee109fa12William Roberts allowed = check_mac_perms(spid, uid, tctx, perm, name); 10869154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn freecon(tctx); 10969154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn return allowed; 11069154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn} 11169154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 1128fb0f92e0fe3c286ebb120bae9e1570ee109fa12William Robertsstatic int svc_can_register(const uint16_t *name, size_t name_len, pid_t spid, uid_t uid) 113c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn{ 114c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn const char *perm = "add"; 1155fa90a063f77054fc6068f45f6a21f43d64364b6Arve Hjønnevåg 1166b9c6d23f69a64f76fc26cda6989183042b0621cArve Hjønnevåg if (multiuser_get_app_id(uid) >= AID_APP) { 1175fa90a063f77054fc6068f45f6a21f43d64364b6Arve Hjønnevåg return 0; /* Don't allow apps to register services */ 1185fa90a063f77054fc6068f45f6a21f43d64364b6Arve Hjønnevåg } 1195fa90a063f77054fc6068f45f6a21f43d64364b6Arve Hjønnevåg 1208fb0f92e0fe3c286ebb120bae9e1570ee109fa12William Roberts return check_mac_perms_from_lookup(spid, uid, perm, str8(name, name_len)) ? 1 : 0; 121c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn} 122c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn 1238fb0f92e0fe3c286ebb120bae9e1570ee109fa12William Robertsstatic int svc_can_list(pid_t spid, uid_t uid) 12494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 125c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn const char *perm = "list"; 1268fb0f92e0fe3c286ebb120bae9e1570ee109fa12William Roberts return check_mac_perms_from_getcon(spid, uid, perm) ? 1 : 0; 127c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn} 128c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn 1298fb0f92e0fe3c286ebb120bae9e1570ee109fa12William Robertsstatic int svc_can_find(const uint16_t *name, size_t name_len, pid_t spid, uid_t uid) 130c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn{ 131c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn const char *perm = "find"; 1328fb0f92e0fe3c286ebb120bae9e1570ee109fa12William Roberts return check_mac_perms_from_lookup(spid, uid, perm, str8(name, name_len)) ? 1 : 0; 13394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 13494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 1359b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescustruct svcinfo 13694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 13794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct svcinfo *next; 1385fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu uint32_t handle; 13994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct binder_death death; 14094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int allow_isolated; 141f56042d6a496fca2e5cfc1f598251f77a9bc7986Vishnu Nair uint32_t dumpsys_priority; 1429b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu size_t len; 14394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint16_t name[0]; 14494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}; 14594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 1469b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescustruct svcinfo *svclist = NULL; 14794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 1489b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescustruct svcinfo *find_svc(const uint16_t *s16, size_t len) 14994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 15094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct svcinfo *si; 15194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 15294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood for (si = svclist; si; si = si->next) { 15394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if ((len == si->len) && 15494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood !memcmp(s16, si->name, len * sizeof(uint16_t))) { 15594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return si; 15694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 15794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 1589b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu return NULL; 15994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 16094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 16194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid svcinfo_death(struct binder_state *bs, void *ptr) 16294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 1639b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu struct svcinfo *si = (struct svcinfo* ) ptr; 1649b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu 1657d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich ALOGI("service '%s' died\n", str8(si->name, si->len)); 1665fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu if (si->handle) { 1675fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu binder_release(bs, si->handle); 1685fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu si->handle = 0; 1699b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu } 17094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 17194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 1729b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescuuint16_t svcmgr_id[] = { 17394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 'a','n','d','r','o','i','d','.','o','s','.', 1749b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu 'I','S','e','r','v','i','c','e','M','a','n','a','g','e','r' 17594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}; 17694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 1779b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu 178d57d9b900da83b1b5431d90e250f86c0047c618aIan Pedowitzuint32_t do_find_service(const uint16_t *s, size_t len, uid_t uid, pid_t spid) 17994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 180b27bbd18bb65b3744ae066fcd6826285dec8b469Nick Kralevich struct svcinfo *si = find_svc(s, len); 18194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 182b27bbd18bb65b3744ae066fcd6826285dec8b469Nick Kralevich if (!si || !si->handle) { 183c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn return 0; 184c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn } 185b27bbd18bb65b3744ae066fcd6826285dec8b469Nick Kralevich 186b27bbd18bb65b3744ae066fcd6826285dec8b469Nick Kralevich if (!si->allow_isolated) { 187b27bbd18bb65b3744ae066fcd6826285dec8b469Nick Kralevich // If this service doesn't allow access from isolated processes, 188b27bbd18bb65b3744ae066fcd6826285dec8b469Nick Kralevich // then check the uid to see if it is isolated. 189b27bbd18bb65b3744ae066fcd6826285dec8b469Nick Kralevich uid_t appid = uid % AID_USER; 190b27bbd18bb65b3744ae066fcd6826285dec8b469Nick Kralevich if (appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END) { 191b27bbd18bb65b3744ae066fcd6826285dec8b469Nick Kralevich return 0; 19294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 193b27bbd18bb65b3744ae066fcd6826285dec8b469Nick Kralevich } 194b27bbd18bb65b3744ae066fcd6826285dec8b469Nick Kralevich 1958fb0f92e0fe3c286ebb120bae9e1570ee109fa12William Roberts if (!svc_can_find(s, len, spid, uid)) { 19694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 19794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 198b27bbd18bb65b3744ae066fcd6826285dec8b469Nick Kralevich 199b27bbd18bb65b3744ae066fcd6826285dec8b469Nick Kralevich return si->handle; 20094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 20194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 202f56042d6a496fca2e5cfc1f598251f77a9bc7986Vishnu Nairint do_add_service(struct binder_state *bs, const uint16_t *s, size_t len, uint32_t handle, 203f56042d6a496fca2e5cfc1f598251f77a9bc7986Vishnu Nair uid_t uid, int allow_isolated, uint32_t dumpsys_priority, pid_t spid) { 20494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct svcinfo *si; 2053a345f0df5f62d77e875a289e9aee89f0d1b526eSerban Constantinescu 2067d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich //ALOGI("add_service('%s',%x,%s) uid=%d\n", str8(s, len), handle, 20794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // allow_isolated ? "allow_isolated" : "!allow_isolated", uid); 20894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 2095fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu if (!handle || (len == 0) || (len > 127)) 21094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 21194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 2128fb0f92e0fe3c286ebb120bae9e1570ee109fa12William Roberts if (!svc_can_register(s, len, spid, uid)) { 2135fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu ALOGE("add_service('%s',%x) uid=%d - PERMISSION DENIED\n", 2147d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich str8(s, len), handle, uid); 21594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 21694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 21794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 21894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood si = find_svc(s, len); 21994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (si) { 2205fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu if (si->handle) { 2215fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu ALOGE("add_service('%s',%x) uid=%d - ALREADY REGISTERED, OVERRIDE\n", 2227d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich str8(s, len), handle, uid); 22394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood svcinfo_death(bs, si); 22494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 2255fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu si->handle = handle; 22694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else { 22794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t)); 22894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!si) { 2295fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu ALOGE("add_service('%s',%x) uid=%d - OUT OF MEMORY\n", 2307d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich str8(s, len), handle, uid); 23194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 23294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 2335fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu si->handle = handle; 23494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood si->len = len; 23594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood memcpy(si->name, s, (len + 1) * sizeof(uint16_t)); 23694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood si->name[len] = '\0'; 2379b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu si->death.func = (void*) svcinfo_death; 23894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood si->death.ptr = si; 23994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood si->allow_isolated = allow_isolated; 240f56042d6a496fca2e5cfc1f598251f77a9bc7986Vishnu Nair si->dumpsys_priority = dumpsys_priority; 24194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood si->next = svclist; 24294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood svclist = si; 24394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 24494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 2455fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu binder_acquire(bs, handle); 2465fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu binder_link_to_death(bs, handle, &si->death); 24794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 24894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 24994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 25094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodint svcmgr_handler(struct binder_state *bs, 251bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu struct binder_transaction_data *txn, 25294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct binder_io *msg, 25394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct binder_io *reply) 25494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 25594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct svcinfo *si; 25694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint16_t *s; 2579b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu size_t len; 2585fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu uint32_t handle; 25994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint32_t strict_policy; 26094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int allow_isolated; 261f56042d6a496fca2e5cfc1f598251f77a9bc7986Vishnu Nair uint32_t dumpsys_priority; 26294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 2630b41ad5d6ec86cd2d481969dcff7e88f2805324fElliott Hughes //ALOGI("target=%p code=%d pid=%d uid=%d\n", 2640b41ad5d6ec86cd2d481969dcff7e88f2805324fElliott Hughes // (void*) txn->target.ptr, txn->code, txn->sender_pid, txn->sender_euid); 26594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 2660b41ad5d6ec86cd2d481969dcff7e88f2805324fElliott Hughes if (txn->target.ptr != BINDER_SERVICE_MANAGER) 26794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 26894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 269e5245cbf5d4e830cf605ef07f5d284d7c5d2867eArve Hjønnevåg if (txn->code == PING_TRANSACTION) 270e5245cbf5d4e830cf605ef07f5d284d7c5d2867eArve Hjønnevåg return 0; 271e5245cbf5d4e830cf605ef07f5d284d7c5d2867eArve Hjønnevåg 27294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // Equivalent to Parcel::enforceInterface(), reading the RPC 27394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // header with the strict mode policy mask and the interface name. 27494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // Note that we ignore the strict_policy and don't propagate it 27594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // further (since we do no outbound RPCs anyway). 27694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood strict_policy = bio_get_uint32(msg); 27794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood s = bio_get_string16(msg, &len); 2787d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich if (s == NULL) { 2797d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich return -1; 2807d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich } 2817d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich 28294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if ((len != (sizeof(svcmgr_id) / 2)) || 28394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood memcmp(svcmgr_id, s, sizeof(svcmgr_id))) { 2847d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich fprintf(stderr,"invalid id %s\n", str8(s, len)); 28594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 28694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 28794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 28869154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn if (sehandle && selinux_status_updated() > 0) { 28961f8dfa24b0846ae66328891f8facf9e06237c15Kouji Shiotani#ifdef VENDORSERVICEMANAGER 29061f8dfa24b0846ae66328891f8facf9e06237c15Kouji Shiotani struct selabel_handle *tmp_sehandle = selinux_android_vendor_service_context_handle(); 29161f8dfa24b0846ae66328891f8facf9e06237c15Kouji Shiotani#else 29269154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn struct selabel_handle *tmp_sehandle = selinux_android_service_context_handle(); 29361f8dfa24b0846ae66328891f8facf9e06237c15Kouji Shiotani#endif 29469154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn if (tmp_sehandle) { 29569154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn selabel_close(sehandle); 29669154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn sehandle = tmp_sehandle; 29769154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn } 29869154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn } 29969154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 30094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood switch(txn->code) { 30194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case SVC_MGR_GET_SERVICE: 30294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case SVC_MGR_CHECK_SERVICE: 30394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood s = bio_get_string16(msg, &len); 3047d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich if (s == NULL) { 3057d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich return -1; 3067d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich } 307d57d9b900da83b1b5431d90e250f86c0047c618aIan Pedowitz handle = do_find_service(s, len, txn->sender_euid, txn->sender_pid); 3085fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu if (!handle) 30994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 3105fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu bio_put_ref(reply, handle); 31194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 31294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 31394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case SVC_MGR_ADD_SERVICE: 31494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood s = bio_get_string16(msg, &len); 3157d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich if (s == NULL) { 3167d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich return -1; 3177d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich } 3185fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu handle = bio_get_ref(msg); 31994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood allow_isolated = bio_get_uint32(msg) ? 1 : 0; 320f56042d6a496fca2e5cfc1f598251f77a9bc7986Vishnu Nair dumpsys_priority = bio_get_uint32(msg); 321f56042d6a496fca2e5cfc1f598251f77a9bc7986Vishnu Nair if (do_add_service(bs, s, len, handle, txn->sender_euid, allow_isolated, dumpsys_priority, 322f56042d6a496fca2e5cfc1f598251f77a9bc7986Vishnu Nair txn->sender_pid)) 32394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 32494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 32594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 32694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case SVC_MGR_LIST_SERVICES: { 3273a345f0df5f62d77e875a289e9aee89f0d1b526eSerban Constantinescu uint32_t n = bio_get_uint32(msg); 328f56042d6a496fca2e5cfc1f598251f77a9bc7986Vishnu Nair uint32_t req_dumpsys_priority = bio_get_uint32(msg); 32994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 3308fb0f92e0fe3c286ebb120bae9e1570ee109fa12William Roberts if (!svc_can_list(txn->sender_pid, txn->sender_euid)) { 331c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn ALOGE("list_service() uid=%d - PERMISSION DENIED\n", 332c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn txn->sender_euid); 333c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn return -1; 334c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn } 33594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood si = svclist; 336f56042d6a496fca2e5cfc1f598251f77a9bc7986Vishnu Nair // walk through the list of services n times skipping services that 337f56042d6a496fca2e5cfc1f598251f77a9bc7986Vishnu Nair // do not support the requested priority 338f56042d6a496fca2e5cfc1f598251f77a9bc7986Vishnu Nair while (si) { 339f56042d6a496fca2e5cfc1f598251f77a9bc7986Vishnu Nair if (si->dumpsys_priority & req_dumpsys_priority) { 340f56042d6a496fca2e5cfc1f598251f77a9bc7986Vishnu Nair if (n == 0) break; 341f56042d6a496fca2e5cfc1f598251f77a9bc7986Vishnu Nair n--; 342f56042d6a496fca2e5cfc1f598251f77a9bc7986Vishnu Nair } 34394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood si = si->next; 344f56042d6a496fca2e5cfc1f598251f77a9bc7986Vishnu Nair } 34594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (si) { 34694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio_put_string16(reply, si->name); 34794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 34894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 34994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 35094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 35194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood default: 35294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("unknown code %d\n", txn->code); 35394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 35494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 35594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 35694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio_put_uint32(reply, 0); 35794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 35894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 35994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 36069154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 361d57d9b900da83b1b5431d90e250f86c0047c618aIan Pedowitzstatic int audit_callback(void *data, __unused security_class_t cls, char *buf, size_t len) 36269154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn{ 3638fb0f92e0fe3c286ebb120bae9e1570ee109fa12William Roberts struct audit_data *ad = (struct audit_data *)data; 3648fb0f92e0fe3c286ebb120bae9e1570ee109fa12William Roberts 3658fb0f92e0fe3c286ebb120bae9e1570ee109fa12William Roberts if (!ad || !ad->name) { 3668fb0f92e0fe3c286ebb120bae9e1570ee109fa12William Roberts ALOGE("No service manager audit data"); 3678fb0f92e0fe3c286ebb120bae9e1570ee109fa12William Roberts return 0; 3688fb0f92e0fe3c286ebb120bae9e1570ee109fa12William Roberts } 3698fb0f92e0fe3c286ebb120bae9e1570ee109fa12William Roberts 3708fb0f92e0fe3c286ebb120bae9e1570ee109fa12William Roberts snprintf(buf, len, "service=%s pid=%d uid=%d", ad->name, ad->pid, ad->uid); 37169154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn return 0; 37269154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn} 37369154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 37469b0515dcd58a479c41977aca7bd18b865571d09Martijn Coenenint main(int argc, char** argv) 37594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 37694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct binder_state *bs; 37793ba7019cb473158bdea1b8fc73a1db34ea9a129Sandeep Patil union selinux_callback cb; 37869b0515dcd58a479c41977aca7bd18b865571d09Martijn Coenen char *driver; 37994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 38069b0515dcd58a479c41977aca7bd18b865571d09Martijn Coenen if (argc > 1) { 38169b0515dcd58a479c41977aca7bd18b865571d09Martijn Coenen driver = argv[1]; 38269b0515dcd58a479c41977aca7bd18b865571d09Martijn Coenen } else { 38369b0515dcd58a479c41977aca7bd18b865571d09Martijn Coenen driver = "/dev/binder"; 38469b0515dcd58a479c41977aca7bd18b865571d09Martijn Coenen } 38569b0515dcd58a479c41977aca7bd18b865571d09Martijn Coenen 38669b0515dcd58a479c41977aca7bd18b865571d09Martijn Coenen bs = binder_open(driver, 128*1024); 387a44542ca74b7da5b44ba30c205c3244805bb0600Serban Constantinescu if (!bs) { 38831361232e1e7965d00c638ead2903f08f168f1c9Martijn Coenen#ifdef VENDORSERVICEMANAGER 38931361232e1e7965d00c638ead2903f08f168f1c9Martijn Coenen ALOGW("failed to open binder driver %s\n", driver); 39031361232e1e7965d00c638ead2903f08f168f1c9Martijn Coenen while (true) { 39131361232e1e7965d00c638ead2903f08f168f1c9Martijn Coenen sleep(UINT_MAX); 39231361232e1e7965d00c638ead2903f08f168f1c9Martijn Coenen } 39331361232e1e7965d00c638ead2903f08f168f1c9Martijn Coenen#else 39469b0515dcd58a479c41977aca7bd18b865571d09Martijn Coenen ALOGE("failed to open binder driver %s\n", driver); 39531361232e1e7965d00c638ead2903f08f168f1c9Martijn Coenen#endif 396a44542ca74b7da5b44ba30c205c3244805bb0600Serban Constantinescu return -1; 397a44542ca74b7da5b44ba30c205c3244805bb0600Serban Constantinescu } 39894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 39994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (binder_become_context_manager(bs)) { 40094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("cannot become context manager (%s)\n", strerror(errno)); 40194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 40294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 40394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 40493ba7019cb473158bdea1b8fc73a1db34ea9a129Sandeep Patil cb.func_audit = audit_callback; 40593ba7019cb473158bdea1b8fc73a1db34ea9a129Sandeep Patil selinux_set_callback(SELINUX_CB_AUDIT, cb); 40693ba7019cb473158bdea1b8fc73a1db34ea9a129Sandeep Patil cb.func_log = selinux_log_callback; 40793ba7019cb473158bdea1b8fc73a1db34ea9a129Sandeep Patil selinux_set_callback(SELINUX_CB_LOG, cb); 40893ba7019cb473158bdea1b8fc73a1db34ea9a129Sandeep Patil 40931361232e1e7965d00c638ead2903f08f168f1c9Martijn Coenen#ifdef VENDORSERVICEMANAGER 41031361232e1e7965d00c638ead2903f08f168f1c9Martijn Coenen sehandle = selinux_android_vendor_service_context_handle(); 41131361232e1e7965d00c638ead2903f08f168f1c9Martijn Coenen#else 41269154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn sehandle = selinux_android_service_context_handle(); 41331361232e1e7965d00c638ead2903f08f168f1c9Martijn Coenen#endif 414bea0746b241d15626cf0a56828efc1d4640dbda7Stephen Smalley selinux_status_open(true); 41569154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 416eb4d5cbde02b17259e968321ef457b158ce1da4eNick Kralevich if (sehandle == NULL) { 417eb4d5cbde02b17259e968321ef457b158ce1da4eNick Kralevich ALOGE("SELinux: Failed to acquire sehandle. Aborting.\n"); 418eb4d5cbde02b17259e968321ef457b158ce1da4eNick Kralevich abort(); 419eb4d5cbde02b17259e968321ef457b158ce1da4eNick Kralevich } 420c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn 421eb4d5cbde02b17259e968321ef457b158ce1da4eNick Kralevich if (getcon(&service_manager_context) != 0) { 422eb4d5cbde02b17259e968321ef457b158ce1da4eNick Kralevich ALOGE("SELinux: Failed to acquire service_manager context. Aborting.\n"); 423eb4d5cbde02b17259e968321ef457b158ce1da4eNick Kralevich abort(); 424c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn } 425c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn 42669154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 42794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood binder_loop(bs, svcmgr_handler); 4289b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu 42994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 43094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 431