service_manager.c revision 69154df9efd3ffb7580b72a0138f58a2f5443db6
194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood/* Copyright 2008 The Android Open Source Project 294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood */ 394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <stdio.h> 594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <stdlib.h> 694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <errno.h> 794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <fcntl.h> 894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <private/android_filesystem_config.h> 1094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 1169154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn#include <selinux/android.h> 1269154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 1394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "binder.h" 1494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 1594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#if 0 1694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#define ALOGI(x...) fprintf(stderr, "svcmgr: " x) 1794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#define ALOGE(x...) fprintf(stderr, "svcmgr: " x) 1894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#else 1994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#define LOG_TAG "ServiceManager" 2094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <cutils/log.h> 2194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#endif 2294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 2394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood/* TODO: 2494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood * These should come from a config file or perhaps be 2594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood * based on some namespace rules of some sort (media 2694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood * uid can register media.*, etc) 2794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood */ 2894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic struct { 299b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu uid_t uid; 3094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood const char *name; 3194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} allowed[] = { 3294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { AID_MEDIA, "media.audio_flinger" }, 3364c8be07878a6a110e5386c5f789fa9db51c5746Glenn Kasten { AID_MEDIA, "media.log" }, 3494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { AID_MEDIA, "media.player" }, 3594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { AID_MEDIA, "media.camera" }, 3694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { AID_MEDIA, "media.audio_policy" }, 3794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { AID_DRM, "drm.drmManager" }, 3894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { AID_NFC, "nfc" }, 3994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { AID_BLUETOOTH, "bluetooth" }, 4094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { AID_RADIO, "radio.phone" }, 4194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { AID_RADIO, "radio.sms" }, 4294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { AID_RADIO, "radio.phonesubinfo" }, 4394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { AID_RADIO, "radio.simphonebook" }, 4494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood/* TODO: remove after phone services are updated: */ 4594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { AID_RADIO, "phone" }, 4694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { AID_RADIO, "sip" }, 4794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { AID_RADIO, "isms" }, 4894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { AID_RADIO, "iphonesubinfo" }, 4994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { AID_RADIO, "simphonebook" }, 5094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { AID_MEDIA, "common_time.clock" }, 5194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { AID_MEDIA, "common_time.config" }, 52244408786cf1f374eeacbf6d16dd5a6f7b5e3c59Kenny Root { AID_KEYSTORE, "android.security.keystore" }, 5394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}; 5494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 555fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescuuint32_t svcmgr_handle; 5694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 579b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescuconst char *str8(const uint16_t *x) 5894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 5994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood static char buf[128]; 6094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned max = 127; 6194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood char *p = buf; 6294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 6394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (x) { 6494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood while (*x && max--) { 6594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood *p++ = *x++; 6694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 6794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 6894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood *p++ = 0; 6994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return buf; 7094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 7194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 729b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescuint str16eq(const uint16_t *a, const char *b) 7394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 7494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood while (*a && *b) 7594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (*a++ != *b++) return 0; 7694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (*a || *b) 7794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 7894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 1; 7994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 8094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 8169154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahnstatic struct selabel_handle* sehandle; 8269154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 8369154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahnstatic bool check_mac_perms(const char *name, pid_t spid) 8469154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn{ 8569154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn if (is_selinux_enabled() <= 0) { 8669154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn return true; 8769154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn } 8869154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 8969154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn bool allowed = false; 9069154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 9169154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn const char *class = "service_manager"; 9269154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn const char *perm = "add"; 9369154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 9469154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn char *tctx = NULL; 9569154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn char *sctx = NULL; 9669154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 9769154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn if (!sehandle) { 9869154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn ALOGE("SELinux: Failed to find sehandle %s.\n", name); 9969154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn return false; 10069154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn } 10169154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 10269154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn if (getpidcon(spid, &sctx) < 0) { 10369154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn ALOGE("SELinux: getpidcon failed to retrieve pid context.\n"); 10469154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn return false; 10569154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn } 10669154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 10769154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn if (!sctx) { 10869154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn ALOGE("SELinux: Failed to find sctx for %s.\n", name); 10969154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn return false; 11069154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn } 11169154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 11269154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn if (selabel_lookup(sehandle, &tctx, name, 1) != 0) { 11369154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn ALOGE("SELinux: selabel_lookup failed to set tctx for %s.\n", name); 11469154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn freecon(sctx); 11569154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn return false; 11669154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn } 11769154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 11869154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn if (!tctx) { 11969154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn ALOGE("SELinux: Failed to find tctx for %s.\n", name); 12069154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn freecon(sctx); 12169154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn return false; 12269154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn } 12369154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 12469154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn int result = selinux_check_access(sctx, tctx, class, perm, (void *) name); 12569154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn allowed = (result == 0); 12669154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 12769154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn freecon(sctx); 12869154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn freecon(tctx); 12969154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn return allowed; 13069154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn} 13169154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 13269154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahnstatic int svc_can_register(uid_t uid, const uint16_t *name, pid_t spid) 13394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 1349b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu size_t n; 1359b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu 13694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if ((uid == 0) || (uid == AID_SYSTEM)) 13769154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn return check_mac_perms(str8(name), spid) ? 1 : 0; 13894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 13994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood for (n = 0; n < sizeof(allowed) / sizeof(allowed[0]); n++) 14094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if ((uid == allowed[n].uid) && str16eq(name, allowed[n].name)) 14169154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn return check_mac_perms(str8(name), spid) ? 1 : 0; 14294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 14394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 14494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 14594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 1469b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescustruct svcinfo 14794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 14894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct svcinfo *next; 1495fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu uint32_t handle; 15094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct binder_death death; 15194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int allow_isolated; 1529b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu size_t len; 15394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint16_t name[0]; 15494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}; 15594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 1569b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescustruct svcinfo *svclist = NULL; 15794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 1589b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescustruct svcinfo *find_svc(const uint16_t *s16, size_t len) 15994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 16094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct svcinfo *si; 16194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 16294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood for (si = svclist; si; si = si->next) { 16394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if ((len == si->len) && 16494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood !memcmp(s16, si->name, len * sizeof(uint16_t))) { 16594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return si; 16694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 16794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 1689b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu return NULL; 16994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 17094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 17194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid svcinfo_death(struct binder_state *bs, void *ptr) 17294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 1739b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu struct svcinfo *si = (struct svcinfo* ) ptr; 1749b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu 17594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGI("service '%s' died\n", str8(si->name)); 1765fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu if (si->handle) { 1775fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu binder_release(bs, si->handle); 1785fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu si->handle = 0; 1799b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu } 18094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 18194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 1829b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescuuint16_t svcmgr_id[] = { 18394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 'a','n','d','r','o','i','d','.','o','s','.', 1849b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu 'I','S','e','r','v','i','c','e','M','a','n','a','g','e','r' 18594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}; 18694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 1879b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu 1885fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescuuint32_t do_find_service(struct binder_state *bs, const uint16_t *s, size_t len, uid_t uid) 18994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 19094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct svcinfo *si; 19194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 1923a345f0df5f62d77e875a289e9aee89f0d1b526eSerban Constantinescu si = find_svc(s, len); 1935fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu //ALOGI("check_service('%s') handle = %x\n", str8(s), si ? si->handle : 0); 1945fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu if (si && si->handle) { 19594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!si->allow_isolated) { 19694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // If this service doesn't allow access from isolated processes, 19794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // then check the uid to see if it is isolated. 1989b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu uid_t appid = uid % AID_USER; 19994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END) { 20094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 20194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 20294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 2035fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu return si->handle; 20494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else { 20594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 20694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 20794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 20894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 20994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodint do_add_service(struct binder_state *bs, 2109b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu const uint16_t *s, size_t len, 21169154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn uint32_t handle, uid_t uid, int allow_isolated, 21269154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn pid_t spid) 21394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 21494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct svcinfo *si; 2153a345f0df5f62d77e875a289e9aee89f0d1b526eSerban Constantinescu 2165fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu //ALOGI("add_service('%s',%x,%s) uid=%d\n", str8(s), handle, 21794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // allow_isolated ? "allow_isolated" : "!allow_isolated", uid); 21894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 2195fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu if (!handle || (len == 0) || (len > 127)) 22094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 22194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 22269154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn if (!svc_can_register(uid, s, spid)) { 2235fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu ALOGE("add_service('%s',%x) uid=%d - PERMISSION DENIED\n", 2245fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu str8(s), handle, uid); 22594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 22694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 22794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 22894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood si = find_svc(s, len); 22994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (si) { 2305fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu if (si->handle) { 2315fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu ALOGE("add_service('%s',%x) uid=%d - ALREADY REGISTERED, OVERRIDE\n", 2325fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu str8(s), handle, uid); 23394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood svcinfo_death(bs, si); 23494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 2355fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu si->handle = handle; 23694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else { 23794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t)); 23894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!si) { 2395fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu ALOGE("add_service('%s',%x) uid=%d - OUT OF MEMORY\n", 2405fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu str8(s), handle, uid); 24194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 24294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 2435fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu si->handle = handle; 24494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood si->len = len; 24594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood memcpy(si->name, s, (len + 1) * sizeof(uint16_t)); 24694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood si->name[len] = '\0'; 2479b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu si->death.func = (void*) svcinfo_death; 24894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood si->death.ptr = si; 24994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood si->allow_isolated = allow_isolated; 25094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood si->next = svclist; 25194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood svclist = si; 25294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 25394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 2545fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu binder_acquire(bs, handle); 2555fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu binder_link_to_death(bs, handle, &si->death); 25694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 25794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 25894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 25994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodint svcmgr_handler(struct binder_state *bs, 260bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu struct binder_transaction_data *txn, 26194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct binder_io *msg, 26294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct binder_io *reply) 26394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 26494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct svcinfo *si; 26594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint16_t *s; 2669b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu size_t len; 2675fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu uint32_t handle; 26894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint32_t strict_policy; 26994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int allow_isolated; 27094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 2713a345f0df5f62d77e875a289e9aee89f0d1b526eSerban Constantinescu //ALOGI("target=%x code=%d pid=%d uid=%d\n", 2723a345f0df5f62d77e875a289e9aee89f0d1b526eSerban Constantinescu // txn->target.handle, txn->code, txn->sender_pid, txn->sender_euid); 27394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 274bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu if (txn->target.handle != svcmgr_handle) 27594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 27694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 277e5245cbf5d4e830cf605ef07f5d284d7c5d2867eArve Hjønnevåg if (txn->code == PING_TRANSACTION) 278e5245cbf5d4e830cf605ef07f5d284d7c5d2867eArve Hjønnevåg return 0; 279e5245cbf5d4e830cf605ef07f5d284d7c5d2867eArve Hjønnevåg 28094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // Equivalent to Parcel::enforceInterface(), reading the RPC 28194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // header with the strict mode policy mask and the interface name. 28294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // Note that we ignore the strict_policy and don't propagate it 28394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // further (since we do no outbound RPCs anyway). 28494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood strict_policy = bio_get_uint32(msg); 28594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood s = bio_get_string16(msg, &len); 28694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if ((len != (sizeof(svcmgr_id) / 2)) || 28794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood memcmp(svcmgr_id, s, sizeof(svcmgr_id))) { 28894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr,"invalid id %s\n", str8(s)); 28994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 29094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 29194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 29269154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn if (sehandle && selinux_status_updated() > 0) { 29369154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn struct selabel_handle *tmp_sehandle = selinux_android_service_context_handle(); 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); 3045fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu handle = do_find_service(bs, s, len, txn->sender_euid); 3055fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu if (!handle) 30694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 3075fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu bio_put_ref(reply, handle); 30894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 30994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 31094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case SVC_MGR_ADD_SERVICE: 31194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood s = bio_get_string16(msg, &len); 3125fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu handle = bio_get_ref(msg); 31394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood allow_isolated = bio_get_uint32(msg) ? 1 : 0; 31469154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn if (do_add_service(bs, s, len, handle, txn->sender_euid, 31569154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn allow_isolated, txn->sender_pid)) 31694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 31794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 31894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 31994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case SVC_MGR_LIST_SERVICES: { 3203a345f0df5f62d77e875a289e9aee89f0d1b526eSerban Constantinescu uint32_t n = bio_get_uint32(msg); 32194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 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 36269154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn sehandle = selinux_android_service_context_handle(); 36369154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 36469154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn union selinux_callback cb; 36569154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn cb.func_audit = audit_callback; 36669154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn selinux_set_callback(SELINUX_CB_AUDIT, cb); 36769154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn cb.func_log = selinux_log_callback; 36869154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn selinux_set_callback(SELINUX_CB_LOG, cb); 36969154df9efd3ffb7580b72a0138f58a2f5443db6Riley Spahn 3709b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu svcmgr_handle = BINDER_SERVICE_MANAGER; 37194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood binder_loop(bs, svcmgr_handler); 3729b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu 37394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 37494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 375