1 /*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <errno.h>
18 #include <fcntl.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21
22 #include <gtest/gtest.h>
23 #include <linux/binder.h>
24 #include <binder/IBinder.h>
25 #include <sys/mman.h>
26 #include <poll.h>
27
28 #define BINDER_DEV_NAME "/dev/binder"
29
30 testing::Environment* binder_env;
31
32 class BinderDriverInterfaceTestEnv : public ::testing::Environment {
SetUp()33 virtual void SetUp() {
34 int ret;
35 uint32_t max_threads = 0;
36
37 m_binderFd = open(BINDER_DEV_NAME, O_RDWR | O_NONBLOCK);
38 ASSERT_GE(m_binderFd, 0);
39 m_buffer = mmap(NULL, 64*1024, PROT_READ, MAP_SHARED, m_binderFd, 0);
40 ASSERT_NE(m_buffer, (void *)NULL);
41 ret = ioctl(m_binderFd, BINDER_SET_MAX_THREADS, &max_threads);
42 EXPECT_EQ(0, ret);
43 EnterLooper();
44 }
TearDown()45 virtual void TearDown() {
46 close(m_binderFd);
47 }
48 private:
49 int m_binderFd;
50 void *m_buffer;
51 public:
getBinderFd(void)52 int getBinderFd(void) {
53 return m_binderFd;
54 }
EnterLooper(void)55 void EnterLooper(void) {
56 int ret;
57 const uint32_t bc[] = {
58 BC_ENTER_LOOPER,
59 };
60 struct binder_write_read bwr = binder_write_read();
61 bwr.write_buffer = (uintptr_t)bc;
62 bwr.write_size = sizeof(bc);
63 ret = ioctl(m_binderFd, BINDER_WRITE_READ, &bwr);
64 EXPECT_EQ(0, ret);
65 if (ret < 0) {
66 EXPECT_EQ(0, errno);
67 }
68 EXPECT_EQ(sizeof(bc), bwr.write_consumed);
69 }
70 };
71
72 class BinderDriverInterfaceTest : public ::testing::Test {
73 public:
SetUp()74 virtual void SetUp() {
75 m_binderFd = static_cast<BinderDriverInterfaceTestEnv *>(binder_env)->getBinderFd();
76 }
TearDown()77 virtual void TearDown() {
78 }
79 protected:
binderTestIoctlRetErr2(int cmd,void * arg,int expect_ret,int expect_errno,int accept_errno)80 void binderTestIoctlRetErr2(int cmd, void *arg, int expect_ret, int expect_errno, int accept_errno) {
81 int ret;
82
83 ret = ioctl(m_binderFd, cmd, arg);
84 EXPECT_EQ(expect_ret, ret);
85 if (ret < 0) {
86 if (errno != accept_errno)
87 EXPECT_EQ(expect_errno, errno);
88 }
89 }
binderTestIoctlErr2(int cmd,void * arg,int expect_errno,int accept_errno)90 void binderTestIoctlErr2(int cmd, void *arg, int expect_errno, int accept_errno) {
91 binderTestIoctlRetErr2(cmd, arg, -1, expect_errno, accept_errno);
92 }
binderTestIoctlErr1(int cmd,void * arg,int expect_errno)93 void binderTestIoctlErr1(int cmd, void *arg, int expect_errno) {
94 binderTestIoctlErr2(cmd, arg, expect_errno, expect_errno);
95 }
binderTestIoctl(int cmd,void * arg)96 void binderTestIoctl(int cmd, void *arg) {
97 binderTestIoctlRetErr2(cmd, arg, 0, 0, 0);
98 }
binderTestIoctlUnimplemented(int cmd,void * arg)99 void binderTestIoctlUnimplemented(int cmd, void *arg) {
100 int ret;
101
102 ret = ioctl(m_binderFd, cmd, arg);
103 if (ret < 0) {
104 /* Not currently implmented. Allow ret == -1, errno == EINVAL */
105 EXPECT_EQ(-1, ret);
106 EXPECT_EQ(EINVAL, errno);
107 }
108 }
binderTestReadEmpty(void)109 void binderTestReadEmpty(void) {
110 size_t i;
111 uint32_t br[32];
112 struct binder_write_read bwr = binder_write_read();
113 SCOPED_TRACE("TestReadEmpty");
114 bwr.read_buffer = (uintptr_t)br;
115 bwr.read_size = sizeof(br);
116 binderTestIoctlErr1(BINDER_WRITE_READ, &bwr, EAGAIN);
117 EXPECT_EQ(0u, bwr.read_consumed);
118 for (i = 0; i * sizeof(uint32_t) < bwr.read_consumed; i++) {
119 SCOPED_TRACE(testing::Message() << "i = " << i);
120 EXPECT_EQ(BR_NOOP, br[i]);
121 }
122 }
binderWaitForReadData(int timeout_ms)123 void binderWaitForReadData(int timeout_ms) {
124 int ret;
125 pollfd pfd = pollfd();
126
127 pfd.fd = m_binderFd;
128 pfd.events = POLLIN;
129 ret = poll(&pfd, 1, timeout_ms);
130 EXPECT_EQ(1, ret);
131 }
132 private:
133 int m_binderFd;
134 };
135
TEST_F(BinderDriverInterfaceTest,Version)136 TEST_F(BinderDriverInterfaceTest, Version) {
137 struct binder_version version;
138 binderTestIoctl(BINDER_VERSION, &version);
139 ASSERT_EQ(BINDER_CURRENT_PROTOCOL_VERSION, version.protocol_version);
140 }
141
TEST_F(BinderDriverInterfaceTest,WriteReadNull)142 TEST_F(BinderDriverInterfaceTest, WriteReadNull) {
143 binderTestIoctlErr1(BINDER_WRITE_READ, NULL, EFAULT);
144 }
145
TEST_F(BinderDriverInterfaceTest,SetIdleTimeoutNull)146 TEST_F(BinderDriverInterfaceTest, SetIdleTimeoutNull) {
147 binderTestIoctlErr2(BINDER_SET_IDLE_TIMEOUT, NULL, EFAULT, EINVAL);
148 }
149
TEST_F(BinderDriverInterfaceTest,SetMaxThreadsNull)150 TEST_F(BinderDriverInterfaceTest, SetMaxThreadsNull) {
151 binderTestIoctlErr2(BINDER_SET_MAX_THREADS, NULL, EFAULT, EINVAL); /* TODO: don't accept EINVAL */
152 }
153
TEST_F(BinderDriverInterfaceTest,SetIdlePriorityNull)154 TEST_F(BinderDriverInterfaceTest, SetIdlePriorityNull) {
155 binderTestIoctlErr2(BINDER_SET_IDLE_PRIORITY, NULL, EFAULT, EINVAL);
156 }
157
TEST_F(BinderDriverInterfaceTest,VersionNull)158 TEST_F(BinderDriverInterfaceTest, VersionNull) {
159 binderTestIoctlErr2(BINDER_VERSION, NULL, EFAULT, EINVAL); /* TODO: don't accept EINVAL */
160 }
161
TEST_F(BinderDriverInterfaceTest,SetIdleTimeoutNoTest)162 TEST_F(BinderDriverInterfaceTest, SetIdleTimeoutNoTest) {
163 int64_t idle_timeout = 100000;
164 binderTestIoctlUnimplemented(BINDER_SET_IDLE_TIMEOUT, &idle_timeout);
165 }
166
TEST_F(BinderDriverInterfaceTest,SetMaxThreads)167 TEST_F(BinderDriverInterfaceTest, SetMaxThreads) {
168 uint32_t max_threads = 0;
169 binderTestIoctl(BINDER_SET_MAX_THREADS, &max_threads);
170 }
171
TEST_F(BinderDriverInterfaceTest,SetIdlePriorityNoTest)172 TEST_F(BinderDriverInterfaceTest, SetIdlePriorityNoTest) {
173 int idle_priority = 0;
174 binderTestIoctlUnimplemented(BINDER_SET_IDLE_PRIORITY, &idle_priority);
175 }
176
TEST_F(BinderDriverInterfaceTest,SetContextMgrBusy)177 TEST_F(BinderDriverInterfaceTest, SetContextMgrBusy) {
178 int32_t dummy = 0;
179 binderTestIoctlErr1(BINDER_SET_CONTEXT_MGR, &dummy, EBUSY);
180 }
181
TEST_F(BinderDriverInterfaceTest,ThreadExit)182 TEST_F(BinderDriverInterfaceTest, ThreadExit) {
183 int32_t dummy = 0;
184 binderTestIoctl(BINDER_THREAD_EXIT, &dummy);
185 static_cast<BinderDriverInterfaceTestEnv *>(binder_env)->EnterLooper();
186 }
187
TEST_F(BinderDriverInterfaceTest,WriteReadEmpty)188 TEST_F(BinderDriverInterfaceTest, WriteReadEmpty) {
189 struct binder_write_read bwr = binder_write_read();
190 binderTestIoctl(BINDER_WRITE_READ, &bwr);
191 }
192
TEST_F(BinderDriverInterfaceTest,Read)193 TEST_F(BinderDriverInterfaceTest, Read) {
194 binderTestReadEmpty();
195 }
196
TEST_F(BinderDriverInterfaceTest,IncRefsAcquireReleaseDecRefs)197 TEST_F(BinderDriverInterfaceTest, IncRefsAcquireReleaseDecRefs) {
198 const uint32_t bc[] = {
199 BC_INCREFS,
200 0,
201 BC_ACQUIRE,
202 0,
203 BC_RELEASE,
204 0,
205 BC_DECREFS,
206 0,
207 };
208 struct binder_write_read bwr = binder_write_read();
209 bwr.write_buffer = (uintptr_t)bc;
210 bwr.write_size = sizeof(bc);
211 binderTestIoctl(BINDER_WRITE_READ, &bwr);
212 EXPECT_EQ(sizeof(bc), bwr.write_consumed);
213 binderTestReadEmpty();
214 }
215
TEST_F(BinderDriverInterfaceTest,Transaction)216 TEST_F(BinderDriverInterfaceTest, Transaction) {
217 binder_uintptr_t cookie = 1234;
218 struct {
219 uint32_t cmd1;
220 struct binder_transaction_data arg1;
221 } __attribute__((packed)) bc1 = {
222 .cmd1 = BC_TRANSACTION,
223 .arg1 = {
224 .target = { 0 },
225 .cookie = 0,
226 .code = android::IBinder::PING_TRANSACTION,
227 .flags = 0,
228 .sender_pid = 0,
229 .sender_euid = 0,
230 .data_size = 0,
231 .offsets_size = 0,
232 .data = {0, 0},
233 },
234 };
235 struct {
236 uint32_t cmd0;
237 uint32_t cmd1;
238 uint32_t cmd2;
239 binder_transaction_data arg2;
240 uint32_t pad[16];
241 } __attribute__((packed)) br;
242 struct binder_write_read bwr = binder_write_read();
243
244 bwr.write_buffer = (uintptr_t)&bc1;
245 bwr.write_size = sizeof(bc1);
246 bwr.read_buffer = (uintptr_t)&br;
247 bwr.read_size = sizeof(br);
248
249 {
250 SCOPED_TRACE("1st WriteRead");
251 binderTestIoctl(BINDER_WRITE_READ, &bwr);
252 }
253 EXPECT_EQ(sizeof(bc1), bwr.write_consumed);
254 if (bwr.read_consumed < offsetof(typeof(br), pad)) {
255 SCOPED_TRACE("2nd WriteRead");
256 binderWaitForReadData(10000);
257 binderTestIoctl(BINDER_WRITE_READ, &bwr);
258 }
259 EXPECT_EQ(offsetof(typeof(br), pad), bwr.read_consumed);
260 if (bwr.read_consumed > offsetof(typeof(br), cmd0))
261 EXPECT_EQ(BR_NOOP, br.cmd0);
262 if (bwr.read_consumed > offsetof(typeof(br), cmd1))
263 EXPECT_EQ(BR_TRANSACTION_COMPLETE, br.cmd1);
264 if (bwr.read_consumed > offsetof(typeof(br), cmd2))
265 EXPECT_EQ(BR_REPLY, br.cmd2);
266 if (bwr.read_consumed >= offsetof(typeof(br), pad)) {
267 EXPECT_EQ(0u, br.arg2.target.ptr);
268 EXPECT_EQ(0u, br.arg2.cookie);
269 EXPECT_EQ(0u, br.arg2.code);
270 EXPECT_EQ(0u, br.arg2.flags);
271 EXPECT_EQ(0u, br.arg2.data_size);
272 EXPECT_EQ(0u, br.arg2.offsets_size);
273
274 SCOPED_TRACE("3rd WriteRead");
275
276 binderTestReadEmpty();
277
278 struct {
279 uint32_t cmd1;
280 binder_uintptr_t arg1;
281 } __attribute__((packed)) bc2 = {
282 .cmd1 = BC_FREE_BUFFER,
283 .arg1 = br.arg2.data.ptr.buffer,
284 };
285
286 bwr.write_buffer = (uintptr_t)&bc2;
287 bwr.write_size = sizeof(bc2);
288 bwr.write_consumed = 0;
289 bwr.read_size = 0;
290
291 binderTestIoctl(BINDER_WRITE_READ, &bwr);
292 EXPECT_EQ(sizeof(bc2), bwr.write_consumed);
293 }
294 binderTestReadEmpty();
295 }
296
TEST_F(BinderDriverInterfaceTest,RequestDeathNotification)297 TEST_F(BinderDriverInterfaceTest, RequestDeathNotification) {
298 binder_uintptr_t cookie = 1234;
299 struct {
300 uint32_t cmd0;
301 uint32_t arg0;
302 uint32_t cmd1;
303 struct binder_handle_cookie arg1;
304 uint32_t cmd2;
305 struct binder_handle_cookie arg2;
306 uint32_t cmd3;
307 uint32_t arg3;
308 } __attribute__((packed)) bc = {
309 .cmd0 = BC_INCREFS,
310 .arg0 = 0,
311 .cmd1 = BC_REQUEST_DEATH_NOTIFICATION,
312 .arg1 = {
313 .handle = 0,
314 .cookie = cookie,
315 },
316 .cmd2 = BC_CLEAR_DEATH_NOTIFICATION,
317 .arg2 = {
318 .handle = 0,
319 .cookie = cookie,
320 },
321 .cmd3 = BC_DECREFS,
322 .arg3 = 0,
323 };
324 struct {
325 uint32_t cmd0;
326 uint32_t cmd1;
327 binder_uintptr_t arg1;
328 uint32_t pad[16];
329 } __attribute__((packed)) br;
330 struct binder_write_read bwr = binder_write_read();
331
332 bwr.write_buffer = (uintptr_t)&bc;
333 bwr.write_size = sizeof(bc);
334 bwr.read_buffer = (uintptr_t)&br;
335 bwr.read_size = sizeof(br);
336
337 binderTestIoctl(BINDER_WRITE_READ, &bwr);
338 EXPECT_EQ(sizeof(bc), bwr.write_consumed);
339 EXPECT_EQ(sizeof(br) - sizeof(br.pad), bwr.read_consumed);
340 EXPECT_EQ(BR_NOOP, br.cmd0);
341 EXPECT_EQ(BR_CLEAR_DEATH_NOTIFICATION_DONE, br.cmd1);
342 EXPECT_EQ(cookie, br.arg1);
343 binderTestReadEmpty();
344 }
345
main(int argc,char ** argv)346 int main(int argc, char **argv) {
347 ::testing::InitGoogleTest(&argc, argv);
348
349 binder_env = AddGlobalTestEnvironment(new BinderDriverInterfaceTestEnv());
350
351 return RUN_ALL_TESTS();
352 }
353
354