This patch introduce decoding for binder ioctls including the command and return protocol from BINDER_WRITE_READ.
* binder.c: New file. * xlat/binder_driver_commands.in: New file. * xlat/binder_driver_returns.in: New file. * Makefile.am (strace_SOURCES): Add binder.c. * ioctl.c (ioctl_decode): Call binder_ioctl for 'b' ioctl commands. * defs.h (binder_ioctl): New prototype. * configure.ac: Check binder header. Signed-off-by: Antoine Damhet <antoine.dam...@lse.epita.fr> Reviewed-by: Gabriel Laskar <gabr...@lse.epita.fr> --- Makefile.am | 1 + binder.c | 171 +++++++++++++++++++++++++++++++++++++++++ configure.ac | 39 ++++++++++ defs.h | 1 + ioctl.c | 4 + xlat/binder_driver_commands.in | 17 ++++ xlat/binder_driver_returns.in | 18 +++++ 7 files changed, 251 insertions(+) create mode 100644 binder.c create mode 100644 xlat/binder_driver_commands.in create mode 100644 xlat/binder_driver_returns.in diff --git a/Makefile.am b/Makefile.am index 77e0cc8..fb75e6d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -78,6 +78,7 @@ strace_SOURCES = \ affinity.c \ aio.c \ alpha.c \ + binder.c \ bjm.c \ block.c \ bpf.c \ diff --git a/binder.c b/binder.c new file mode 100644 index 0000000..a614c82 --- /dev/null +++ b/binder.c @@ -0,0 +1,171 @@ +#include "defs.h" + +#if defined(HAVE_LINUX_ANDROID_BINDER_H) || defined(__ANDROID__) + +#include <linux/ioctl.h> + +/* + * The driver can support either 32 or 64 bit but not both at the same time. + */ +#if SIZEOF_LONG == 4 +# define BINDER_IPC_32BIT +#endif +#ifdef HAVE_LINUX_ANDROID_BINDER_H +# include <linux/android/binder.h> +#else +# include <linux/binder.h> +#endif + +#include "xlat/binder_driver_commands.h" +#include "xlat/binder_driver_returns.h" + +static int +decode_binder_commands_buffer(struct tcb *tcp, uintptr_t buffer, size_t pos, + size_t size, const struct xlat *x, const char *str) +{ + if (size < sizeof(uint32_t)) { + printaddr(buffer); + return 0; + } + + if (abbrev(tcp)) { + tprints("[...]"); + return 0; + } + + uint32_t type; + int first_time = 1; + tprints("["); + + while (pos + sizeof(uint32_t) <= size) { + if (umove(tcp, buffer + pos, &type)) { + tprints("]"); + return 1; + } + + if (!first_time) + tprints(", "); + else + first_time = 0; + + if (_IOC_SIZE(type) > 0 + && pos + sizeof(type) + _IOC_SIZE(type) <= size) { + tprints("{"); + printxval(x, type, str); + tprints(", "); + printstr(tcp, buffer + pos + sizeof(type), + _IOC_SIZE(type)); + tprints("}"); + } else + printxval(x, type, str); + + if (SIZE_MAX - sizeof(uint32_t) + _IOC_SIZE(type) >= pos) + pos += sizeof(uint32_t) + _IOC_SIZE(type); + else + break; + } + + tprints("]"); + return 0; +} + +static int +decode_binder_write_read(struct tcb *tcp, const long addr) +{ + struct binder_write_read wr; + + if (entering(tcp)) { + tprints(", "); + if (umove_or_printaddr(tcp, addr, &wr)) + return RVAL_DECODED | 1; + + tprintf("{write_size=%" PRIu64 ", write_consumed=%" PRIu64 + ", write_buffer=", + (uint64_t)wr.write_size, + (uint64_t)wr.write_consumed); + if (decode_binder_commands_buffer(tcp, wr.write_buffer, + wr.write_consumed, wr.write_size, + binder_driver_commands, "BC_???")) { + tprints("}"); + return RVAL_DECODED | 1; + } + + tprintf(", read_size=%" PRIu64 ", read_consumed=%" PRIu64 "}", + (uint64_t)wr.read_size, + (uint64_t)wr.read_consumed); + return 0; + } + + if (syserror(tcp) || umove(tcp, addr, &wr)) + return RVAL_DECODED | 1; + + tprints(" => "); + + tprintf("{write_size=%" PRIu64 ", write_consumed=%" PRIu64 + ", read_size=%" PRIu64 ", read_consumed=%" PRIu64 + ", read_buffer=", + (uint64_t)wr.write_size, + (uint64_t)wr.write_consumed, + (uint64_t)wr.read_size, + (uint64_t)wr.read_consumed); + if (decode_binder_commands_buffer(tcp, wr.read_buffer, 0, + wr.read_consumed, + binder_driver_returns, "BR_???")) { + tprints("}"); + return RVAL_DECODED | 1; + } + + tprints("}"); + return RVAL_DECODED | 1; +} + +int +decode_binder_version(struct tcb *tcp, long addr) +{ + struct binder_version version; + + tprints(", "); + if (umove_or_printaddr(tcp, addr, &version)) + return RVAL_DECODED | 1; + + tprintf("{protocol_version=%" PRId32 "}", version.protocol_version); + return RVAL_DECODED | 1; +} + +int +binder_ioctl(struct tcb *tcp, const unsigned int code, long arg) +{ + if (!verbose(tcp)) + return RVAL_DECODED; + + if (code == BINDER_WRITE_READ) + return decode_binder_write_read(tcp, arg); + + if (entering(tcp)) { + switch (code) { + case BINDER_SET_IDLE_TIMEOUT: + tprints(", "); + printnum_int64(tcp, arg, "%lld"); + return RVAL_DECODED | 1; + case BINDER_SET_MAX_THREADS: + tprints(", "); + printnum_int(tcp, arg, "%u"); + return RVAL_DECODED | 1; + case BINDER_SET_IDLE_PRIORITY: + case BINDER_SET_CONTEXT_MGR: + case BINDER_THREAD_EXIT: + tprints(", "); + printnum_int(tcp, arg, "%d"); + return RVAL_DECODED | 1; + default: + break; + } + } else { + if (code == BINDER_VERSION) + return decode_binder_version(tcp, arg); + } + + return 0; +} + +#endif /* !(HAVE_LINUX_ANDROID_BINDER_H || __ANDROID__) */ diff --git a/configure.ac b/configure.ac index 9afda73..0d77998 100644 --- a/configure.ac +++ b/configure.ac @@ -434,6 +434,45 @@ AC_CHECK_HEADERS([linux/bpf.h], [ fi ]) +AC_CHECK_HEADERS([linux/android/binder.h], [[ #include <sys/types.h> +#include <linux/android/binder.h>]) + AC_CHECK_DECLS(m4_normalize([BC_TRANSACTION, + BC_REPLY, + BC_ACQUIRE_RESULT, + BC_FREE_BUFFER, + BC_INCREFS, + BC_ACQUIRE, + BC_RELEASE, + BC_DECREFS, + BC_INCREFS_DONE, + BC_ACQUIRE_DONE, + BC_ATTEMPT_ACQUIRE, + BC_REGISTER_LOOPER, + BC_ENTER_LOOPER, + BC_EXIT_LOOPER, + BC_REQUEST_DEATH_NOTIFICATION, + BC_CLEAR_DEATH_NOTIFICATION, + BC_DEAD_BINDER_DONE, + BR_ERROR, + BR_OK, + BR_TRANSACTION, + BR_REPLY, + BR_ACQUIRE_RESULT, + BR_DEAD_REPLY, + BR_TRANSACTION_COMPLETE, + BR_INCREFS, + BR_ACQUIRE, + BR_RELEASE, + BR_DECREFS, + BR_ATTEMPT_ACQUIRE, + BR_NOOP, + BR_SPAWN_LOOPER, + BR_FINISHED, + BR_DEAD_BINDER, + BR_CLEAR_DEATH_NOTIFICATION_DONE, + BR_FAILED_REPLY]),,,[ #include <sys/types.h> +#include <linux/android/binder.h>])]) + AC_CHECK_TYPES([struct statfs], [ AC_CHECK_MEMBERS([struct statfs.f_frsize],,, [#include <linux/types.h> #include <asm/statfs.h>]) diff --git a/defs.h b/defs.h index 99447e6..367a6e9 100644 --- a/defs.h +++ b/defs.h @@ -682,6 +682,7 @@ struct strace_statfs; extern void print_struct_statfs(struct tcb *tcp, long); extern void print_struct_statfs64(struct tcb *tcp, long, unsigned long); +extern int binder_ioctl(struct tcb *, const unsigned int, long); extern int file_ioctl(struct tcb *, const unsigned int, long); extern int fs_x_ioctl(struct tcb *, const unsigned int, long); extern int loop_ioctl(struct tcb *, const unsigned int, long); diff --git a/ioctl.c b/ioctl.c index e4b20d9..54aa9a7 100644 --- a/ioctl.c +++ b/ioctl.c @@ -282,6 +282,10 @@ ioctl_decode(struct tcb *tcp) case 0x94: return btrfs_ioctl(tcp, code, arg); #endif +#if defined(HAVE_LINUX_ANDROID_BINDER_H) || defined(__ANDROID__) + case 'b': + return binder_ioctl(tcp, code, arg); +#endif default: break; } diff --git a/xlat/binder_driver_commands.in b/xlat/binder_driver_commands.in new file mode 100644 index 0000000..84d481c --- /dev/null +++ b/xlat/binder_driver_commands.in @@ -0,0 +1,17 @@ +BC_TRANSACTION +BC_REPLY +BC_ACQUIRE_RESULT +BC_FREE_BUFFER +BC_INCREFS +BC_ACQUIRE +BC_RELEASE +BC_DECREFS +BC_INCREFS_DONE +BC_ACQUIRE_DONE +BC_ATTEMPT_ACQUIRE +BC_REGISTER_LOOPER +BC_ENTER_LOOPER +BC_EXIT_LOOPER +BC_REQUEST_DEATH_NOTIFICATION +BC_CLEAR_DEATH_NOTIFICATION +BC_DEAD_BINDER_DONE diff --git a/xlat/binder_driver_returns.in b/xlat/binder_driver_returns.in new file mode 100644 index 0000000..dc4c4c1 --- /dev/null +++ b/xlat/binder_driver_returns.in @@ -0,0 +1,18 @@ +BR_ERROR +BR_OK +BR_TRANSACTION +BR_REPLY +BR_ACQUIRE_RESULT +BR_DEAD_REPLY +BR_TRANSACTION_COMPLETE +BR_INCREFS +BR_ACQUIRE +BR_RELEASE +BR_DECREFS +BR_ATTEMPT_ACQUIRE +BR_NOOP +BR_SPAWN_LOOPER +BR_FINISHED +BR_DEAD_BINDER +BR_CLEAR_DEATH_NOTIFICATION_DONE +BR_FAILED_REPLY -- 2.8.3 ------------------------------------------------------------------------------ Attend Shape: An AT&T Tech Expo July 15-16. Meet us at AT&T Park in San Francisco, CA to explore cutting-edge tech and listen to tech luminaries present their vision of the future. This family event has something for everyone, including kids. Get more information and register today. http://sdm.link/attshape _______________________________________________ Strace-devel mailing list Strace-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/strace-devel