ServiceManager: Generic Fixes

This patch fixes some of the ServiceManager issues. The following patches
of the series add fixes to the ABI.

Change-Id: Ib479234c8704e12592f1b149ddec67881bc50230
Signed-off-by: Serban Constantinescu <serban.constantinescu@arm.com>
This commit is contained in:
Serban Constantinescu 2014-01-10 15:48:29 +00:00 committed by David Butcher
parent a44542ca74
commit 9b738bb411
3 changed files with 66 additions and 64 deletions

View File

@ -20,14 +20,14 @@
void bio_init_from_txn(struct binder_io *io, struct binder_transaction_data *txn); void bio_init_from_txn(struct binder_io *io, struct binder_transaction_data *txn);
#if TRACE #if TRACE
void hexdump(void *_data, unsigned len) void hexdump(void *_data, size_t len)
{ {
unsigned char *data = _data; unsigned char *data = _data;
unsigned count; size_t count;
for (count = 0; count < len; count++) { for (count = 0; count < len; count++) {
if ((count & 15) == 0) if ((count & 15) == 0)
fprintf(stderr,"%04x:", count); fprintf(stderr,"%04zu:", count);
fprintf(stderr," %02x %c", *data, fprintf(stderr," %02x %c", *data,
(*data < 32) || (*data > 126) ? '.' : *data); (*data < 32) || (*data > 126) ? '.' : *data);
data++; data++;
@ -41,8 +41,8 @@ void hexdump(void *_data, unsigned len)
void binder_dump_txn(struct binder_transaction_data *txn) void binder_dump_txn(struct binder_transaction_data *txn)
{ {
struct flat_binder_object *obj; struct flat_binder_object *obj;
unsigned *offs = txn->data.ptr.offsets; size_t *offs = txn->data.ptr.offsets;
unsigned count = txn->offsets_size / 4; size_t count = txn->offsets_size / sizeof(size_t);
fprintf(stderr," target %p cookie %p code %08x flags %08x\n", fprintf(stderr," target %p cookie %p code %08x flags %08x\n",
txn->target.ptr, txn->cookie, txn->code, txn->flags); txn->target.ptr, txn->cookie, txn->code, txn->flags);
@ -88,10 +88,10 @@ struct binder_state
{ {
int fd; int fd;
void *mapped; void *mapped;
unsigned mapsize; size_t mapsize;
}; };
struct binder_state *binder_open(unsigned mapsize) struct binder_state *binder_open(size_t mapsize)
{ {
struct binder_state *bs; struct binder_state *bs;
struct binder_version vers; struct binder_version vers;
@ -99,7 +99,7 @@ struct binder_state *binder_open(unsigned mapsize)
bs = malloc(sizeof(*bs)); bs = malloc(sizeof(*bs));
if (!bs) { if (!bs) {
errno = ENOMEM; errno = ENOMEM;
return 0; return NULL;
} }
bs->fd = open("/dev/binder", O_RDWR); bs->fd = open("/dev/binder", O_RDWR);
@ -129,7 +129,7 @@ fail_map:
close(bs->fd); close(bs->fd);
fail_open: fail_open:
free(bs); free(bs);
return 0; return NULL;
} }
void binder_close(struct binder_state *bs) void binder_close(struct binder_state *bs)
@ -144,7 +144,7 @@ int binder_become_context_manager(struct binder_state *bs)
return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0); return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
} }
int binder_write(struct binder_state *bs, void *data, unsigned len) int binder_write(struct binder_state *bs, void *data, size_t len)
{ {
struct binder_write_read bwr; struct binder_write_read bwr;
int res; int res;
@ -164,7 +164,7 @@ int binder_write(struct binder_state *bs, void *data, unsigned len)
void binder_send_reply(struct binder_state *bs, void binder_send_reply(struct binder_state *bs,
struct binder_io *reply, struct binder_io *reply,
void *buffer_to_free, const void *buffer_to_free,
int status) int status)
{ {
struct { struct {
@ -334,7 +334,7 @@ int binder_call(struct binder_state *bs,
bwr.write_size = sizeof(writebuf); bwr.write_size = sizeof(writebuf);
bwr.write_consumed = 0; bwr.write_consumed = 0;
bwr.write_buffer = (unsigned) &writebuf; bwr.write_buffer = (unsigned) &writebuf;
hexdump(msg->data0, msg->data - msg->data0); hexdump(msg->data0, msg->data - msg->data0);
for (;;) { for (;;) {
bwr.read_size = sizeof(readbuf); bwr.read_size = sizeof(readbuf);
@ -368,7 +368,7 @@ void binder_loop(struct binder_state *bs, binder_handler func)
bwr.write_size = 0; bwr.write_size = 0;
bwr.write_consumed = 0; bwr.write_consumed = 0;
bwr.write_buffer = 0; bwr.write_buffer = 0;
readbuf[0] = BC_ENTER_LOOPER; readbuf[0] = BC_ENTER_LOOPER;
binder_write(bs, readbuf, sizeof(unsigned)); binder_write(bs, readbuf, sizeof(unsigned));
@ -406,9 +406,9 @@ void bio_init_from_txn(struct binder_io *bio, struct binder_transaction_data *tx
} }
void bio_init(struct binder_io *bio, void *data, void bio_init(struct binder_io *bio, void *data,
uint32_t maxdata, uint32_t maxoffs) size_t maxdata, size_t maxoffs)
{ {
uint32_t n = maxoffs * sizeof(uint32_t); size_t n = maxoffs * sizeof(size_t);
if (n > maxdata) { if (n > maxdata) {
bio->flags = BIO_F_OVERFLOW; bio->flags = BIO_F_OVERFLOW;
@ -429,7 +429,7 @@ static void *bio_alloc(struct binder_io *bio, uint32_t size)
size = (size + 3) & (~3); size = (size + 3) & (~3);
if (size > bio->data_avail) { if (size > bio->data_avail) {
bio->flags |= BIO_F_OVERFLOW; bio->flags |= BIO_F_OVERFLOW;
return 0; return NULL;
} else { } else {
void *ptr = bio->data; void *ptr = bio->data;
bio->data += size; bio->data += size;
@ -456,7 +456,7 @@ static struct flat_binder_object *bio_alloc_obj(struct binder_io *bio)
struct flat_binder_object *obj; struct flat_binder_object *obj;
obj = bio_alloc(bio, sizeof(*obj)); obj = bio_alloc(bio, sizeof(*obj));
if (obj && bio->offs_avail) { if (obj && bio->offs_avail) {
bio->offs_avail--; bio->offs_avail--;
*bio->offs++ = ((char*) obj) - ((char*) bio->data0); *bio->offs++ = ((char*) obj) - ((char*) bio->data0);
@ -464,7 +464,7 @@ static struct flat_binder_object *bio_alloc_obj(struct binder_io *bio)
} }
bio->flags |= BIO_F_OVERFLOW; bio->flags |= BIO_F_OVERFLOW;
return 0; return NULL;
} }
void bio_put_uint32(struct binder_io *bio, uint32_t n) void bio_put_uint32(struct binder_io *bio, uint32_t n)
@ -508,7 +508,7 @@ void bio_put_ref(struct binder_io *bio, void *ptr)
void bio_put_string16(struct binder_io *bio, const uint16_t *str) void bio_put_string16(struct binder_io *bio, const uint16_t *str)
{ {
uint32_t len; size_t len;
uint16_t *ptr; uint16_t *ptr;
if (!str) { if (!str) {
@ -524,7 +524,8 @@ void bio_put_string16(struct binder_io *bio, const uint16_t *str)
return; return;
} }
bio_put_uint32(bio, len); /* Note: The payload will carry 32bit size instead of size_t */
bio_put_uint32(bio, (uint32_t) len);
len = (len + 1) * sizeof(uint16_t); len = (len + 1) * sizeof(uint16_t);
ptr = bio_alloc(bio, len); ptr = bio_alloc(bio, len);
if (ptr) if (ptr)
@ -534,7 +535,7 @@ void bio_put_string16(struct binder_io *bio, const uint16_t *str)
void bio_put_string16_x(struct binder_io *bio, const char *_str) void bio_put_string16_x(struct binder_io *bio, const char *_str)
{ {
unsigned char *str = (unsigned char*) _str; unsigned char *str = (unsigned char*) _str;
uint32_t len; size_t len;
uint16_t *ptr; uint16_t *ptr;
if (!str) { if (!str) {
@ -549,6 +550,7 @@ void bio_put_string16_x(struct binder_io *bio, const char *_str)
return; return;
} }
/* Note: The payload will carry 32bit size instead of size_t */
bio_put_uint32(bio, len); bio_put_uint32(bio, len);
ptr = bio_alloc(bio, (len + 1) * sizeof(uint16_t)); ptr = bio_alloc(bio, (len + 1) * sizeof(uint16_t));
if (!ptr) if (!ptr)
@ -559,14 +561,14 @@ void bio_put_string16_x(struct binder_io *bio, const char *_str)
*ptr++ = 0; *ptr++ = 0;
} }
static void *bio_get(struct binder_io *bio, uint32_t size) static void *bio_get(struct binder_io *bio, size_t size)
{ {
size = (size + 3) & (~3); size = (size + 3) & (~3);
if (bio->data_avail < size){ if (bio->data_avail < size){
bio->data_avail = 0; bio->data_avail = 0;
bio->flags |= BIO_F_OVERFLOW; bio->flags |= BIO_F_OVERFLOW;
return 0; return NULL;
} else { } else {
void *ptr = bio->data; void *ptr = bio->data;
bio->data += size; bio->data += size;
@ -581,10 +583,12 @@ uint32_t bio_get_uint32(struct binder_io *bio)
return ptr ? *ptr : 0; return ptr ? *ptr : 0;
} }
uint16_t *bio_get_string16(struct binder_io *bio, unsigned *sz) uint16_t *bio_get_string16(struct binder_io *bio, size_t *sz)
{ {
unsigned len; size_t len;
len = bio_get_uint32(bio);
/* Note: The payload will carry 32bit size instead of size_t */
len = (size_t) bio_get_uint32(bio);
if (sz) if (sz)
*sz = len; *sz = len;
return bio_get(bio, (len + 1) * sizeof(uint16_t)); return bio_get(bio, (len + 1) * sizeof(uint16_t));
@ -592,8 +596,8 @@ uint16_t *bio_get_string16(struct binder_io *bio, unsigned *sz)
static struct flat_binder_object *_bio_get_obj(struct binder_io *bio) static struct flat_binder_object *_bio_get_obj(struct binder_io *bio)
{ {
unsigned n; size_t n;
unsigned off = bio->data - bio->data0; size_t off = bio->data - bio->data0;
/* TODO: be smarter about this? */ /* TODO: be smarter about this? */
for (n = 0; n < bio->offs_avail; n++) { for (n = 0; n < bio->offs_avail; n++) {
@ -603,7 +607,7 @@ static struct flat_binder_object *_bio_get_obj(struct binder_io *bio)
bio->data_avail = 0; bio->data_avail = 0;
bio->flags |= BIO_F_OVERFLOW; bio->flags |= BIO_F_OVERFLOW;
return 0; return NULL;
} }
void *bio_get_ref(struct binder_io *bio) void *bio_get_ref(struct binder_io *bio)

View File

@ -12,12 +12,12 @@ struct binder_state;
struct binder_io struct binder_io
{ {
char *data; /* pointer to read/write from */ char *data; /* pointer to read/write from */
uint32_t *offs; /* array of offsets */ size_t *offs; /* array of offsets */
uint32_t data_avail; /* bytes available in data buffer */ size_t data_avail; /* bytes available in data buffer */
uint32_t offs_avail; /* entries available in offsets array */ size_t offs_avail; /* entries available in offsets array */
char *data0; /* start of data buffer */ char *data0; /* start of data buffer */
uint32_t *offs0; /* start of offsets buffer */ size_t *offs0; /* start of offsets buffer */
uint32_t flags; uint32_t flags;
uint32_t unused; uint32_t unused;
}; };
@ -25,7 +25,7 @@ struct binder_io
struct binder_death { struct binder_death {
void (*func)(struct binder_state *bs, void *ptr); void (*func)(struct binder_state *bs, void *ptr);
void *ptr; void *ptr;
}; };
/* the one magic object */ /* the one magic object */
#define BINDER_SERVICE_MANAGER ((void*) 0) #define BINDER_SERVICE_MANAGER ((void*) 0)
@ -44,7 +44,7 @@ typedef int (*binder_handler)(struct binder_state *bs,
struct binder_io *msg, struct binder_io *msg,
struct binder_io *reply); struct binder_io *reply);
struct binder_state *binder_open(unsigned mapsize); struct binder_state *binder_open(size_t mapsize);
void binder_close(struct binder_state *bs); void binder_close(struct binder_state *bs);
/* initiate a blocking binder call /* initiate a blocking binder call
@ -77,9 +77,7 @@ int binder_become_context_manager(struct binder_state *bs);
* offset entries to reserve from the buffer * offset entries to reserve from the buffer
*/ */
void bio_init(struct binder_io *bio, void *data, void bio_init(struct binder_io *bio, void *data,
uint32_t maxdata, uint32_t maxobjects); size_t maxdata, size_t maxobjects);
void bio_destroy(struct binder_io *bio);
void bio_put_obj(struct binder_io *bio, void *ptr); void bio_put_obj(struct binder_io *bio, void *ptr);
void bio_put_ref(struct binder_io *bio, void *ptr); void bio_put_ref(struct binder_io *bio, void *ptr);
@ -88,8 +86,7 @@ void bio_put_string16(struct binder_io *bio, const uint16_t *str);
void bio_put_string16_x(struct binder_io *bio, const char *_str); void bio_put_string16_x(struct binder_io *bio, const char *_str);
uint32_t bio_get_uint32(struct binder_io *bio); uint32_t bio_get_uint32(struct binder_io *bio);
uint16_t *bio_get_string16(struct binder_io *bio, uint32_t *sz); uint16_t *bio_get_string16(struct binder_io *bio, size_t *sz);
void *bio_get_obj(struct binder_io *bio);
void *bio_get_ref(struct binder_io *bio); void *bio_get_ref(struct binder_io *bio);
#endif #endif

View File

@ -24,7 +24,7 @@
* uid can register media.*, etc) * uid can register media.*, etc)
*/ */
static struct { static struct {
unsigned uid; uid_t uid;
const char *name; const char *name;
} allowed[] = { } allowed[] = {
{ AID_MEDIA, "media.audio_flinger" }, { AID_MEDIA, "media.audio_flinger" },
@ -52,7 +52,7 @@ static struct {
void *svcmgr_handle; void *svcmgr_handle;
const char *str8(uint16_t *x) const char *str8(const uint16_t *x)
{ {
static char buf[128]; static char buf[128];
unsigned max = 127; unsigned max = 127;
@ -67,7 +67,7 @@ const char *str8(uint16_t *x)
return buf; return buf;
} }
int str16eq(uint16_t *a, const char *b) int str16eq(const uint16_t *a, const char *b)
{ {
while (*a && *b) while (*a && *b)
if (*a++ != *b++) return 0; if (*a++ != *b++) return 0;
@ -76,10 +76,10 @@ int str16eq(uint16_t *a, const char *b)
return 1; 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)) if ((uid == 0) || (uid == AID_SYSTEM))
return 1; return 1;
@ -90,19 +90,19 @@ int svc_can_register(unsigned uid, uint16_t *name)
return 0; return 0;
} }
struct svcinfo struct svcinfo
{ {
struct svcinfo *next; struct svcinfo *next;
void *ptr; void *ptr;
struct binder_death death; struct binder_death death;
int allow_isolated; int allow_isolated;
unsigned len; size_t len;
uint16_t name[0]; 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; struct svcinfo *si;
@ -112,26 +112,27 @@ struct svcinfo *find_svc(uint16_t *s16, unsigned len)
return si; return si;
} }
} }
return 0; return NULL;
} }
void svcinfo_death(struct binder_state *bs, void *ptr) 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)); ALOGI("service '%s' died\n", str8(si->name));
if (si->ptr) { if (si->ptr) {
binder_release(bs, si->ptr); binder_release(bs, si->ptr);
si->ptr = 0; si->ptr = 0;
} }
} }
uint16_t svcmgr_id[] = { uint16_t svcmgr_id[] = {
'a','n','d','r','o','i','d','.','o','s','.', '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)
void *do_find_service(struct binder_state *bs, const uint16_t *s, size_t len, uid_t uid)
{ {
struct svcinfo *si; struct svcinfo *si;
si = find_svc(s, len); si = find_svc(s, len);
@ -141,7 +142,7 @@ void *do_find_service(struct binder_state *bs, uint16_t *s, unsigned len, unsign
if (!si->allow_isolated) { if (!si->allow_isolated) {
// If this service doesn't allow access from isolated processes, // If this service doesn't allow access from isolated processes,
// then check the uid to see if it is isolated. // 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) { if (appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END) {
return 0; return 0;
} }
@ -153,8 +154,8 @@ void *do_find_service(struct binder_state *bs, uint16_t *s, unsigned len, unsign
} }
int do_add_service(struct binder_state *bs, int do_add_service(struct binder_state *bs,
uint16_t *s, unsigned len, const uint16_t *s, size_t len,
void *ptr, unsigned uid, int allow_isolated) void *ptr, uid_t uid, int allow_isolated)
{ {
struct svcinfo *si; struct svcinfo *si;
//ALOGI("add_service('%s',%p,%s) uid=%d\n", str8(s), ptr, //ALOGI("add_service('%s',%p,%s) uid=%d\n", str8(s), ptr,
@ -188,7 +189,7 @@ int do_add_service(struct binder_state *bs,
si->len = len; si->len = len;
memcpy(si->name, s, (len + 1) * sizeof(uint16_t)); memcpy(si->name, s, (len + 1) * sizeof(uint16_t));
si->name[len] = '\0'; si->name[len] = '\0';
si->death.func = svcinfo_death; si->death.func = (void*) svcinfo_death;
si->death.ptr = si; si->death.ptr = si;
si->allow_isolated = allow_isolated; si->allow_isolated = allow_isolated;
si->next = svclist; si->next = svclist;
@ -207,7 +208,7 @@ int svcmgr_handler(struct binder_state *bs,
{ {
struct svcinfo *si; struct svcinfo *si;
uint16_t *s; uint16_t *s;
unsigned len; size_t len;
void *ptr; void *ptr;
uint32_t strict_policy; uint32_t strict_policy;
int allow_isolated; int allow_isolated;
@ -272,7 +273,6 @@ int svcmgr_handler(struct binder_state *bs,
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
struct binder_state *bs; struct binder_state *bs;
void *svcmgr = BINDER_SERVICE_MANAGER;
bs = binder_open(128*1024); bs = binder_open(128*1024);
if (!bs) { if (!bs) {
@ -285,7 +285,8 @@ int main(int argc, char **argv)
return -1; return -1;
} }
svcmgr_handle = svcmgr; svcmgr_handle = BINDER_SERVICE_MANAGER;
binder_loop(bs, svcmgr_handler); binder_loop(bs, svcmgr_handler);
return 0; return 0;
} }