blob: 8cc3054f80dda180a55c3609dfb13a8fabb2bd08 [file] [log] [blame]
Riley Andrewsdc9b1482014-12-18 11:54:32 -08001/*
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>
Dan Willemsene05dc6d2016-07-25 17:13:45 -070023#include <linux/android/binder.h>
Riley Andrewsdc9b1482014-12-18 11:54:32 -080024#include <binder/IBinder.h>
25#include <sys/mman.h>
26#include <poll.h>
27
Steven Morelandf9f3de22020-05-06 17:14:39 -070028#include "binderAbiHelper.h"
29
Riley Andrewsdc9b1482014-12-18 11:54:32 -080030#define BINDER_DEV_NAME "/dev/binder"
31
32testing::Environment* binder_env;
33
34class BinderDriverInterfaceTestEnv : public ::testing::Environment {
35 virtual void SetUp() {
36 int ret;
37 uint32_t max_threads = 0;
38
Nick Kralevich0fe7ce32015-12-23 18:58:05 -080039 m_binderFd = open(BINDER_DEV_NAME, O_RDWR | O_NONBLOCK | O_CLOEXEC);
Riley Andrewsdc9b1482014-12-18 11:54:32 -080040 ASSERT_GE(m_binderFd, 0);
Yi Kongfdd8da92018-06-07 17:52:27 -070041 m_buffer = mmap(nullptr, 64*1024, PROT_READ, MAP_SHARED, m_binderFd, 0);
42 ASSERT_NE(m_buffer, (void *)nullptr);
Riley Andrewsdc9b1482014-12-18 11:54:32 -080043 ret = ioctl(m_binderFd, BINDER_SET_MAX_THREADS, &max_threads);
44 EXPECT_EQ(0, ret);
45 EnterLooper();
46 }
47 virtual void TearDown() {
48 close(m_binderFd);
49 }
50 private:
51 int m_binderFd;
52 void *m_buffer;
53 public:
54 int getBinderFd(void) {
55 return m_binderFd;
56 }
57 void EnterLooper(void) {
58 int ret;
59 const uint32_t bc[] = {
60 BC_ENTER_LOOPER,
61 };
62 struct binder_write_read bwr = binder_write_read();
Riley Andrews29d8cf92015-01-12 18:16:29 -080063 bwr.write_buffer = (uintptr_t)bc;
Riley Andrewsdc9b1482014-12-18 11:54:32 -080064 bwr.write_size = sizeof(bc);
65 ret = ioctl(m_binderFd, BINDER_WRITE_READ, &bwr);
66 EXPECT_EQ(0, ret);
67 if (ret < 0) {
68 EXPECT_EQ(0, errno);
69 }
70 EXPECT_EQ(sizeof(bc), bwr.write_consumed);
71 }
72};
73
74class BinderDriverInterfaceTest : public ::testing::Test {
75 public:
76 virtual void SetUp() {
77 m_binderFd = static_cast<BinderDriverInterfaceTestEnv *>(binder_env)->getBinderFd();
78 }
79 virtual void TearDown() {
80 }
81 protected:
Martijn Coenen2b39df72017-12-11 11:10:34 +010082 /* The ioctl must either return 0, or if it doesn't errno should be accepted_errno */
83 void binderTestIoctlSuccessOrError(int cmd, void *arg, int accepted_errno) {
84 int ret;
85
86 ret = ioctl(m_binderFd, cmd, arg);
87 if (ret != 0) {
88 EXPECT_EQ(errno, accepted_errno);
89 }
90 }
91
Riley Andrewsdc9b1482014-12-18 11:54:32 -080092 void binderTestIoctlRetErr2(int cmd, void *arg, int expect_ret, int expect_errno, int accept_errno) {
93 int ret;
94
95 ret = ioctl(m_binderFd, cmd, arg);
96 EXPECT_EQ(expect_ret, ret);
97 if (ret < 0) {
98 if (errno != accept_errno)
99 EXPECT_EQ(expect_errno, errno);
100 }
101 }
102 void binderTestIoctlErr2(int cmd, void *arg, int expect_errno, int accept_errno) {
103 binderTestIoctlRetErr2(cmd, arg, -1, expect_errno, accept_errno);
104 }
105 void binderTestIoctlErr1(int cmd, void *arg, int expect_errno) {
106 binderTestIoctlErr2(cmd, arg, expect_errno, expect_errno);
107 }
108 void binderTestIoctl(int cmd, void *arg) {
109 binderTestIoctlRetErr2(cmd, arg, 0, 0, 0);
110 }
111 void binderTestIoctlUnimplemented(int cmd, void *arg) {
112 int ret;
113
114 ret = ioctl(m_binderFd, cmd, arg);
115 if (ret < 0) {
116 /* Not currently implmented. Allow ret == -1, errno == EINVAL */
117 EXPECT_EQ(-1, ret);
118 EXPECT_EQ(EINVAL, errno);
119 }
120 }
121 void binderTestReadEmpty(void) {
122 size_t i;
123 uint32_t br[32];
124 struct binder_write_read bwr = binder_write_read();
125 SCOPED_TRACE("TestReadEmpty");
Riley Andrews29d8cf92015-01-12 18:16:29 -0800126 bwr.read_buffer = (uintptr_t)br;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800127 bwr.read_size = sizeof(br);
128 binderTestIoctlErr1(BINDER_WRITE_READ, &bwr, EAGAIN);
Riley Andrews50bcb002015-01-12 18:14:55 -0800129 EXPECT_EQ(0u, bwr.read_consumed);
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800130 for (i = 0; i * sizeof(uint32_t) < bwr.read_consumed; i++) {
131 SCOPED_TRACE(testing::Message() << "i = " << i);
132 EXPECT_EQ(BR_NOOP, br[i]);
133 }
134 }
135 void binderWaitForReadData(int timeout_ms) {
136 int ret;
137 pollfd pfd = pollfd();
138
139 pfd.fd = m_binderFd;
140 pfd.events = POLLIN;
141 ret = poll(&pfd, 1, timeout_ms);
142 EXPECT_EQ(1, ret);
143 }
144 private:
145 int m_binderFd;
146};
147
148TEST_F(BinderDriverInterfaceTest, Version) {
149 struct binder_version version;
150 binderTestIoctl(BINDER_VERSION, &version);
151 ASSERT_EQ(BINDER_CURRENT_PROTOCOL_VERSION, version.protocol_version);
152}
153
Sherry Yang2437b322017-08-29 16:07:57 -0700154TEST_F(BinderDriverInterfaceTest, OpenNoMmap) {
155 int binderFd = open(BINDER_DEV_NAME, O_RDWR | O_NONBLOCK | O_CLOEXEC);
156 ASSERT_GE(binderFd, 0);
157 close(binderFd);
158}
159
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800160TEST_F(BinderDriverInterfaceTest, WriteReadNull) {
Yi Kongfdd8da92018-06-07 17:52:27 -0700161 binderTestIoctlErr1(BINDER_WRITE_READ, nullptr, EFAULT);
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800162}
163
164TEST_F(BinderDriverInterfaceTest, SetIdleTimeoutNull) {
Yi Kongfdd8da92018-06-07 17:52:27 -0700165 binderTestIoctlErr2(BINDER_SET_IDLE_TIMEOUT, nullptr, EFAULT, EINVAL);
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800166}
167
168TEST_F(BinderDriverInterfaceTest, SetMaxThreadsNull) {
Yi Kongfdd8da92018-06-07 17:52:27 -0700169 binderTestIoctlErr2(BINDER_SET_MAX_THREADS, nullptr, EFAULT, EINVAL); /* TODO: don't accept EINVAL */
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800170}
171
172TEST_F(BinderDriverInterfaceTest, SetIdlePriorityNull) {
Yi Kongfdd8da92018-06-07 17:52:27 -0700173 binderTestIoctlErr2(BINDER_SET_IDLE_PRIORITY, nullptr, EFAULT, EINVAL);
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800174}
175
176TEST_F(BinderDriverInterfaceTest, VersionNull) {
Yi Kongfdd8da92018-06-07 17:52:27 -0700177 binderTestIoctlErr2(BINDER_VERSION, nullptr, EFAULT, EINVAL); /* TODO: don't accept EINVAL */
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800178}
179
180TEST_F(BinderDriverInterfaceTest, SetIdleTimeoutNoTest) {
181 int64_t idle_timeout = 100000;
182 binderTestIoctlUnimplemented(BINDER_SET_IDLE_TIMEOUT, &idle_timeout);
183}
184
185TEST_F(BinderDriverInterfaceTest, SetMaxThreads) {
186 uint32_t max_threads = 0;
187 binderTestIoctl(BINDER_SET_MAX_THREADS, &max_threads);
188}
189
190TEST_F(BinderDriverInterfaceTest, SetIdlePriorityNoTest) {
191 int idle_priority = 0;
192 binderTestIoctlUnimplemented(BINDER_SET_IDLE_PRIORITY, &idle_priority);
193}
194
195TEST_F(BinderDriverInterfaceTest, SetContextMgrBusy) {
196 int32_t dummy = 0;
197 binderTestIoctlErr1(BINDER_SET_CONTEXT_MGR, &dummy, EBUSY);
198}
199
200TEST_F(BinderDriverInterfaceTest, ThreadExit) {
201 int32_t dummy = 0;
202 binderTestIoctl(BINDER_THREAD_EXIT, &dummy);
203 static_cast<BinderDriverInterfaceTestEnv *>(binder_env)->EnterLooper();
204}
205
206TEST_F(BinderDriverInterfaceTest, WriteReadEmpty) {
207 struct binder_write_read bwr = binder_write_read();
208 binderTestIoctl(BINDER_WRITE_READ, &bwr);
209}
210
211TEST_F(BinderDriverInterfaceTest, Read) {
212 binderTestReadEmpty();
213}
214
215TEST_F(BinderDriverInterfaceTest, IncRefsAcquireReleaseDecRefs) {
216 const uint32_t bc[] = {
217 BC_INCREFS,
218 0,
219 BC_ACQUIRE,
220 0,
221 BC_RELEASE,
222 0,
223 BC_DECREFS,
224 0,
225 };
226 struct binder_write_read bwr = binder_write_read();
Riley Andrews29d8cf92015-01-12 18:16:29 -0800227 bwr.write_buffer = (uintptr_t)bc;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800228 bwr.write_size = sizeof(bc);
229 binderTestIoctl(BINDER_WRITE_READ, &bwr);
230 EXPECT_EQ(sizeof(bc), bwr.write_consumed);
231 binderTestReadEmpty();
232}
233
234TEST_F(BinderDriverInterfaceTest, Transaction) {
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800235 struct {
236 uint32_t cmd1;
237 struct binder_transaction_data arg1;
238 } __attribute__((packed)) bc1 = {
239 .cmd1 = BC_TRANSACTION,
240 .arg1 = {
241 .target = { 0 },
242 .cookie = 0,
243 .code = android::IBinder::PING_TRANSACTION,
244 .flags = 0,
245 .sender_pid = 0,
246 .sender_euid = 0,
247 .data_size = 0,
248 .offsets_size = 0,
Wei Wang78f2a372016-10-20 23:18:17 -0700249 .data = {
250 .ptr = {0, 0},
251 },
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800252 },
253 };
254 struct {
255 uint32_t cmd0;
256 uint32_t cmd1;
257 uint32_t cmd2;
258 binder_transaction_data arg2;
259 uint32_t pad[16];
260 } __attribute__((packed)) br;
261 struct binder_write_read bwr = binder_write_read();
262
Riley Andrews29d8cf92015-01-12 18:16:29 -0800263 bwr.write_buffer = (uintptr_t)&bc1;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800264 bwr.write_size = sizeof(bc1);
Riley Andrews29d8cf92015-01-12 18:16:29 -0800265 bwr.read_buffer = (uintptr_t)&br;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800266 bwr.read_size = sizeof(br);
267
268 {
269 SCOPED_TRACE("1st WriteRead");
Martijn Coenen2b39df72017-12-11 11:10:34 +0100270 binderTestIoctlSuccessOrError(BINDER_WRITE_READ, &bwr, EAGAIN);
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800271 }
272 EXPECT_EQ(sizeof(bc1), bwr.write_consumed);
273 if (bwr.read_consumed < offsetof(typeof(br), pad)) {
274 SCOPED_TRACE("2nd WriteRead");
275 binderWaitForReadData(10000);
276 binderTestIoctl(BINDER_WRITE_READ, &bwr);
277 }
278 EXPECT_EQ(offsetof(typeof(br), pad), bwr.read_consumed);
279 if (bwr.read_consumed > offsetof(typeof(br), cmd0))
280 EXPECT_EQ(BR_NOOP, br.cmd0);
281 if (bwr.read_consumed > offsetof(typeof(br), cmd1))
282 EXPECT_EQ(BR_TRANSACTION_COMPLETE, br.cmd1);
283 if (bwr.read_consumed > offsetof(typeof(br), cmd2))
284 EXPECT_EQ(BR_REPLY, br.cmd2);
285 if (bwr.read_consumed >= offsetof(typeof(br), pad)) {
Riley Andrews50bcb002015-01-12 18:14:55 -0800286 EXPECT_EQ(0u, br.arg2.target.ptr);
287 EXPECT_EQ(0u, br.arg2.cookie);
288 EXPECT_EQ(0u, br.arg2.code);
289 EXPECT_EQ(0u, br.arg2.flags);
Steven Moreland6e69d652019-07-10 14:17:55 -0700290 EXPECT_EQ(0u, br.arg2.data_size);
Riley Andrews50bcb002015-01-12 18:14:55 -0800291 EXPECT_EQ(0u, br.arg2.offsets_size);
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800292
293 SCOPED_TRACE("3rd WriteRead");
294
295 binderTestReadEmpty();
296
297 struct {
298 uint32_t cmd1;
299 binder_uintptr_t arg1;
300 } __attribute__((packed)) bc2 = {
301 .cmd1 = BC_FREE_BUFFER,
302 .arg1 = br.arg2.data.ptr.buffer,
303 };
304
Riley Andrews29d8cf92015-01-12 18:16:29 -0800305 bwr.write_buffer = (uintptr_t)&bc2;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800306 bwr.write_size = sizeof(bc2);
307 bwr.write_consumed = 0;
308 bwr.read_size = 0;
309
310 binderTestIoctl(BINDER_WRITE_READ, &bwr);
311 EXPECT_EQ(sizeof(bc2), bwr.write_consumed);
312 }
313 binderTestReadEmpty();
314}
315
316TEST_F(BinderDriverInterfaceTest, RequestDeathNotification) {
317 binder_uintptr_t cookie = 1234;
318 struct {
319 uint32_t cmd0;
320 uint32_t arg0;
321 uint32_t cmd1;
322 struct binder_handle_cookie arg1;
323 uint32_t cmd2;
324 struct binder_handle_cookie arg2;
325 uint32_t cmd3;
326 uint32_t arg3;
327 } __attribute__((packed)) bc = {
328 .cmd0 = BC_INCREFS,
329 .arg0 = 0,
330 .cmd1 = BC_REQUEST_DEATH_NOTIFICATION,
331 .arg1 = {
332 .handle = 0,
333 .cookie = cookie,
334 },
335 .cmd2 = BC_CLEAR_DEATH_NOTIFICATION,
336 .arg2 = {
337 .handle = 0,
338 .cookie = cookie,
339 },
340 .cmd3 = BC_DECREFS,
341 .arg3 = 0,
342 };
343 struct {
344 uint32_t cmd0;
345 uint32_t cmd1;
346 binder_uintptr_t arg1;
347 uint32_t pad[16];
348 } __attribute__((packed)) br;
349 struct binder_write_read bwr = binder_write_read();
350
Riley Andrews29d8cf92015-01-12 18:16:29 -0800351 bwr.write_buffer = (uintptr_t)&bc;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800352 bwr.write_size = sizeof(bc);
Riley Andrews29d8cf92015-01-12 18:16:29 -0800353 bwr.read_buffer = (uintptr_t)&br;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800354 bwr.read_size = sizeof(br);
355
356 binderTestIoctl(BINDER_WRITE_READ, &bwr);
357 EXPECT_EQ(sizeof(bc), bwr.write_consumed);
358 EXPECT_EQ(sizeof(br) - sizeof(br.pad), bwr.read_consumed);
359 EXPECT_EQ(BR_NOOP, br.cmd0);
360 EXPECT_EQ(BR_CLEAR_DEATH_NOTIFICATION_DONE, br.cmd1);
361 EXPECT_EQ(cookie, br.arg1);
362 binderTestReadEmpty();
363}
364
365int main(int argc, char **argv) {
Steven Morelandf9f3de22020-05-06 17:14:39 -0700366 ExitIfWrongAbi();
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800367 ::testing::InitGoogleTest(&argc, argv);
368
369 binder_env = AddGlobalTestEnvironment(new BinderDriverInterfaceTestEnv());
370
371 return RUN_ALL_TESTS();
372}