1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
|
# 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 <linux/android/binder.h>
include <linux/fcntl.h>
resource fd_binder[fd]
resource binder_ptr[int64]: 0
type binder_handle int32[0:4]
type binder_cookie int64[0:4]
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 flags[mmap_prot], flags flags[mmap_flags], 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])
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_ptr
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_sg
} [packed]
binder_cmd_reply_sg {
cmd const[BC_REPLY_SG, int32]
data binder_transaction_data_sg
} [packed]
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, array[binder_object, 0:3]]
offsets ptr64[in, array[flags[binder_buffer_offsets, int64]]]
}
binder_transaction_data_sg {
trx binder_transaction_data
# NEED: buffers_size should be multiple of 8.
buffers_size int64
} [packed]
# These are sizes of flat_binder_object, binder_fd_object, binder_fd_array_object and
# binder_buffer_object, and also sums of all pairs of these sizes.
# This allows guessing offsets for up to 3 objects.
binder_buffer_offsets = 0, 24, 32, 40, 48, 56, 64, 72
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_ptr]
weak_binder flat_binder_object_t[BINDER_TYPE_WEAK_BINDER, binder_ptr]
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:4]
parent_offset int64[0:64]
}
binder_buffer_object {
type const[BINDER_TYPE_PTR, int32]
flags bool32
buffer ptr64[in, array[int8]]
length bytesize[buffer, int64]
parnt int64[0:4]
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 int32[0:4]
} [packed]
binder_cmd_acquire {
cmd const[BC_ACQUIRE, int32]
ref int32[0:4]
} [packed]
binder_cmd_release {
cmd const[BC_RELEASE, int32]
ref int32[0:4]
} [packed]
binder_cmd_decrefs {
cmd const[BC_DECREFS, int32]
ref int32[0:4]
} [packed]
binder_cmd_increfs_done {
cmd const[BC_INCREFS_DONE, int32]
ptr binder_ptr
cookie binder_cookie
} [packed]
binder_cmd_acquire_done {
cmd const[BC_ACQUIRE_DONE, int32]
ptr binder_ptr
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]
|