Home | History | Annotate | Download | only in servicemanager
      1 /* Copyright 2008 The Android Open Source Project
      2  */
      3 
      4 #define LOG_TAG "Binder"
      5 
      6 #include <errno.h>
      7 #include <fcntl.h>
      8 #include <inttypes.h>
      9 #include <stdio.h>
     10 #include <stdlib.h>
     11 #include <string.h>
     12 #include <sys/mman.h>
     13 #include <unistd.h>
     14 
     15 #include <log/log.h>
     16 
     17 #include "binder.h"
     18 
     19 #define MAX_BIO_SIZE (1 << 30)
     20 
     21 #define TRACE 0
     22 
     23 void bio_init_from_txn(struct binder_io *io, struct binder_transaction_data *txn);
     24 
     25 #if TRACE
     26 void hexdump(void *_data, size_t len)
     27 {
     28     unsigned char *data = _data;
     29     size_t count;
     30 
     31     for (count = 0; count < len; count++) {
     32         if ((count & 15) == 0)
     33             fprintf(stderr,"%04zu:", count);
     34         fprintf(stderr," %02x %c", *data,
     35                 (*data < 32) || (*data > 126) ? '.' : *data);
     36         data++;
     37         if ((count & 15) == 15)
     38             fprintf(stderr,"\n");
     39     }
     40     if ((count & 15) != 0)
     41         fprintf(stderr,"\n");
     42 }
     43 
     44 void binder_dump_txn(struct binder_transaction_data *txn)
     45 {
     46     struct flat_binder_object *obj;
     47     binder_size_t *offs = (binder_size_t *)(uintptr_t)txn->data.ptr.offsets;
     48     size_t count = txn->offsets_size / sizeof(binder_size_t);
     49 
     50     fprintf(stderr,"  target %016"PRIx64"  cookie %016"PRIx64"  code %08x  flags %08x\n",
     51             (uint64_t)txn->target.ptr, (uint64_t)txn->cookie, txn->code, txn->flags);
     52     fprintf(stderr,"  pid %8d  uid %8d  data %"PRIu64"  offs %"PRIu64"\n",
     53             txn->sender_pid, txn->sender_euid, (uint64_t)txn->data_size, (uint64_t)txn->offsets_size);
     54     hexdump((void *)(uintptr_t)txn->data.ptr.buffer, txn->data_size);
     55     while (count--) {
     56         obj = (struct flat_binder_object *) (((char*)(uintptr_t)txn->data.ptr.buffer) + *offs++);
     57         fprintf(stderr,"  - type %08x  flags %08x  ptr %016"PRIx64"  cookie %016"PRIx64"\n",
     58                 obj->type, obj->flags, (uint64_t)obj->binder, (uint64_t)obj->cookie);
     59     }
     60 }
     61 
     62 #define NAME(n) case n: return #n
     63 const char *cmd_name(uint32_t cmd)
     64 {
     65     switch(cmd) {
     66         NAME(BR_NOOP);
     67         NAME(BR_TRANSACTION_COMPLETE);
     68         NAME(BR_INCREFS);
     69         NAME(BR_ACQUIRE);
     70         NAME(BR_RELEASE);
     71         NAME(BR_DECREFS);
     72         NAME(BR_TRANSACTION);
     73         NAME(BR_REPLY);
     74         NAME(BR_FAILED_REPLY);
     75         NAME(BR_DEAD_REPLY);
     76         NAME(BR_DEAD_BINDER);
     77     default: return "???";
     78     }
     79 }
     80 #else
     81 #define hexdump(a,b) do{} while (0)
     82 #define binder_dump_txn(txn)  do{} while (0)
     83 #endif
     84 
     85 #define BIO_F_SHARED    0x01  /* needs to be buffer freed */
     86 #define BIO_F_OVERFLOW  0x02  /* ran out of space */
     87 #define BIO_F_IOERROR   0x04
     88 #define BIO_F_MALLOCED  0x08  /* needs to be free()'d */
     89 
     90 struct binder_state
     91 {
     92     int fd;
     93     void *mapped;
     94     size_t mapsize;
     95 };
     96 
     97 struct binder_state *binder_open(const char* driver, size_t mapsize)
     98 {
     99     struct binder_state *bs;
    100     struct binder_version vers;
    101 
    102     bs = malloc(sizeof(*bs));
    103     if (!bs) {
    104         errno = ENOMEM;
    105         return NULL;
    106     }
    107 
    108     bs->fd = open(driver, O_RDWR | O_CLOEXEC);
    109     if (bs->fd < 0) {
    110         fprintf(stderr,"binder: cannot open %s (%s)\n",
    111                 driver, strerror(errno));
    112         goto fail_open;
    113     }
    114 
    115     if ((ioctl(bs->fd, BINDER_VERSION, &vers) == -1) ||
    116         (vers.protocol_version != BINDER_CURRENT_PROTOCOL_VERSION)) {
    117         fprintf(stderr,
    118                 "binder: kernel driver version (%d) differs from user space version (%d)\n",
    119                 vers.protocol_version, BINDER_CURRENT_PROTOCOL_VERSION);
    120         goto fail_open;
    121     }
    122 
    123     bs->mapsize = mapsize;
    124     bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);
    125     if (bs->mapped == MAP_FAILED) {
    126         fprintf(stderr,"binder: cannot map device (%s)\n",
    127                 strerror(errno));
    128         goto fail_map;
    129     }
    130 
    131     return bs;
    132 
    133 fail_map:
    134     close(bs->fd);
    135 fail_open:
    136     free(bs);
    137     return NULL;
    138 }
    139 
    140 void binder_close(struct binder_state *bs)
    141 {
    142     munmap(bs->mapped, bs->mapsize);
    143     close(bs->fd);
    144     free(bs);
    145 }
    146 
    147 int binder_become_context_manager(struct binder_state *bs)
    148 {
    149     return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
    150 }
    151 
    152 int binder_write(struct binder_state *bs, void *data, size_t len)
    153 {
    154     struct binder_write_read bwr;
    155     int res;
    156 
    157     bwr.write_size = len;
    158     bwr.write_consumed = 0;
    159     bwr.write_buffer = (uintptr_t) data;
    160     bwr.read_size = 0;
    161     bwr.read_consumed = 0;
    162     bwr.read_buffer = 0;
    163     res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
    164     if (res < 0) {
    165         fprintf(stderr,"binder_write: ioctl failed (%s)\n",
    166                 strerror(errno));
    167     }
    168     return res;
    169 }
    170 
    171 void binder_free_buffer(struct binder_state *bs,
    172                         binder_uintptr_t buffer_to_free)
    173 {
    174     struct {
    175         uint32_t cmd_free;
    176         binder_uintptr_t buffer;
    177     } __attribute__((packed)) data;
    178     data.cmd_free = BC_FREE_BUFFER;
    179     data.buffer = buffer_to_free;
    180     binder_write(bs, &data, sizeof(data));
    181 }
    182 
    183 void binder_send_reply(struct binder_state *bs,
    184                        struct binder_io *reply,
    185                        binder_uintptr_t buffer_to_free,
    186                        int status)
    187 {
    188     struct {
    189         uint32_t cmd_free;
    190         binder_uintptr_t buffer;
    191         uint32_t cmd_reply;
    192         struct binder_transaction_data txn;
    193     } __attribute__((packed)) data;
    194 
    195     data.cmd_free = BC_FREE_BUFFER;
    196     data.buffer = buffer_to_free;
    197     data.cmd_reply = BC_REPLY;
    198     data.txn.target.ptr = 0;
    199     data.txn.cookie = 0;
    200     data.txn.code = 0;
    201     if (status) {
    202         data.txn.flags = TF_STATUS_CODE;
    203         data.txn.data_size = sizeof(int);
    204         data.txn.offsets_size = 0;
    205         data.txn.data.ptr.buffer = (uintptr_t)&status;
    206         data.txn.data.ptr.offsets = 0;
    207     } else {
    208         data.txn.flags = 0;
    209         data.txn.data_size = reply->data - reply->data0;
    210         data.txn.offsets_size = ((char*) reply->offs) - ((char*) reply->offs0);
    211         data.txn.data.ptr.buffer = (uintptr_t)reply->data0;
    212         data.txn.data.ptr.offsets = (uintptr_t)reply->offs0;
    213     }
    214     binder_write(bs, &data, sizeof(data));
    215 }
    216 
    217 int binder_parse(struct binder_state *bs, struct binder_io *bio,
    218                  uintptr_t ptr, size_t size, binder_handler func)
    219 {
    220     int r = 1;
    221     uintptr_t end = ptr + (uintptr_t) size;
    222 
    223     while (ptr < end) {
    224         uint32_t cmd = *(uint32_t *) ptr;
    225         ptr += sizeof(uint32_t);
    226 #if TRACE
    227         fprintf(stderr,"%s:\n", cmd_name(cmd));
    228 #endif
    229         switch(cmd) {
    230         case BR_NOOP:
    231             break;
    232         case BR_TRANSACTION_COMPLETE:
    233             break;
    234         case BR_INCREFS:
    235         case BR_ACQUIRE:
    236         case BR_RELEASE:
    237         case BR_DECREFS:
    238 #if TRACE
    239             fprintf(stderr,"  %p, %p\n", (void *)ptr, (void *)(ptr + sizeof(void *)));
    240 #endif
    241             ptr += sizeof(struct binder_ptr_cookie);
    242             break;
    243         case BR_TRANSACTION: {
    244             struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr;
    245             if ((end - ptr) < sizeof(*txn)) {
    246                 ALOGE("parse: txn too small!\n");
    247                 return -1;
    248             }
    249             binder_dump_txn(txn);
    250             if (func) {
    251                 unsigned rdata[256/4];
    252                 struct binder_io msg;
    253                 struct binder_io reply;
    254                 int res;
    255 
    256                 bio_init(&reply, rdata, sizeof(rdata), 4);
    257                 bio_init_from_txn(&msg, txn);
    258                 res = func(bs, txn, &msg, &reply);
    259                 if (txn->flags & TF_ONE_WAY) {
    260                     binder_free_buffer(bs, txn->data.ptr.buffer);
    261                 } else {
    262                     binder_send_reply(bs, &reply, txn->data.ptr.buffer, res);
    263                 }
    264             }
    265             ptr += sizeof(*txn);
    266             break;
    267         }
    268         case BR_REPLY: {
    269             struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr;
    270             if ((end - ptr) < sizeof(*txn)) {
    271                 ALOGE("parse: reply too small!\n");
    272                 return -1;
    273             }
    274             binder_dump_txn(txn);
    275             if (bio) {
    276                 bio_init_from_txn(bio, txn);
    277                 bio = 0;
    278             } else {
    279                 /* todo FREE BUFFER */
    280             }
    281             ptr += sizeof(*txn);
    282             r = 0;
    283             break;
    284         }
    285         case BR_DEAD_BINDER: {
    286             struct binder_death *death = (struct binder_death *)(uintptr_t) *(binder_uintptr_t *)ptr;
    287             ptr += sizeof(binder_uintptr_t);
    288             death->func(bs, death->ptr);
    289             break;
    290         }
    291         case BR_FAILED_REPLY:
    292             r = -1;
    293             break;
    294         case BR_DEAD_REPLY:
    295             r = -1;
    296             break;
    297         default:
    298             ALOGE("parse: OOPS %d\n", cmd);
    299             return -1;
    300         }
    301     }
    302 
    303     return r;
    304 }
    305 
    306 void binder_acquire(struct binder_state *bs, uint32_t target)
    307 {
    308     uint32_t cmd[2];
    309     cmd[0] = BC_ACQUIRE;
    310     cmd[1] = target;
    311     binder_write(bs, cmd, sizeof(cmd));
    312 }
    313 
    314 void binder_release(struct binder_state *bs, uint32_t target)
    315 {
    316     uint32_t cmd[2];
    317     cmd[0] = BC_RELEASE;
    318     cmd[1] = target;
    319     binder_write(bs, cmd, sizeof(cmd));
    320 }
    321 
    322 void binder_link_to_death(struct binder_state *bs, uint32_t target, struct binder_death *death)
    323 {
    324     struct {
    325         uint32_t cmd;
    326         struct binder_handle_cookie payload;
    327     } __attribute__((packed)) data;
    328 
    329     data.cmd = BC_REQUEST_DEATH_NOTIFICATION;
    330     data.payload.handle = target;
    331     data.payload.cookie = (uintptr_t) death;
    332     binder_write(bs, &data, sizeof(data));
    333 }
    334 
    335 int binder_call(struct binder_state *bs,
    336                 struct binder_io *msg, struct binder_io *reply,
    337                 uint32_t target, uint32_t code)
    338 {
    339     int res;
    340     struct binder_write_read bwr;
    341     struct {
    342         uint32_t cmd;
    343         struct binder_transaction_data txn;
    344     } __attribute__((packed)) writebuf;
    345     unsigned readbuf[32];
    346 
    347     if (msg->flags & BIO_F_OVERFLOW) {
    348         fprintf(stderr,"binder: txn buffer overflow\n");
    349         goto fail;
    350     }
    351 
    352     writebuf.cmd = BC_TRANSACTION;
    353     writebuf.txn.target.handle = target;
    354     writebuf.txn.code = code;
    355     writebuf.txn.flags = 0;
    356     writebuf.txn.data_size = msg->data - msg->data0;
    357     writebuf.txn.offsets_size = ((char*) msg->offs) - ((char*) msg->offs0);
    358     writebuf.txn.data.ptr.buffer = (uintptr_t)msg->data0;
    359     writebuf.txn.data.ptr.offsets = (uintptr_t)msg->offs0;
    360 
    361     bwr.write_size = sizeof(writebuf);
    362     bwr.write_consumed = 0;
    363     bwr.write_buffer = (uintptr_t) &writebuf;
    364 
    365     hexdump(msg->data0, msg->data - msg->data0);
    366     for (;;) {
    367         bwr.read_size = sizeof(readbuf);
    368         bwr.read_consumed = 0;
    369         bwr.read_buffer = (uintptr_t) readbuf;
    370 
    371         res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
    372 
    373         if (res < 0) {
    374             fprintf(stderr,"binder: ioctl failed (%s)\n", strerror(errno));
    375             goto fail;
    376         }
    377 
    378         res = binder_parse(bs, reply, (uintptr_t) readbuf, bwr.read_consumed, 0);
    379         if (res == 0) return 0;
    380         if (res < 0) goto fail;
    381     }
    382 
    383 fail:
    384     memset(reply, 0, sizeof(*reply));
    385     reply->flags |= BIO_F_IOERROR;
    386     return -1;
    387 }
    388 
    389 void binder_loop(struct binder_state *bs, binder_handler func)
    390 {
    391     int res;
    392     struct binder_write_read bwr;
    393     uint32_t readbuf[32];
    394 
    395     bwr.write_size = 0;
    396     bwr.write_consumed = 0;
    397     bwr.write_buffer = 0;
    398 
    399     readbuf[0] = BC_ENTER_LOOPER;
    400     binder_write(bs, readbuf, sizeof(uint32_t));
    401 
    402     for (;;) {
    403         bwr.read_size = sizeof(readbuf);
    404         bwr.read_consumed = 0;
    405         bwr.read_buffer = (uintptr_t) readbuf;
    406 
    407         res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
    408 
    409         if (res < 0) {
    410             ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));
    411             break;
    412         }
    413 
    414         res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);
    415         if (res == 0) {
    416             ALOGE("binder_loop: unexpected reply?!\n");
    417             break;
    418         }
    419         if (res < 0) {
    420             ALOGE("binder_loop: io error %d %s\n", res, strerror(errno));
    421             break;
    422         }
    423     }
    424 }
    425 
    426 void bio_init_from_txn(struct binder_io *bio, struct binder_transaction_data *txn)
    427 {
    428     bio->data = bio->data0 = (char *)(intptr_t)txn->data.ptr.buffer;
    429     bio->offs = bio->offs0 = (binder_size_t *)(intptr_t)txn->data.ptr.offsets;
    430     bio->data_avail = txn->data_size;
    431     bio->offs_avail = txn->offsets_size / sizeof(size_t);
    432     bio->flags = BIO_F_SHARED;
    433 }
    434 
    435 void bio_init(struct binder_io *bio, void *data,
    436               size_t maxdata, size_t maxoffs)
    437 {
    438     size_t n = maxoffs * sizeof(size_t);
    439 
    440     if (n > maxdata) {
    441         bio->flags = BIO_F_OVERFLOW;
    442         bio->data_avail = 0;
    443         bio->offs_avail = 0;
    444         return;
    445     }
    446 
    447     bio->data = bio->data0 = (char *) data + n;
    448     bio->offs = bio->offs0 = data;
    449     bio->data_avail = maxdata - n;
    450     bio->offs_avail = maxoffs;
    451     bio->flags = 0;
    452 }
    453 
    454 static void *bio_alloc(struct binder_io *bio, size_t size)
    455 {
    456     size = (size + 3) & (~3);
    457     if (size > bio->data_avail) {
    458         bio->flags |= BIO_F_OVERFLOW;
    459         return NULL;
    460     } else {
    461         void *ptr = bio->data;
    462         bio->data += size;
    463         bio->data_avail -= size;
    464         return ptr;
    465     }
    466 }
    467 
    468 void binder_done(struct binder_state *bs,
    469                  __unused struct binder_io *msg,
    470                  struct binder_io *reply)
    471 {
    472     struct {
    473         uint32_t cmd;
    474         uintptr_t buffer;
    475     } __attribute__((packed)) data;
    476 
    477     if (reply->flags & BIO_F_SHARED) {
    478         data.cmd = BC_FREE_BUFFER;
    479         data.buffer = (uintptr_t) reply->data0;
    480         binder_write(bs, &data, sizeof(data));
    481         reply->flags = 0;
    482     }
    483 }
    484 
    485 static struct flat_binder_object *bio_alloc_obj(struct binder_io *bio)
    486 {
    487     struct flat_binder_object *obj;
    488 
    489     obj = bio_alloc(bio, sizeof(*obj));
    490 
    491     if (obj && bio->offs_avail) {
    492         bio->offs_avail--;
    493         *bio->offs++ = ((char*) obj) - ((char*) bio->data0);
    494         return obj;
    495     }
    496 
    497     bio->flags |= BIO_F_OVERFLOW;
    498     return NULL;
    499 }
    500 
    501 void bio_put_uint32(struct binder_io *bio, uint32_t n)
    502 {
    503     uint32_t *ptr = bio_alloc(bio, sizeof(n));
    504     if (ptr)
    505         *ptr = n;
    506 }
    507 
    508 void bio_put_obj(struct binder_io *bio, void *ptr)
    509 {
    510     struct flat_binder_object *obj;
    511 
    512     obj = bio_alloc_obj(bio);
    513     if (!obj)
    514         return;
    515 
    516     obj->flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
    517     obj->hdr.type = BINDER_TYPE_BINDER;
    518     obj->binder = (uintptr_t)ptr;
    519     obj->cookie = 0;
    520 }
    521 
    522 void bio_put_ref(struct binder_io *bio, uint32_t handle)
    523 {
    524     struct flat_binder_object *obj;
    525 
    526     if (handle)
    527         obj = bio_alloc_obj(bio);
    528     else
    529         obj = bio_alloc(bio, sizeof(*obj));
    530 
    531     if (!obj)
    532         return;
    533 
    534     obj->flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
    535     obj->hdr.type = BINDER_TYPE_HANDLE;
    536     obj->handle = handle;
    537     obj->cookie = 0;
    538 }
    539 
    540 void bio_put_string16(struct binder_io *bio, const uint16_t *str)
    541 {
    542     size_t len;
    543     uint16_t *ptr;
    544 
    545     if (!str) {
    546         bio_put_uint32(bio, 0xffffffff);
    547         return;
    548     }
    549 
    550     len = 0;
    551     while (str[len]) len++;
    552 
    553     if (len >= (MAX_BIO_SIZE / sizeof(uint16_t))) {
    554         bio_put_uint32(bio, 0xffffffff);
    555         return;
    556     }
    557 
    558     /* Note: The payload will carry 32bit size instead of size_t */
    559     bio_put_uint32(bio, (uint32_t) len);
    560     len = (len + 1) * sizeof(uint16_t);
    561     ptr = bio_alloc(bio, len);
    562     if (ptr)
    563         memcpy(ptr, str, len);
    564 }
    565 
    566 void bio_put_string16_x(struct binder_io *bio, const char *_str)
    567 {
    568     unsigned char *str = (unsigned char*) _str;
    569     size_t len;
    570     uint16_t *ptr;
    571 
    572     if (!str) {
    573         bio_put_uint32(bio, 0xffffffff);
    574         return;
    575     }
    576 
    577     len = strlen(_str);
    578 
    579     if (len >= (MAX_BIO_SIZE / sizeof(uint16_t))) {
    580         bio_put_uint32(bio, 0xffffffff);
    581         return;
    582     }
    583 
    584     /* Note: The payload will carry 32bit size instead of size_t */
    585     bio_put_uint32(bio, len);
    586     ptr = bio_alloc(bio, (len + 1) * sizeof(uint16_t));
    587     if (!ptr)
    588         return;
    589 
    590     while (*str)
    591         *ptr++ = *str++;
    592     *ptr++ = 0;
    593 }
    594 
    595 static void *bio_get(struct binder_io *bio, size_t size)
    596 {
    597     size = (size + 3) & (~3);
    598 
    599     if (bio->data_avail < size){
    600         bio->data_avail = 0;
    601         bio->flags |= BIO_F_OVERFLOW;
    602         return NULL;
    603     }  else {
    604         void *ptr = bio->data;
    605         bio->data += size;
    606         bio->data_avail -= size;
    607         return ptr;
    608     }
    609 }
    610 
    611 uint32_t bio_get_uint32(struct binder_io *bio)
    612 {
    613     uint32_t *ptr = bio_get(bio, sizeof(*ptr));
    614     return ptr ? *ptr : 0;
    615 }
    616 
    617 uint16_t *bio_get_string16(struct binder_io *bio, size_t *sz)
    618 {
    619     size_t len;
    620 
    621     /* Note: The payload will carry 32bit size instead of size_t */
    622     len = (size_t) bio_get_uint32(bio);
    623     if (sz)
    624         *sz = len;
    625     return bio_get(bio, (len + 1) * sizeof(uint16_t));
    626 }
    627 
    628 static struct flat_binder_object *_bio_get_obj(struct binder_io *bio)
    629 {
    630     size_t n;
    631     size_t off = bio->data - bio->data0;
    632 
    633     /* TODO: be smarter about this? */
    634     for (n = 0; n < bio->offs_avail; n++) {
    635         if (bio->offs[n] == off)
    636             return bio_get(bio, sizeof(struct flat_binder_object));
    637     }
    638 
    639     bio->data_avail = 0;
    640     bio->flags |= BIO_F_OVERFLOW;
    641     return NULL;
    642 }
    643 
    644 uint32_t bio_get_ref(struct binder_io *bio)
    645 {
    646     struct flat_binder_object *obj;
    647 
    648     obj = _bio_get_obj(bio);
    649     if (!obj)
    650         return 0;
    651 
    652     if (obj->hdr.type == BINDER_TYPE_HANDLE)
    653         return obj->handle;
    654 
    655     return 0;
    656 }
    657