service_manager.c revision bea0746b241d15626cf0a56828efc1d4640dbda7
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 1194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <private/android_filesystem_config.h> 1294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 1369154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn#include <selinux/android.h> 147d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich#include <selinux/avc.h> 1569154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 1694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "binder.h" 1794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 1894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#if 0 1994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#define ALOGI(x...) fprintf(stderr, "svcmgr: " x) 2094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#define ALOGE(x...) fprintf(stderr, "svcmgr: " x) 2194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#else 2294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#define LOG_TAG "ServiceManager" 2394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <cutils/log.h> 2494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#endif 2594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 267d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevichconst char *str8(const uint16_t *x, size_t x_len) 2794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 2894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood static char buf[128]; 297d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich size_t max = 127; 3094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood char *p = buf; 3194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 327d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich if (x_len < max) { 337d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich max = x_len; 347d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich } 357d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich 3694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (x) { 377d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich while ((max > 0) && (*x != '\0')) { 3894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood *p++ = *x++; 397d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich max--; 4094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 4194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 4294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood *p++ = 0; 4394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return buf; 4494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 4594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 469b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescuint str16eq(const uint16_t *a, const char *b) 4794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 4894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood while (*a && *b) 4994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (*a++ != *b++) return 0; 5094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (*a || *b) 5194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 5294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 1; 5394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 5494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 55c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahnstatic int selinux_enabled; 56c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahnstatic char *service_manager_context; 5769154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahnstatic struct selabel_handle* sehandle; 5869154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 59c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahnstatic bool check_mac_perms(pid_t spid, const char *tctx, const char *perm, const char *name) 6069154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn{ 6169154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn char *sctx = NULL; 62c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn const char *class = "service_manager"; 63c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn bool allowed; 6469154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 65c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn if (getpidcon(spid, &sctx) < 0) { 66c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn ALOGE("SELinux: getpidcon(pid=%d) failed to retrieve pid context.\n", spid); 6769154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn return false; 6869154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn } 6969154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 70c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn int result = selinux_check_access(sctx, tctx, class, perm, (void *) name); 71c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn allowed = (result == 0); 72c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn 73c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn freecon(sctx); 74c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn return allowed; 75c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn} 76c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn 77c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahnstatic bool check_mac_perms_from_getcon(pid_t spid, const char *perm) 78c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn{ 79c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn if (selinux_enabled <= 0) { 80c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn return true; 8169154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn } 8269154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 83c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn return check_mac_perms(spid, service_manager_context, perm, NULL); 84c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn} 85c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn 86c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahnstatic bool check_mac_perms_from_lookup(pid_t spid, const char *perm, const char *name) 87c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn{ 88c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn bool allowed; 89c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn char *tctx = NULL; 90c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn 91c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn if (selinux_enabled <= 0) { 92c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn return true; 9369154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn } 9469154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 95c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn if (!sehandle) { 96c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn ALOGE("SELinux: Failed to find sehandle. Aborting service_manager.\n"); 97c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn abort(); 9869154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn } 9969154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 100c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn if (selabel_lookup(sehandle, &tctx, name, 0) != 0) { 101c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn ALOGE("SELinux: No match for %s in service_contexts.\n", name); 10269154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn return false; 10369154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn } 10469154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 105c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn allowed = check_mac_perms(spid, tctx, perm, name); 10669154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn freecon(tctx); 10769154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn return allowed; 10869154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn} 10969154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 110c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahnstatic int svc_can_register(const uint16_t *name, size_t name_len, pid_t spid) 111c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn{ 112c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn const char *perm = "add"; 113c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn return check_mac_perms_from_lookup(spid, perm, str8(name, name_len)) ? 1 : 0; 114c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn} 115c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn 116c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahnstatic int svc_can_list(pid_t spid) 11794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 118c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn const char *perm = "list"; 119c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn return check_mac_perms_from_getcon(spid, perm) ? 1 : 0; 120c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn} 121c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn 122c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahnstatic int svc_can_find(const uint16_t *name, size_t name_len, pid_t spid) 123c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn{ 124c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn const char *perm = "find"; 125c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn return check_mac_perms_from_lookup(spid, perm, str8(name, name_len)) ? 1 : 0; 12694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 12794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 1289b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescustruct svcinfo 12994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 13094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct svcinfo *next; 1315fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu uint32_t handle; 13294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct binder_death death; 13394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int allow_isolated; 1349b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu size_t len; 13594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint16_t name[0]; 13694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}; 13794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 1389b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescustruct svcinfo *svclist = NULL; 13994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 1409b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescustruct svcinfo *find_svc(const uint16_t *s16, size_t len) 14194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 14294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct svcinfo *si; 14394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 14494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood for (si = svclist; si; si = si->next) { 14594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if ((len == si->len) && 14694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood !memcmp(s16, si->name, len * sizeof(uint16_t))) { 14794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return si; 14894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 14994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 1509b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu return NULL; 15194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 15294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 15394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid svcinfo_death(struct binder_state *bs, void *ptr) 15494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 1559b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu struct svcinfo *si = (struct svcinfo* ) ptr; 1569b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu 1577d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich ALOGI("service '%s' died\n", str8(si->name, si->len)); 1585fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu if (si->handle) { 1595fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu binder_release(bs, si->handle); 1605fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu si->handle = 0; 1619b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu } 16294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 16394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 1649b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescuuint16_t svcmgr_id[] = { 16594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 'a','n','d','r','o','i','d','.','o','s','.', 1669b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu 'I','S','e','r','v','i','c','e','M','a','n','a','g','e','r' 16794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}; 16894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 1699b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu 170c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahnuint32_t do_find_service(struct binder_state *bs, const uint16_t *s, size_t len, uid_t uid, pid_t spid) 17194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 172b27bbd18bb65b3744ae066fcd6826285dec8b469Nick Kralevich struct svcinfo *si = find_svc(s, len); 17394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 174b27bbd18bb65b3744ae066fcd6826285dec8b469Nick Kralevich if (!si || !si->handle) { 175c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn return 0; 176c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn } 177b27bbd18bb65b3744ae066fcd6826285dec8b469Nick Kralevich 178b27bbd18bb65b3744ae066fcd6826285dec8b469Nick Kralevich if (!si->allow_isolated) { 179b27bbd18bb65b3744ae066fcd6826285dec8b469Nick Kralevich // If this service doesn't allow access from isolated processes, 180b27bbd18bb65b3744ae066fcd6826285dec8b469Nick Kralevich // then check the uid to see if it is isolated. 181b27bbd18bb65b3744ae066fcd6826285dec8b469Nick Kralevich uid_t appid = uid % AID_USER; 182b27bbd18bb65b3744ae066fcd6826285dec8b469Nick Kralevich if (appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END) { 183b27bbd18bb65b3744ae066fcd6826285dec8b469Nick Kralevich return 0; 18494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 185b27bbd18bb65b3744ae066fcd6826285dec8b469Nick Kralevich } 186b27bbd18bb65b3744ae066fcd6826285dec8b469Nick Kralevich 187b27bbd18bb65b3744ae066fcd6826285dec8b469Nick Kralevich if (!svc_can_find(s, len, spid)) { 18894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 18994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 190b27bbd18bb65b3744ae066fcd6826285dec8b469Nick Kralevich 191b27bbd18bb65b3744ae066fcd6826285dec8b469Nick Kralevich return si->handle; 19294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 19394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 19494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodint do_add_service(struct binder_state *bs, 1959b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu const uint16_t *s, size_t len, 19669154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn uint32_t handle, uid_t uid, int allow_isolated, 19769154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn pid_t spid) 19894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 19994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct svcinfo *si; 2003a345f0df5f62d77e875a289e9aee89f0d1b526eSerban Constantinescu 2017d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich //ALOGI("add_service('%s',%x,%s) uid=%d\n", str8(s, len), handle, 20294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // allow_isolated ? "allow_isolated" : "!allow_isolated", uid); 20394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 2045fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu if (!handle || (len == 0) || (len > 127)) 20594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 20694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 207c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn if (!svc_can_register(s, len, spid)) { 2085fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu ALOGE("add_service('%s',%x) uid=%d - PERMISSION DENIED\n", 2097d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich str8(s, len), handle, uid); 21094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 21194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 21294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 21394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood si = find_svc(s, len); 21494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (si) { 2155fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu if (si->handle) { 2165fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu ALOGE("add_service('%s',%x) uid=%d - ALREADY REGISTERED, OVERRIDE\n", 2177d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich str8(s, len), handle, uid); 21894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood svcinfo_death(bs, si); 21994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 2205fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu si->handle = handle; 22194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else { 22294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t)); 22394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!si) { 2245fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu ALOGE("add_service('%s',%x) uid=%d - OUT OF MEMORY\n", 2257d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich str8(s, len), handle, uid); 22694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 22794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 2285fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu si->handle = handle; 22994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood si->len = len; 23094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood memcpy(si->name, s, (len + 1) * sizeof(uint16_t)); 23194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood si->name[len] = '\0'; 2329b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu si->death.func = (void*) svcinfo_death; 23394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood si->death.ptr = si; 23494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood si->allow_isolated = allow_isolated; 23594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood si->next = svclist; 23694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood svclist = si; 23794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 23894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 2395fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu binder_acquire(bs, handle); 2405fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu binder_link_to_death(bs, handle, &si->death); 24194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 24294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 24394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 24494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodint svcmgr_handler(struct binder_state *bs, 245bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu struct binder_transaction_data *txn, 24694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct binder_io *msg, 24794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct binder_io *reply) 24894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 24994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct svcinfo *si; 25094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint16_t *s; 2519b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu size_t len; 2525fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu uint32_t handle; 25394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint32_t strict_policy; 25494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int allow_isolated; 25594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 2560b41ad5d6ec86cd2d481969dcff7e88f2805324fElliott Hughes //ALOGI("target=%p code=%d pid=%d uid=%d\n", 2570b41ad5d6ec86cd2d481969dcff7e88f2805324fElliott Hughes // (void*) txn->target.ptr, txn->code, txn->sender_pid, txn->sender_euid); 25894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 2590b41ad5d6ec86cd2d481969dcff7e88f2805324fElliott Hughes if (txn->target.ptr != BINDER_SERVICE_MANAGER) 26094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 26194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 262e5245cbf5d4e830cf605ef07f5d284d7c5d2867eArve Hjønnevåg if (txn->code == PING_TRANSACTION) 263e5245cbf5d4e830cf605ef07f5d284d7c5d2867eArve Hjønnevåg return 0; 264e5245cbf5d4e830cf605ef07f5d284d7c5d2867eArve Hjønnevåg 26594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // Equivalent to Parcel::enforceInterface(), reading the RPC 26694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // header with the strict mode policy mask and the interface name. 26794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // Note that we ignore the strict_policy and don't propagate it 26894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // further (since we do no outbound RPCs anyway). 26994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood strict_policy = bio_get_uint32(msg); 27094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood s = bio_get_string16(msg, &len); 2717d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich if (s == NULL) { 2727d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich return -1; 2737d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich } 2747d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich 27594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if ((len != (sizeof(svcmgr_id) / 2)) || 27694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood memcmp(svcmgr_id, s, sizeof(svcmgr_id))) { 2777d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich fprintf(stderr,"invalid id %s\n", str8(s, len)); 27894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 27994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 28094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 28169154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn if (sehandle && selinux_status_updated() > 0) { 28269154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn struct selabel_handle *tmp_sehandle = selinux_android_service_context_handle(); 28369154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn if (tmp_sehandle) { 28469154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn selabel_close(sehandle); 28569154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn sehandle = tmp_sehandle; 28669154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn } 28769154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn } 28869154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 28994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood switch(txn->code) { 29094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case SVC_MGR_GET_SERVICE: 29194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case SVC_MGR_CHECK_SERVICE: 29294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood s = bio_get_string16(msg, &len); 2937d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich if (s == NULL) { 2947d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich return -1; 2957d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich } 296c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn handle = do_find_service(bs, s, len, txn->sender_euid, txn->sender_pid); 2975fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu if (!handle) 29894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 2995fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu bio_put_ref(reply, handle); 30094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 30194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 30294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case SVC_MGR_ADD_SERVICE: 30394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood s = bio_get_string16(msg, &len); 3047d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich if (s == NULL) { 3057d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich return -1; 3067d42a3c31ba78a418f9bdde0e0ab951469f321b5Nick Kralevich } 3075fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu handle = bio_get_ref(msg); 30894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood allow_isolated = bio_get_uint32(msg) ? 1 : 0; 30969154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn if (do_add_service(bs, s, len, handle, txn->sender_euid, 31069154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn allow_isolated, txn->sender_pid)) 31194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 31294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 31394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 31494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case SVC_MGR_LIST_SERVICES: { 3153a345f0df5f62d77e875a289e9aee89f0d1b526eSerban Constantinescu uint32_t n = bio_get_uint32(msg); 31694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 317c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn if (!svc_can_list(txn->sender_pid)) { 318c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn ALOGE("list_service() uid=%d - PERMISSION DENIED\n", 319c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn txn->sender_euid); 320c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn return -1; 321c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn } 32294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood si = svclist; 32394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood while ((n-- > 0) && si) 32494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood si = si->next; 32594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (si) { 32694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio_put_string16(reply, si->name); 32794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 32894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 32994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 33094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 33194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood default: 33294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("unknown code %d\n", txn->code); 33394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 33494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 33594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 33694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio_put_uint32(reply, 0); 33794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 33894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 33994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 34069154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 34169154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahnstatic int audit_callback(void *data, security_class_t cls, char *buf, size_t len) 34269154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn{ 34369154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn snprintf(buf, len, "service=%s", !data ? "NULL" : (char *)data); 34469154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn return 0; 34569154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn} 34669154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 34794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodint main(int argc, char **argv) 34894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 34994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct binder_state *bs; 35094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 35194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bs = binder_open(128*1024); 352a44542ca74b7da5b44ba30c205c3244805bb0600Serban Constantinescu if (!bs) { 353a44542ca74b7da5b44ba30c205c3244805bb0600Serban Constantinescu ALOGE("failed to open binder driver\n"); 354a44542ca74b7da5b44ba30c205c3244805bb0600Serban Constantinescu return -1; 355a44542ca74b7da5b44ba30c205c3244805bb0600Serban Constantinescu } 35694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 35794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (binder_become_context_manager(bs)) { 35894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("cannot become context manager (%s)\n", strerror(errno)); 35994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 36094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 36194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 362c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn selinux_enabled = is_selinux_enabled(); 36369154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn sehandle = selinux_android_service_context_handle(); 364bea0746b241d15626cf0a56828efc1d4640dbda7Stephen Smalley selinux_status_open(true); 36569154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 366c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn if (selinux_enabled > 0) { 367c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn if (sehandle == NULL) { 368c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn ALOGE("SELinux: Failed to acquire sehandle. Aborting.\n"); 369c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn abort(); 370c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn } 371c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn 372c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn if (getcon(&service_manager_context) != 0) { 373c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn ALOGE("SELinux: Failed to acquire service_manager context. Aborting.\n"); 374c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn abort(); 375c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn } 376c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn } 377c67e6307cadb1f2cd876907c42d39b8374b93acdRiley Spahn 37869154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn union selinux_callback cb; 37969154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn cb.func_audit = audit_callback; 38069154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn selinux_set_callback(SELINUX_CB_AUDIT, cb); 38169154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn cb.func_log = selinux_log_callback; 38269154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn selinux_set_callback(SELINUX_CB_LOG, cb); 38369154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 38494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood binder_loop(bs, svcmgr_handler); 3859b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu 38694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 38794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 388