diff options
Diffstat (limited to 'cmds/servicemanager/service_manager.c')
-rw-r--r-- | cmds/servicemanager/service_manager.c | 123 |
1 files changed, 66 insertions, 57 deletions
diff --git a/cmds/servicemanager/service_manager.c b/cmds/servicemanager/service_manager.c index 3eaf1eb..79ce6ed 100644 --- a/cmds/servicemanager/service_manager.c +++ b/cmds/servicemanager/service_manager.c @@ -24,7 +24,7 @@ * uid can register media.*, etc) */ static struct { - unsigned uid; + uid_t uid; const char *name; } allowed[] = { { AID_MEDIA, "media.audio_flinger" }, @@ -50,9 +50,9 @@ static struct { { AID_KEYSTORE, "android.security.keystore" }, }; -void *svcmgr_handle; +uint32_t svcmgr_handle; -const char *str8(uint16_t *x) +const char *str8(const uint16_t *x) { static char buf[128]; unsigned max = 127; @@ -67,7 +67,7 @@ const char *str8(uint16_t *x) return buf; } -int str16eq(uint16_t *a, const char *b) +int str16eq(const uint16_t *a, const char *b) { while (*a && *b) if (*a++ != *b++) return 0; @@ -76,10 +76,10 @@ int str16eq(uint16_t *a, const char *b) return 1; } -int svc_can_register(unsigned uid, uint16_t *name) +int svc_can_register(uid_t uid, const uint16_t *name) { - unsigned n; - + size_t n; + if ((uid == 0) || (uid == AID_SYSTEM)) return 1; @@ -90,19 +90,19 @@ int svc_can_register(unsigned uid, uint16_t *name) return 0; } -struct svcinfo +struct svcinfo { struct svcinfo *next; - void *ptr; + uint32_t handle; struct binder_death death; int allow_isolated; - unsigned len; + size_t len; uint16_t name[0]; }; -struct svcinfo *svclist = 0; +struct svcinfo *svclist = NULL; -struct svcinfo *find_svc(uint16_t *s16, unsigned len) +struct svcinfo *find_svc(const uint16_t *s16, size_t len) { struct svcinfo *si; @@ -112,112 +112,117 @@ struct svcinfo *find_svc(uint16_t *s16, unsigned len) return si; } } - return 0; + return NULL; } void svcinfo_death(struct binder_state *bs, void *ptr) { - struct svcinfo *si = ptr; + struct svcinfo *si = (struct svcinfo* ) ptr; + ALOGI("service '%s' died\n", str8(si->name)); - if (si->ptr) { - binder_release(bs, si->ptr); - si->ptr = 0; - } + if (si->handle) { + binder_release(bs, si->handle); + si->handle = 0; + } } -uint16_t svcmgr_id[] = { +uint16_t svcmgr_id[] = { 'a','n','d','r','o','i','d','.','o','s','.', - 'I','S','e','r','v','i','c','e','M','a','n','a','g','e','r' + 'I','S','e','r','v','i','c','e','M','a','n','a','g','e','r' }; - -void *do_find_service(struct binder_state *bs, uint16_t *s, unsigned len, unsigned uid) + +uint32_t do_find_service(struct binder_state *bs, const uint16_t *s, size_t len, uid_t uid) { struct svcinfo *si; - si = find_svc(s, len); -// ALOGI("check_service('%s') ptr = %p\n", str8(s), si ? si->ptr : 0); - if (si && si->ptr) { + si = find_svc(s, len); + //ALOGI("check_service('%s') handle = %x\n", str8(s), si ? si->handle : 0); + if (si && si->handle) { if (!si->allow_isolated) { // If this service doesn't allow access from isolated processes, // then check the uid to see if it is isolated. - unsigned appid = uid % AID_USER; + uid_t appid = uid % AID_USER; if (appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END) { return 0; } } - return si->ptr; + return si->handle; } else { return 0; } } int do_add_service(struct binder_state *bs, - uint16_t *s, unsigned len, - void *ptr, unsigned uid, int allow_isolated) + const uint16_t *s, size_t len, + uint32_t handle, uid_t uid, int allow_isolated) { struct svcinfo *si; - //ALOGI("add_service('%s',%p,%s) uid=%d\n", str8(s), ptr, + + //ALOGI("add_service('%s',%x,%s) uid=%d\n", str8(s), handle, // allow_isolated ? "allow_isolated" : "!allow_isolated", uid); - if (!ptr || (len == 0) || (len > 127)) + if (!handle || (len == 0) || (len > 127)) return -1; if (!svc_can_register(uid, s)) { - ALOGE("add_service('%s',%p) uid=%d - PERMISSION DENIED\n", - str8(s), ptr, uid); + ALOGE("add_service('%s',%x) uid=%d - PERMISSION DENIED\n", + str8(s), handle, uid); return -1; } si = find_svc(s, len); if (si) { - if (si->ptr) { - ALOGE("add_service('%s',%p) uid=%d - ALREADY REGISTERED, OVERRIDE\n", - str8(s), ptr, uid); + if (si->handle) { + ALOGE("add_service('%s',%x) uid=%d - ALREADY REGISTERED, OVERRIDE\n", + str8(s), handle, uid); svcinfo_death(bs, si); } - si->ptr = ptr; + si->handle = handle; } else { si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t)); if (!si) { - ALOGE("add_service('%s',%p) uid=%d - OUT OF MEMORY\n", - str8(s), ptr, uid); + ALOGE("add_service('%s',%x) uid=%d - OUT OF MEMORY\n", + str8(s), handle, uid); return -1; } - si->ptr = ptr; + si->handle = handle; si->len = len; memcpy(si->name, s, (len + 1) * sizeof(uint16_t)); si->name[len] = '\0'; - si->death.func = svcinfo_death; + si->death.func = (void*) svcinfo_death; si->death.ptr = si; si->allow_isolated = allow_isolated; si->next = svclist; svclist = si; } - binder_acquire(bs, ptr); - binder_link_to_death(bs, ptr, &si->death); + binder_acquire(bs, handle); + binder_link_to_death(bs, handle, &si->death); return 0; } int svcmgr_handler(struct binder_state *bs, - struct binder_txn *txn, + struct binder_transaction_data *txn, struct binder_io *msg, struct binder_io *reply) { struct svcinfo *si; uint16_t *s; - unsigned len; - void *ptr; + size_t len; + uint32_t handle; uint32_t strict_policy; int allow_isolated; -// ALOGI("target=%p code=%d pid=%d uid=%d\n", -// txn->target, txn->code, txn->sender_pid, txn->sender_euid); + //ALOGI("target=%x code=%d pid=%d uid=%d\n", + // txn->target.handle, txn->code, txn->sender_pid, txn->sender_euid); - if (txn->target != svcmgr_handle) + if (txn->target.handle != svcmgr_handle) return -1; + if (txn->code == PING_TRANSACTION) + return 0; + // Equivalent to Parcel::enforceInterface(), reading the RPC // header with the strict mode policy mask and the interface name. // Note that we ignore the strict_policy and don't propagate it @@ -234,22 +239,22 @@ int svcmgr_handler(struct binder_state *bs, case SVC_MGR_GET_SERVICE: case SVC_MGR_CHECK_SERVICE: s = bio_get_string16(msg, &len); - ptr = do_find_service(bs, s, len, txn->sender_euid); - if (!ptr) + handle = do_find_service(bs, s, len, txn->sender_euid); + if (!handle) break; - bio_put_ref(reply, ptr); + bio_put_ref(reply, handle); return 0; case SVC_MGR_ADD_SERVICE: s = bio_get_string16(msg, &len); - ptr = bio_get_ref(msg); + handle = bio_get_ref(msg); allow_isolated = bio_get_uint32(msg) ? 1 : 0; - if (do_add_service(bs, s, len, ptr, txn->sender_euid, allow_isolated)) + if (do_add_service(bs, s, len, handle, txn->sender_euid, allow_isolated)) return -1; break; case SVC_MGR_LIST_SERVICES: { - unsigned n = bio_get_uint32(msg); + uint32_t n = bio_get_uint32(msg); si = svclist; while ((n-- > 0) && si) @@ -272,16 +277,20 @@ int svcmgr_handler(struct binder_state *bs, int main(int argc, char **argv) { struct binder_state *bs; - void *svcmgr = BINDER_SERVICE_MANAGER; bs = binder_open(128*1024); + if (!bs) { + ALOGE("failed to open binder driver\n"); + return -1; + } if (binder_become_context_manager(bs)) { ALOGE("cannot become context manager (%s)\n", strerror(errno)); return -1; } - svcmgr_handle = svcmgr; + svcmgr_handle = BINDER_SERVICE_MANAGER; binder_loop(bs, svcmgr_handler); + return 0; } |