blob: de9d42bac010697cf03cbeff6cbedc819fd218aa [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
Tomasz Wasilczykb70f4712024-06-21 11:58:54 -070022#include <binder/IBinder.h>
Riley Andrewsdc9b1482014-12-18 11:54:32 -080023#include <gtest/gtest.h>
Dan Willemsene05dc6d2016-07-25 17:13:45 -070024#include <linux/android/binder.h>
Riley Andrewsdc9b1482014-12-18 11:54:32 -080025#include <poll.h>
Tomasz Wasilczykb70f4712024-06-21 11:58:54 -070026#include <sys/ioctl.h>
27#include <sys/mman.h>
Riley Andrewsdc9b1482014-12-18 11:54:32 -080028
29#define BINDER_DEV_NAME "/dev/binder"
30
31testing::Environment* binder_env;
32
33class BinderDriverInterfaceTestEnv : public ::testing::Environment {
34 virtual void SetUp() {
35 int ret;
36 uint32_t max_threads = 0;
37
Nick Kralevich0fe7ce32015-12-23 18:58:05 -080038 m_binderFd = open(BINDER_DEV_NAME, O_RDWR | O_NONBLOCK | O_CLOEXEC);
Riley Andrewsdc9b1482014-12-18 11:54:32 -080039 ASSERT_GE(m_binderFd, 0);
Yi Kongfdd8da92018-06-07 17:52:27 -070040 m_buffer = mmap(nullptr, 64*1024, PROT_READ, MAP_SHARED, m_binderFd, 0);
41 ASSERT_NE(m_buffer, (void *)nullptr);
Riley Andrewsdc9b1482014-12-18 11:54:32 -080042 ret = ioctl(m_binderFd, BINDER_SET_MAX_THREADS, &max_threads);
43 EXPECT_EQ(0, ret);
44 EnterLooper();
45 }
46 virtual void TearDown() {
47 close(m_binderFd);
48 }
49 private:
50 int m_binderFd;
51 void *m_buffer;
52 public:
53 int getBinderFd(void) {
54 return m_binderFd;
55 }
56 void EnterLooper(void) {
57 int ret;
58 const uint32_t bc[] = {
59 BC_ENTER_LOOPER,
60 };
61 struct binder_write_read bwr = binder_write_read();
Riley Andrews29d8cf92015-01-12 18:16:29 -080062 bwr.write_buffer = (uintptr_t)bc;
Riley Andrewsdc9b1482014-12-18 11:54:32 -080063 bwr.write_size = sizeof(bc);
64 ret = ioctl(m_binderFd, BINDER_WRITE_READ, &bwr);
65 EXPECT_EQ(0, ret);
66 if (ret < 0) {
67 EXPECT_EQ(0, errno);
68 }
69 EXPECT_EQ(sizeof(bc), bwr.write_consumed);
70 }
71};
72
73class BinderDriverInterfaceTest : public ::testing::Test {
74 public:
75 virtual void SetUp() {
76 m_binderFd = static_cast<BinderDriverInterfaceTestEnv *>(binder_env)->getBinderFd();
77 }
78 virtual void TearDown() {
79 }
80 protected:
Martijn Coenen2b39df72017-12-11 11:10:34 +010081 /* The ioctl must either return 0, or if it doesn't errno should be accepted_errno */
82 void binderTestIoctlSuccessOrError(int cmd, void *arg, int accepted_errno) {
83 int ret;
84
85 ret = ioctl(m_binderFd, cmd, arg);
86 if (ret != 0) {
87 EXPECT_EQ(errno, accepted_errno);
88 }
89 }
90
Riley Andrewsdc9b1482014-12-18 11:54:32 -080091 void binderTestIoctlRetErr2(int cmd, void *arg, int expect_ret, int expect_errno, int accept_errno) {
92 int ret;
93
94 ret = ioctl(m_binderFd, cmd, arg);
95 EXPECT_EQ(expect_ret, ret);
96 if (ret < 0) {
97 if (errno != accept_errno)
98 EXPECT_EQ(expect_errno, errno);
99 }
100 }
101 void binderTestIoctlErr2(int cmd, void *arg, int expect_errno, int accept_errno) {
102 binderTestIoctlRetErr2(cmd, arg, -1, expect_errno, accept_errno);
103 }
104 void binderTestIoctlErr1(int cmd, void *arg, int expect_errno) {
105 binderTestIoctlErr2(cmd, arg, expect_errno, expect_errno);
106 }
107 void binderTestIoctl(int cmd, void *arg) {
108 binderTestIoctlRetErr2(cmd, arg, 0, 0, 0);
109 }
110 void binderTestIoctlUnimplemented(int cmd, void *arg) {
111 int ret;
112
113 ret = ioctl(m_binderFd, cmd, arg);
114 if (ret < 0) {
115 /* Not currently implmented. Allow ret == -1, errno == EINVAL */
116 EXPECT_EQ(-1, ret);
117 EXPECT_EQ(EINVAL, errno);
118 }
119 }
120 void binderTestReadEmpty(void) {
121 size_t i;
122 uint32_t br[32];
123 struct binder_write_read bwr = binder_write_read();
124 SCOPED_TRACE("TestReadEmpty");
Riley Andrews29d8cf92015-01-12 18:16:29 -0800125 bwr.read_buffer = (uintptr_t)br;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800126 bwr.read_size = sizeof(br);
127 binderTestIoctlErr1(BINDER_WRITE_READ, &bwr, EAGAIN);
Riley Andrews50bcb002015-01-12 18:14:55 -0800128 EXPECT_EQ(0u, bwr.read_consumed);
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800129 for (i = 0; i * sizeof(uint32_t) < bwr.read_consumed; i++) {
130 SCOPED_TRACE(testing::Message() << "i = " << i);
131 EXPECT_EQ(BR_NOOP, br[i]);
132 }
133 }
134 void binderWaitForReadData(int timeout_ms) {
135 int ret;
136 pollfd pfd = pollfd();
137
138 pfd.fd = m_binderFd;
139 pfd.events = POLLIN;
140 ret = poll(&pfd, 1, timeout_ms);
141 EXPECT_EQ(1, ret);
142 }
143 private:
144 int m_binderFd;
145};
146
147TEST_F(BinderDriverInterfaceTest, Version) {
148 struct binder_version version;
149 binderTestIoctl(BINDER_VERSION, &version);
150 ASSERT_EQ(BINDER_CURRENT_PROTOCOL_VERSION, version.protocol_version);
151}
152
Sherry Yang2437b322017-08-29 16:07:57 -0700153TEST_F(BinderDriverInterfaceTest, OpenNoMmap) {
154 int binderFd = open(BINDER_DEV_NAME, O_RDWR | O_NONBLOCK | O_CLOEXEC);
155 ASSERT_GE(binderFd, 0);
156 close(binderFd);
157}
158
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800159TEST_F(BinderDriverInterfaceTest, WriteReadNull) {
Yi Kongfdd8da92018-06-07 17:52:27 -0700160 binderTestIoctlErr1(BINDER_WRITE_READ, nullptr, EFAULT);
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800161}
162
163TEST_F(BinderDriverInterfaceTest, SetIdleTimeoutNull) {
Yi Kongfdd8da92018-06-07 17:52:27 -0700164 binderTestIoctlErr2(BINDER_SET_IDLE_TIMEOUT, nullptr, EFAULT, EINVAL);
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800165}
166
167TEST_F(BinderDriverInterfaceTest, SetMaxThreadsNull) {
Yi Kongfdd8da92018-06-07 17:52:27 -0700168 binderTestIoctlErr2(BINDER_SET_MAX_THREADS, nullptr, EFAULT, EINVAL); /* TODO: don't accept EINVAL */
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800169}
170
171TEST_F(BinderDriverInterfaceTest, SetIdlePriorityNull) {
Yi Kongfdd8da92018-06-07 17:52:27 -0700172 binderTestIoctlErr2(BINDER_SET_IDLE_PRIORITY, nullptr, EFAULT, EINVAL);
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800173}
174
175TEST_F(BinderDriverInterfaceTest, VersionNull) {
Yi Kongfdd8da92018-06-07 17:52:27 -0700176 binderTestIoctlErr2(BINDER_VERSION, nullptr, EFAULT, EINVAL); /* TODO: don't accept EINVAL */
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800177}
178
179TEST_F(BinderDriverInterfaceTest, SetIdleTimeoutNoTest) {
180 int64_t idle_timeout = 100000;
181 binderTestIoctlUnimplemented(BINDER_SET_IDLE_TIMEOUT, &idle_timeout);
182}
183
184TEST_F(BinderDriverInterfaceTest, SetMaxThreads) {
185 uint32_t max_threads = 0;
186 binderTestIoctl(BINDER_SET_MAX_THREADS, &max_threads);
187}
188
189TEST_F(BinderDriverInterfaceTest, SetIdlePriorityNoTest) {
190 int idle_priority = 0;
191 binderTestIoctlUnimplemented(BINDER_SET_IDLE_PRIORITY, &idle_priority);
192}
193
194TEST_F(BinderDriverInterfaceTest, SetContextMgrBusy) {
195 int32_t dummy = 0;
196 binderTestIoctlErr1(BINDER_SET_CONTEXT_MGR, &dummy, EBUSY);
197}
198
199TEST_F(BinderDriverInterfaceTest, ThreadExit) {
200 int32_t dummy = 0;
201 binderTestIoctl(BINDER_THREAD_EXIT, &dummy);
202 static_cast<BinderDriverInterfaceTestEnv *>(binder_env)->EnterLooper();
203}
204
205TEST_F(BinderDriverInterfaceTest, WriteReadEmpty) {
206 struct binder_write_read bwr = binder_write_read();
207 binderTestIoctl(BINDER_WRITE_READ, &bwr);
208}
209
210TEST_F(BinderDriverInterfaceTest, Read) {
211 binderTestReadEmpty();
212}
213
214TEST_F(BinderDriverInterfaceTest, IncRefsAcquireReleaseDecRefs) {
215 const uint32_t bc[] = {
216 BC_INCREFS,
217 0,
218 BC_ACQUIRE,
219 0,
220 BC_RELEASE,
221 0,
222 BC_DECREFS,
223 0,
224 };
225 struct binder_write_read bwr = binder_write_read();
Riley Andrews29d8cf92015-01-12 18:16:29 -0800226 bwr.write_buffer = (uintptr_t)bc;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800227 bwr.write_size = sizeof(bc);
228 binderTestIoctl(BINDER_WRITE_READ, &bwr);
229 EXPECT_EQ(sizeof(bc), bwr.write_consumed);
230 binderTestReadEmpty();
231}
232
233TEST_F(BinderDriverInterfaceTest, Transaction) {
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800234 struct {
235 uint32_t cmd1;
236 struct binder_transaction_data arg1;
237 } __attribute__((packed)) bc1 = {
238 .cmd1 = BC_TRANSACTION,
239 .arg1 = {
240 .target = { 0 },
241 .cookie = 0,
242 .code = android::IBinder::PING_TRANSACTION,
243 .flags = 0,
244 .sender_pid = 0,
245 .sender_euid = 0,
246 .data_size = 0,
247 .offsets_size = 0,
Wei Wang78f2a372016-10-20 23:18:17 -0700248 .data = {
249 .ptr = {0, 0},
250 },
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800251 },
252 };
253 struct {
254 uint32_t cmd0;
255 uint32_t cmd1;
256 uint32_t cmd2;
257 binder_transaction_data arg2;
258 uint32_t pad[16];
259 } __attribute__((packed)) br;
260 struct binder_write_read bwr = binder_write_read();
261
Riley Andrews29d8cf92015-01-12 18:16:29 -0800262 bwr.write_buffer = (uintptr_t)&bc1;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800263 bwr.write_size = sizeof(bc1);
Riley Andrews29d8cf92015-01-12 18:16:29 -0800264 bwr.read_buffer = (uintptr_t)&br;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800265 bwr.read_size = sizeof(br);
266
267 {
268 SCOPED_TRACE("1st WriteRead");
Martijn Coenen2b39df72017-12-11 11:10:34 +0100269 binderTestIoctlSuccessOrError(BINDER_WRITE_READ, &bwr, EAGAIN);
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800270 }
271 EXPECT_EQ(sizeof(bc1), bwr.write_consumed);
272 if (bwr.read_consumed < offsetof(typeof(br), pad)) {
273 SCOPED_TRACE("2nd WriteRead");
274 binderWaitForReadData(10000);
275 binderTestIoctl(BINDER_WRITE_READ, &bwr);
276 }
277 EXPECT_EQ(offsetof(typeof(br), pad), bwr.read_consumed);
278 if (bwr.read_consumed > offsetof(typeof(br), cmd0))
279 EXPECT_EQ(BR_NOOP, br.cmd0);
280 if (bwr.read_consumed > offsetof(typeof(br), cmd1))
281 EXPECT_EQ(BR_TRANSACTION_COMPLETE, br.cmd1);
282 if (bwr.read_consumed > offsetof(typeof(br), cmd2))
283 EXPECT_EQ(BR_REPLY, br.cmd2);
284 if (bwr.read_consumed >= offsetof(typeof(br), pad)) {
Riley Andrews50bcb002015-01-12 18:14:55 -0800285 EXPECT_EQ(0u, br.arg2.target.ptr);
286 EXPECT_EQ(0u, br.arg2.cookie);
287 EXPECT_EQ(0u, br.arg2.code);
288 EXPECT_EQ(0u, br.arg2.flags);
Steven Moreland6e69d652019-07-10 14:17:55 -0700289 EXPECT_EQ(0u, br.arg2.data_size);
Riley Andrews50bcb002015-01-12 18:14:55 -0800290 EXPECT_EQ(0u, br.arg2.offsets_size);
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800291
292 SCOPED_TRACE("3rd WriteRead");
293
294 binderTestReadEmpty();
295
296 struct {
297 uint32_t cmd1;
298 binder_uintptr_t arg1;
299 } __attribute__((packed)) bc2 = {
300 .cmd1 = BC_FREE_BUFFER,
301 .arg1 = br.arg2.data.ptr.buffer,
302 };
303
Riley Andrews29d8cf92015-01-12 18:16:29 -0800304 bwr.write_buffer = (uintptr_t)&bc2;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800305 bwr.write_size = sizeof(bc2);
306 bwr.write_consumed = 0;
307 bwr.read_size = 0;
308
309 binderTestIoctl(BINDER_WRITE_READ, &bwr);
310 EXPECT_EQ(sizeof(bc2), bwr.write_consumed);
311 }
312 binderTestReadEmpty();
313}
314
315TEST_F(BinderDriverInterfaceTest, RequestDeathNotification) {
316 binder_uintptr_t cookie = 1234;
317 struct {
318 uint32_t cmd0;
319 uint32_t arg0;
320 uint32_t cmd1;
321 struct binder_handle_cookie arg1;
322 uint32_t cmd2;
323 struct binder_handle_cookie arg2;
324 uint32_t cmd3;
325 uint32_t arg3;
326 } __attribute__((packed)) bc = {
327 .cmd0 = BC_INCREFS,
328 .arg0 = 0,
329 .cmd1 = BC_REQUEST_DEATH_NOTIFICATION,
330 .arg1 = {
331 .handle = 0,
332 .cookie = cookie,
333 },
334 .cmd2 = BC_CLEAR_DEATH_NOTIFICATION,
335 .arg2 = {
336 .handle = 0,
337 .cookie = cookie,
338 },
339 .cmd3 = BC_DECREFS,
340 .arg3 = 0,
341 };
342 struct {
343 uint32_t cmd0;
344 uint32_t cmd1;
345 binder_uintptr_t arg1;
346 uint32_t pad[16];
347 } __attribute__((packed)) br;
348 struct binder_write_read bwr = binder_write_read();
349
Riley Andrews29d8cf92015-01-12 18:16:29 -0800350 bwr.write_buffer = (uintptr_t)&bc;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800351 bwr.write_size = sizeof(bc);
Riley Andrews29d8cf92015-01-12 18:16:29 -0800352 bwr.read_buffer = (uintptr_t)&br;
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800353 bwr.read_size = sizeof(br);
354
355 binderTestIoctl(BINDER_WRITE_READ, &bwr);
356 EXPECT_EQ(sizeof(bc), bwr.write_consumed);
357 EXPECT_EQ(sizeof(br) - sizeof(br.pad), bwr.read_consumed);
358 EXPECT_EQ(BR_NOOP, br.cmd0);
359 EXPECT_EQ(BR_CLEAR_DEATH_NOTIFICATION_DONE, br.cmd1);
360 EXPECT_EQ(cookie, br.arg1);
361 binderTestReadEmpty();
362}
363
Steven Moreland68275d72023-04-21 22:12:45 +0000364int main(int argc, char** argv) {
Riley Andrewsdc9b1482014-12-18 11:54:32 -0800365 ::testing::InitGoogleTest(&argc, argv);
366
367 binder_env = AddGlobalTestEnvironment(new BinderDriverInterfaceTestEnv());
368
369 return RUN_ALL_TESTS();
370}