blob: f9fb3d7f5949012d63d591682f2dd0392e01fd2d [file] [log] [blame]
# 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".
# "binder,hwbinder,vndbinder" is also supported; this is the kconfig default and
# it's what's used on real Android devices (the main user of binder).
# Description assumes CONFIG_ANDROID_BINDER_IPC_32BIT is not set.
include <linux/android/binder.h>
include <linux/fcntl.h>
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$binderN(dev ptr[in, string["/dev/binder#"]], id proc[0, 1], flags flags[binder_open_flags]) fd_binder
syz_open_dev$binder(dev ptr[in, string["/dev/binder"]], id intptr, flags flags[binder_open_flags]) fd_binder
syz_open_dev$hwbinder(dev ptr[in, string["/dev/hwbinder"]], id intptr, flags flags[binder_open_flags]) fd_binder
syz_open_dev$vndbinder(dev ptr[in, string["/dev/vndbinder"]], id intptr, 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]