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 | O_CLOEXEC);
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_free_buffer(struct binder_state * bs,binder_uintptr_t buffer_to_free)170 void binder_free_buffer(struct binder_state *bs,
171                         binder_uintptr_t buffer_to_free)
172 {
173     struct {
174         uint32_t cmd_free;
175         binder_uintptr_t buffer;
176     } __attribute__((packed)) data;
177     data.cmd_free = BC_FREE_BUFFER;
178     data.buffer = buffer_to_free;
179     binder_write(bs, &data, sizeof(data));
180 }
181 
binder_send_reply(struct binder_state * bs,struct binder_io * reply,binder_uintptr_t buffer_to_free,int status)182 void binder_send_reply(struct binder_state *bs,
183                        struct binder_io *reply,
184                        binder_uintptr_t buffer_to_free,
185                        int status)
186 {
187     struct {
188         uint32_t cmd_free;
189         binder_uintptr_t buffer;
190         uint32_t cmd_reply;
191         struct binder_transaction_data txn;
192     } __attribute__((packed)) data;
193 
194     data.cmd_free = BC_FREE_BUFFER;
195     data.buffer = buffer_to_free;
196     data.cmd_reply = BC_REPLY;
197     data.txn.target.ptr = 0;
198     data.txn.cookie = 0;
199     data.txn.code = 0;
200     if (status) {
201         data.txn.flags = TF_STATUS_CODE;
202         data.txn.data_size = sizeof(int);
203         data.txn.offsets_size = 0;
204         data.txn.data.ptr.buffer = (uintptr_t)&status;
205         data.txn.data.ptr.offsets = 0;
206     } else {
207         data.txn.flags = 0;
208         data.txn.data_size = reply->data - reply->data0;
209         data.txn.offsets_size = ((char*) reply->offs) - ((char*) reply->offs0);
210         data.txn.data.ptr.buffer = (uintptr_t)reply->data0;
211         data.txn.data.ptr.offsets = (uintptr_t)reply->offs0;
212     }
213     binder_write(bs, &data, sizeof(data));
214 }
215 
binder_parse(struct binder_state * bs,struct binder_io * bio,uintptr_t ptr,size_t size,binder_handler func)216 int binder_parse(struct binder_state *bs, struct binder_io *bio,
217                  uintptr_t ptr, size_t size, binder_handler func)
218 {
219     int r = 1;
220     uintptr_t end = ptr + (uintptr_t) size;
221 
222     while (ptr < end) {
223         uint32_t cmd = *(uint32_t *) ptr;
224         ptr += sizeof(uint32_t);
225 #if TRACE
226         fprintf(stderr,"%s:\n", cmd_name(cmd));
227 #endif
228         switch(cmd) {
229         case BR_NOOP:
230             break;
231         case BR_TRANSACTION_COMPLETE:
232             break;
233         case BR_INCREFS:
234         case BR_ACQUIRE:
235         case BR_RELEASE:
236         case BR_DECREFS:
237 #if TRACE
238             fprintf(stderr,"  %p, %p\n", (void *)ptr, (void *)(ptr + sizeof(void *)));
239 #endif
240             ptr += sizeof(struct binder_ptr_cookie);
241             break;
242         case BR_TRANSACTION: {
243             struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr;
244             if ((end - ptr) < sizeof(*txn)) {
245                 ALOGE("parse: txn too small!\n");
246                 return -1;
247             }
248             binder_dump_txn(txn);
249             if (func) {
250                 unsigned rdata[256/4];
251                 struct binder_io msg;
252                 struct binder_io reply;
253                 int res;
254 
255                 bio_init(&reply, rdata, sizeof(rdata), 4);
256                 bio_init_from_txn(&msg, txn);
257                 res = func(bs, txn, &msg, &reply);
258                 if (txn->flags & TF_ONE_WAY) {
259                     binder_free_buffer(bs, txn->data.ptr.buffer);
260                 } else {
261                     binder_send_reply(bs, &reply, txn->data.ptr.buffer, res);
262                 }
263             }
264             ptr += sizeof(*txn);
265             break;
266         }
267         case BR_REPLY: {
268             struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr;
269             if ((end - ptr) < sizeof(*txn)) {
270                 ALOGE("parse: reply too small!\n");
271                 return -1;
272             }
273             binder_dump_txn(txn);
274             if (bio) {
275                 bio_init_from_txn(bio, txn);
276                 bio = 0;
277             } else {
278                 /* todo FREE BUFFER */
279             }
280             ptr += sizeof(*txn);
281             r = 0;
282             break;
283         }
284         case BR_DEAD_BINDER: {
285             struct binder_death *death = (struct binder_death *)(uintptr_t) *(binder_uintptr_t *)ptr;
286             ptr += sizeof(binder_uintptr_t);
287             death->func(bs, death->ptr);
288             break;
289         }
290         case BR_FAILED_REPLY:
291             r = -1;
292             break;
293         case BR_DEAD_REPLY:
294             r = -1;
295             break;
296         default:
297             ALOGE("parse: OOPS %d\n", cmd);
298             return -1;
299         }
300     }
301 
302     return r;
303 }
304 
binder_acquire(struct binder_state * bs,uint32_t target)305 void binder_acquire(struct binder_state *bs, uint32_t target)
306 {
307     uint32_t cmd[2];
308     cmd[0] = BC_ACQUIRE;
309     cmd[1] = target;
310     binder_write(bs, cmd, sizeof(cmd));
311 }
312 
binder_release(struct binder_state * bs,uint32_t target)313 void binder_release(struct binder_state *bs, uint32_t target)
314 {
315     uint32_t cmd[2];
316     cmd[0] = BC_RELEASE;
317     cmd[1] = target;
318     binder_write(bs, cmd, sizeof(cmd));
319 }
320 
binder_link_to_death(struct binder_state * bs,uint32_t target,struct binder_death * death)321 void binder_link_to_death(struct binder_state *bs, uint32_t target, struct binder_death *death)
322 {
323     struct {
324         uint32_t cmd;
325         struct binder_handle_cookie payload;
326     } __attribute__((packed)) data;
327 
328     data.cmd = BC_REQUEST_DEATH_NOTIFICATION;
329     data.payload.handle = target;
330     data.payload.cookie = (uintptr_t) death;
331     binder_write(bs, &data, sizeof(data));
332 }
333 
binder_call(struct binder_state * bs,struct binder_io * msg,struct binder_io * reply,uint32_t target,uint32_t code)334 int binder_call(struct binder_state *bs,
335                 struct binder_io *msg, struct binder_io *reply,
336                 uint32_t target, uint32_t code)
337 {
338     int res;
339     struct binder_write_read bwr;
340     struct {
341         uint32_t cmd;
342         struct binder_transaction_data txn;
343     } __attribute__((packed)) writebuf;
344     unsigned readbuf[32];
345 
346     if (msg->flags & BIO_F_OVERFLOW) {
347         fprintf(stderr,"binder: txn buffer overflow\n");
348         goto fail;
349     }
350 
351     writebuf.cmd = BC_TRANSACTION;
352     writebuf.txn.target.handle = target;
353     writebuf.txn.code = code;
354     writebuf.txn.flags = 0;
355     writebuf.txn.data_size = msg->data - msg->data0;
356     writebuf.txn.offsets_size = ((char*) msg->offs) - ((char*) msg->offs0);
357     writebuf.txn.data.ptr.buffer = (uintptr_t)msg->data0;
358     writebuf.txn.data.ptr.offsets = (uintptr_t)msg->offs0;
359 
360     bwr.write_size = sizeof(writebuf);
361     bwr.write_consumed = 0;
362     bwr.write_buffer = (uintptr_t) &writebuf;
363 
364     hexdump(msg->data0, msg->data - msg->data0);
365     for (;;) {
366         bwr.read_size = sizeof(readbuf);
367         bwr.read_consumed = 0;
368         bwr.read_buffer = (uintptr_t) readbuf;
369 
370         res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
371 
372         if (res < 0) {
373             fprintf(stderr,"binder: ioctl failed (%s)\n", strerror(errno));
374             goto fail;
375         }
376 
377         res = binder_parse(bs, reply, (uintptr_t) readbuf, bwr.read_consumed, 0);
378         if (res == 0) return 0;
379         if (res < 0) goto fail;
380     }
381 
382 fail:
383     memset(reply, 0, sizeof(*reply));
384     reply->flags |= BIO_F_IOERROR;
385     return -1;
386 }
387 
binder_loop(struct binder_state * bs,binder_handler func)388 void binder_loop(struct binder_state *bs, binder_handler func)
389 {
390     int res;
391     struct binder_write_read bwr;
392     uint32_t readbuf[32];
393 
394     bwr.write_size = 0;
395     bwr.write_consumed = 0;
396     bwr.write_buffer = 0;
397 
398     readbuf[0] = BC_ENTER_LOOPER;
399     binder_write(bs, readbuf, sizeof(uint32_t));
400 
401     for (;;) {
402         bwr.read_size = sizeof(readbuf);
403         bwr.read_consumed = 0;
404         bwr.read_buffer = (uintptr_t) readbuf;
405 
406         res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
407 
408         if (res < 0) {
409             ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));
410             break;
411         }
412 
413         res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);
414         if (res == 0) {
415             ALOGE("binder_loop: unexpected reply?!\n");
416             break;
417         }
418         if (res < 0) {
419             ALOGE("binder_loop: io error %d %s\n", res, strerror(errno));
420             break;
421         }
422     }
423 }
424 
bio_init_from_txn(struct binder_io * bio,struct binder_transaction_data * txn)425 void bio_init_from_txn(struct binder_io *bio, struct binder_transaction_data *txn)
426 {
427     bio->data = bio->data0 = (char *)(intptr_t)txn->data.ptr.buffer;
428     bio->offs = bio->offs0 = (binder_size_t *)(intptr_t)txn->data.ptr.offsets;
429     bio->data_avail = txn->data_size;
430     bio->offs_avail = txn->offsets_size / sizeof(size_t);
431     bio->flags = BIO_F_SHARED;
432 }
433 
bio_init(struct binder_io * bio,void * data,size_t maxdata,size_t maxoffs)434 void bio_init(struct binder_io *bio, void *data,
435               size_t maxdata, size_t maxoffs)
436 {
437     size_t n = maxoffs * sizeof(size_t);
438 
439     if (n > maxdata) {
440         bio->flags = BIO_F_OVERFLOW;
441         bio->data_avail = 0;
442         bio->offs_avail = 0;
443         return;
444     }
445 
446     bio->data = bio->data0 = (char *) data + n;
447     bio->offs = bio->offs0 = data;
448     bio->data_avail = maxdata - n;
449     bio->offs_avail = maxoffs;
450     bio->flags = 0;
451 }
452 
bio_alloc(struct binder_io * bio,size_t size)453 static void *bio_alloc(struct binder_io *bio, size_t size)
454 {
455     size = (size + 3) & (~3);
456     if (size > bio->data_avail) {
457         bio->flags |= BIO_F_OVERFLOW;
458         return NULL;
459     } else {
460         void *ptr = bio->data;
461         bio->data += size;
462         bio->data_avail -= size;
463         return ptr;
464     }
465 }
466 
binder_done(struct binder_state * bs,__unused struct binder_io * msg,struct binder_io * reply)467 void binder_done(struct binder_state *bs,
468                  __unused struct binder_io *msg,
469                  struct binder_io *reply)
470 {
471     struct {
472         uint32_t cmd;
473         uintptr_t buffer;
474     } __attribute__((packed)) data;
475 
476     if (reply->flags & BIO_F_SHARED) {
477         data.cmd = BC_FREE_BUFFER;
478         data.buffer = (uintptr_t) reply->data0;
479         binder_write(bs, &data, sizeof(data));
480         reply->flags = 0;
481     }
482 }
483 
bio_alloc_obj(struct binder_io * bio)484 static struct flat_binder_object *bio_alloc_obj(struct binder_io *bio)
485 {
486     struct flat_binder_object *obj;
487 
488     obj = bio_alloc(bio, sizeof(*obj));
489 
490     if (obj && bio->offs_avail) {
491         bio->offs_avail--;
492         *bio->offs++ = ((char*) obj) - ((char*) bio->data0);
493         return obj;
494     }
495 
496     bio->flags |= BIO_F_OVERFLOW;
497     return NULL;
498 }
499 
bio_put_uint32(struct binder_io * bio,uint32_t n)500 void bio_put_uint32(struct binder_io *bio, uint32_t n)
501 {
502     uint32_t *ptr = bio_alloc(bio, sizeof(n));
503     if (ptr)
504         *ptr = n;
505 }
506 
bio_put_obj(struct binder_io * bio,void * ptr)507 void bio_put_obj(struct binder_io *bio, void *ptr)
508 {
509     struct flat_binder_object *obj;
510 
511     obj = bio_alloc_obj(bio);
512     if (!obj)
513         return;
514 
515     obj->flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
516     obj->type = BINDER_TYPE_BINDER;
517     obj->binder = (uintptr_t)ptr;
518     obj->cookie = 0;
519 }
520 
bio_put_ref(struct binder_io * bio,uint32_t handle)521 void bio_put_ref(struct binder_io *bio, uint32_t handle)
522 {
523     struct flat_binder_object *obj;
524 
525     if (handle)
526         obj = bio_alloc_obj(bio);
527     else
528         obj = bio_alloc(bio, sizeof(*obj));
529 
530     if (!obj)
531         return;
532 
533     obj->flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
534     obj->type = BINDER_TYPE_HANDLE;
535     obj->handle = handle;
536     obj->cookie = 0;
537 }
538 
bio_put_string16(struct binder_io * bio,const uint16_t * str)539 void bio_put_string16(struct binder_io *bio, const uint16_t *str)
540 {
541     size_t len;
542     uint16_t *ptr;
543 
544     if (!str) {
545         bio_put_uint32(bio, 0xffffffff);
546         return;
547     }
548 
549     len = 0;
550     while (str[len]) len++;
551 
552     if (len >= (MAX_BIO_SIZE / sizeof(uint16_t))) {
553         bio_put_uint32(bio, 0xffffffff);
554         return;
555     }
556 
557     /* Note: The payload will carry 32bit size instead of size_t */
558     bio_put_uint32(bio, (uint32_t) len);
559     len = (len + 1) * sizeof(uint16_t);
560     ptr = bio_alloc(bio, len);
561     if (ptr)
562         memcpy(ptr, str, len);
563 }
564 
bio_put_string16_x(struct binder_io * bio,const char * _str)565 void bio_put_string16_x(struct binder_io *bio, const char *_str)
566 {
567     unsigned char *str = (unsigned char*) _str;
568     size_t len;
569     uint16_t *ptr;
570 
571     if (!str) {
572         bio_put_uint32(bio, 0xffffffff);
573         return;
574     }
575 
576     len = strlen(_str);
577 
578     if (len >= (MAX_BIO_SIZE / sizeof(uint16_t))) {
579         bio_put_uint32(bio, 0xffffffff);
580         return;
581     }
582 
583     /* Note: The payload will carry 32bit size instead of size_t */
584     bio_put_uint32(bio, len);
585     ptr = bio_alloc(bio, (len + 1) * sizeof(uint16_t));
586     if (!ptr)
587         return;
588 
589     while (*str)
590         *ptr++ = *str++;
591     *ptr++ = 0;
592 }
593 
bio_get(struct binder_io * bio,size_t size)594 static void *bio_get(struct binder_io *bio, size_t size)
595 {
596     size = (size + 3) & (~3);
597 
598     if (bio->data_avail < size){
599         bio->data_avail = 0;
600         bio->flags |= BIO_F_OVERFLOW;
601         return NULL;
602     }  else {
603         void *ptr = bio->data;
604         bio->data += size;
605         bio->data_avail -= size;
606         return ptr;
607     }
608 }
609 
bio_get_uint32(struct binder_io * bio)610 uint32_t bio_get_uint32(struct binder_io *bio)
611 {
612     uint32_t *ptr = bio_get(bio, sizeof(*ptr));
613     return ptr ? *ptr : 0;
614 }
615 
bio_get_string16(struct binder_io * bio,size_t * sz)616 uint16_t *bio_get_string16(struct binder_io *bio, size_t *sz)
617 {
618     size_t len;
619 
620     /* Note: The payload will carry 32bit size instead of size_t */
621     len = (size_t) bio_get_uint32(bio);
622     if (sz)
623         *sz = len;
624     return bio_get(bio, (len + 1) * sizeof(uint16_t));
625 }
626 
_bio_get_obj(struct binder_io * bio)627 static struct flat_binder_object *_bio_get_obj(struct binder_io *bio)
628 {
629     size_t n;
630     size_t off = bio->data - bio->data0;
631 
632     /* TODO: be smarter about this? */
633     for (n = 0; n < bio->offs_avail; n++) {
634         if (bio->offs[n] == off)
635             return bio_get(bio, sizeof(struct flat_binder_object));
636     }
637 
638     bio->data_avail = 0;
639     bio->flags |= BIO_F_OVERFLOW;
640     return NULL;
641 }
642 
bio_get_ref(struct binder_io * bio)643 uint32_t bio_get_ref(struct binder_io *bio)
644 {
645     struct flat_binder_object *obj;
646 
647     obj = _bio_get_obj(bio);
648     if (!obj)
649         return 0;
650 
651     if (obj->type == BINDER_TYPE_HANDLE)
652         return obj->handle;
653 
654     return 0;
655 }
656