# Copyright 2017 syzkaller project authors. All rights reserved. # Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. # Description uses binder device per test process, they are expected to be configured with # CONFIG_ANDROID_BINDER_DEVICES="binder0,...,binder31". # Description assumes CONFIG_ANDROID_BINDER_IPC_32BIT is not set. include include resource fd_binder[fd] resource binder_ptr[int64]: 0 # What's the difference between these node and handle? Do they mean the same? type binder_node int64[0:3] type binder_handle int32[0:3] # It seems that cookies are only checked for inequality and non-matching cookies only cover error paths. type binder_cookie const[0, int64] syz_open_dev$binder(dev ptr[in, string["/dev/binder#"]], id proc[0, 1], flags flags[binder_open_flags]) fd_binder mmap$binder(addr vma, len len[addr], prot const[PROT_READ], flags const[MAP_SHARED], fd fd_binder, offset fileoff) binder_ptr ioctl$BINDER_SET_MAX_THREADS(fd fd_binder, cmd const[BINDER_SET_MAX_THREADS], arg ptr[in, int32]) ioctl$BINDER_SET_CONTEXT_MGR(fd fd_binder, cmd const[BINDER_SET_CONTEXT_MGR], arg const[0]) ioctl$BINDER_SET_CONTEXT_MGR_EXT(fd fd_binder, cmd const[BINDER_SET_CONTEXT_MGR_EXT], arg ptr[in, flat_binder_object_t[BINDER_TYPE_BINDER, binder_node]]) ioctl$BINDER_THREAD_EXIT(fd fd_binder, cmd const[BINDER_THREAD_EXIT], arg const[0]) ioctl$BINDER_GET_NODE_DEBUG_INFO(fd fd_binder, cmd const[BINDER_GET_NODE_DEBUG_INFO], arg ptr[inout, binder_node_debug_info]) ioctl$BINDER_WRITE_READ(fd fd_binder, cmd const[BINDER_WRITE_READ], arg ptr[in, binder_write_read]) ioctl$BINDER_GET_NODE_INFO_FOR_REF(fd fd_binder, cmd const[BINDER_GET_NODE_INFO_FOR_REF], arg ptr[in, binder_node_info_for_ref]) binder_open_flags = O_RDWR, O_NONBLOCK _ = __NR_mmap2 binder_node_debug_info { ptr binder_node cookie const[0, int64] has_strong_ref const[0, int32] has_weak_ref const[0, int32] } binder_node_info_for_ref { handle binder_handle strong_count const[0, int32] weak_count const[0, int32] reserved1 const[0, int32] reserved2 const[0, int32] reserved3 const[0, int32] } binder_write_read { write_size bytesize[write_buffer, int64] write_consumed const[0, int64] write_buffer ptr64[in, array[binder_write_cmd]] read_size bytesize[read_buffer, int64] read_consumed const[0, int64] read_buffer ptr64[in, array[int8]] } binder_write_cmd [ transaction binder_cmd_transaction reply binder_cmd_reply transaction_sg binder_cmd_transaction_sg reply_sg binder_cmd_reply_sg free_buffer binder_cmd_free_buffer increfs binder_cmd_increfs acquire binder_cmd_acquire release binder_cmd_release decrefs binder_cmd_decrefs increfs_done binder_cmd_increfs_done acquire_done binder_cmd_acquire_done register_looper binder_cmd_register_looper enter_looper binder_cmd_enter_looper exit_looper binder_cmd_exit_looper request_death binder_cmd_request_death clear_death binder_cmd_clear_death dead_binder_done binder_cmd_dead_binder_done ] [varlen] binder_cmd_transaction { cmd const[BC_TRANSACTION, int32] data binder_transaction_data } [packed] binder_cmd_reply { cmd const[BC_REPLY, int32] data binder_transaction_data } [packed] binder_cmd_transaction_sg { cmd const[BC_TRANSACTION_SG, int32] data binder_transaction_data buffers_size flags[binder_sg_size, int64] } [packed] binder_cmd_reply_sg { cmd const[BC_REPLY_SG, int32] data binder_transaction_data buffers_size flags[binder_sg_size, int64] } [packed] # NEED: buffers_size should be multiple of 8 and must be no less than size of all BINDER_TYPE_PTR buffers. binder_sg_size = 0, 64, 1024, 4096 binder_transaction_data { handle binder_handle # there is a union of handle with binder_uintptr_t pad const[0, int32] cookie binder_cookie code const[0, int32] flags flags[binder_transaction_flags, int32] sender_pid const[0, int32] sender_euid const[0, int32] data_size bytesize[buffer, int64] offsets_size bytesize[offsets, int64] buffer ptr64[in, binder_objects] offsets ptr64[in, binder_offsets] } binder_objects { obj0 binder_object obj1 binder_object obj2 binder_object } [packed, align_8] binder_offsets { off0 offsetof[binder_transaction_data:buffer:obj0, int64] off1 offsetof[binder_transaction_data:buffer:obj1, int64] off2 offsetof[binder_transaction_data:buffer:obj2, int64] } binder_transaction_flags = TF_ONE_WAY, TF_ACCEPT_FDS binder_object [ flat flat_binder_object fd binder_fd_object fda binder_fd_array_object ptr binder_buffer_object ] [varlen] flat_binder_object [ binder flat_binder_object_t[BINDER_TYPE_BINDER, binder_node] weak_binder flat_binder_object_t[BINDER_TYPE_WEAK_BINDER, binder_node] handle flat_binder_object_t[BINDER_TYPE_HANDLE, binder_handle] weak_handle flat_binder_object_t[BINDER_TYPE_WEAK_HANDLE, binder_handle] ] type flat_binder_object_t[TYP, DATA] { type const[TYP, int32] flags flags[binder_flat_flags, int32] binder DATA cookie binder_cookie } binder_flat_flags = 1, 10, FLAT_BINDER_FLAG_ACCEPTS_FDS, FLAT_BINDER_FLAG_TXN_SECURITY_CTX binder_fd_object { type const[BINDER_TYPE_FD, int32] pad const[0, int32] fd fd pad2 const[0, int32] cookie binder_cookie } binder_fd_array_object { type const[BINDER_TYPE_FDA, int32] num_fds int64[0:10] parnt int64[0:2] parent_offset int64[0:64] } binder_buffer_object { type const[BINDER_TYPE_PTR, int32] # This is BINDER_BUFFER_FLAG_HAS_PARENT. flags bool32 # The buffer is actually input, but the data is opaque. buffer ptr64[out, array[int8]] length bytesize[buffer, int64] # If flags == BINDER_BUFFER_FLAG_HAS_PARENT, this must point to another BINDER_TYPE_PTR object. parnt int64[0:2] parent_offset int64[0:64] } binder_cmd_free_buffer { cmd const[BC_FREE_BUFFER, int32] ptr binder_ptr } [packed] binder_cmd_increfs { cmd const[BC_INCREFS, int32] ref binder_handle } [packed] binder_cmd_acquire { cmd const[BC_ACQUIRE, int32] ref binder_handle } [packed] binder_cmd_release { cmd const[BC_RELEASE, int32] ref binder_handle } [packed] binder_cmd_decrefs { cmd const[BC_DECREFS, int32] ref binder_handle } [packed] binder_cmd_increfs_done { cmd const[BC_INCREFS_DONE, int32] ptr binder_node cookie binder_cookie } [packed] binder_cmd_acquire_done { cmd const[BC_ACQUIRE_DONE, int32] ptr binder_node cookie binder_cookie } [packed] binder_cmd_register_looper { cmd const[BC_REGISTER_LOOPER, int32] } [packed] binder_cmd_enter_looper { cmd const[BC_ENTER_LOOPER, int32] } [packed] binder_cmd_exit_looper { cmd const[BC_EXIT_LOOPER, int32] } [packed] binder_cmd_request_death { cmd const[BC_REQUEST_DEATH_NOTIFICATION, int32] handle binder_handle cookie binder_cookie } [packed] binder_cmd_clear_death { cmd const[BC_CLEAR_DEATH_NOTIFICATION, int32] handle binder_handle cookie binder_cookie } [packed] binder_cmd_dead_binder_done { cmd const[BC_DEAD_BINDER_DONE, int32] cookie binder_cookie } [packed]