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