• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/android/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 | O_CLOEXEC);
38             ASSERT_GE(m_binderFd, 0);
39             m_buffer = mmap(nullptr, 64*1024, PROT_READ, MAP_SHARED, m_binderFd, 0);
40             ASSERT_NE(m_buffer, (void *)nullptr);
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:
80         /* The ioctl must either return 0, or if it doesn't errno should be accepted_errno */
binderTestIoctlSuccessOrError(int cmd,void * arg,int accepted_errno)81         void binderTestIoctlSuccessOrError(int cmd, void *arg, int accepted_errno) {
82             int ret;
83 
84             ret = ioctl(m_binderFd, cmd, arg);
85             if (ret != 0) {
86                 EXPECT_EQ(errno, accepted_errno);
87             }
88         }
89 
binderTestIoctlRetErr2(int cmd,void * arg,int expect_ret,int expect_errno,int accept_errno)90         void binderTestIoctlRetErr2(int cmd, void *arg, int expect_ret, int expect_errno, int accept_errno) {
91             int ret;
92 
93             ret = ioctl(m_binderFd, cmd, arg);
94             EXPECT_EQ(expect_ret, ret);
95             if (ret < 0) {
96                 if (errno != accept_errno)
97                     EXPECT_EQ(expect_errno, errno);
98             }
99         }
binderTestIoctlErr2(int cmd,void * arg,int expect_errno,int accept_errno)100         void binderTestIoctlErr2(int cmd, void *arg, int expect_errno, int accept_errno) {
101             binderTestIoctlRetErr2(cmd, arg, -1, expect_errno, accept_errno);
102         }
binderTestIoctlErr1(int cmd,void * arg,int expect_errno)103         void binderTestIoctlErr1(int cmd, void *arg, int expect_errno) {
104             binderTestIoctlErr2(cmd, arg, expect_errno, expect_errno);
105         }
binderTestIoctl(int cmd,void * arg)106         void binderTestIoctl(int cmd, void *arg) {
107             binderTestIoctlRetErr2(cmd, arg, 0, 0, 0);
108         }
binderTestIoctlUnimplemented(int cmd,void * arg)109         void binderTestIoctlUnimplemented(int cmd, void *arg) {
110             int ret;
111 
112             ret = ioctl(m_binderFd, cmd, arg);
113             if (ret < 0) {
114                 /* Not currently implmented. Allow ret == -1, errno == EINVAL */
115                 EXPECT_EQ(-1, ret);
116                 EXPECT_EQ(EINVAL, errno);
117             }
118         }
binderTestReadEmpty(void)119         void binderTestReadEmpty(void) {
120             size_t i;
121             uint32_t br[32];
122             struct binder_write_read bwr = binder_write_read();
123             SCOPED_TRACE("TestReadEmpty");
124             bwr.read_buffer = (uintptr_t)br;
125             bwr.read_size = sizeof(br);
126             binderTestIoctlErr1(BINDER_WRITE_READ, &bwr, EAGAIN);
127             EXPECT_EQ(0u, bwr.read_consumed);
128             for (i = 0; i * sizeof(uint32_t) < bwr.read_consumed; i++) {
129                 SCOPED_TRACE(testing::Message() << "i = " << i);
130                 EXPECT_EQ(BR_NOOP, br[i]);
131             }
132         }
binderWaitForReadData(int timeout_ms)133         void binderWaitForReadData(int timeout_ms) {
134             int ret;
135             pollfd pfd = pollfd();
136 
137             pfd.fd = m_binderFd;
138             pfd.events = POLLIN;
139             ret = poll(&pfd, 1, timeout_ms);
140             EXPECT_EQ(1, ret);
141         }
142     private:
143         int m_binderFd;
144 };
145 
TEST_F(BinderDriverInterfaceTest,Version)146 TEST_F(BinderDriverInterfaceTest, Version) {
147     struct binder_version version;
148     binderTestIoctl(BINDER_VERSION, &version);
149     ASSERT_EQ(BINDER_CURRENT_PROTOCOL_VERSION, version.protocol_version);
150 }
151 
TEST_F(BinderDriverInterfaceTest,OpenNoMmap)152 TEST_F(BinderDriverInterfaceTest, OpenNoMmap) {
153     int binderFd = open(BINDER_DEV_NAME, O_RDWR | O_NONBLOCK | O_CLOEXEC);
154     ASSERT_GE(binderFd, 0);
155     close(binderFd);
156 }
157 
TEST_F(BinderDriverInterfaceTest,WriteReadNull)158 TEST_F(BinderDriverInterfaceTest, WriteReadNull) {
159     binderTestIoctlErr1(BINDER_WRITE_READ, nullptr, EFAULT);
160 }
161 
TEST_F(BinderDriverInterfaceTest,SetIdleTimeoutNull)162 TEST_F(BinderDriverInterfaceTest, SetIdleTimeoutNull) {
163     binderTestIoctlErr2(BINDER_SET_IDLE_TIMEOUT, nullptr, EFAULT, EINVAL);
164 }
165 
TEST_F(BinderDriverInterfaceTest,SetMaxThreadsNull)166 TEST_F(BinderDriverInterfaceTest, SetMaxThreadsNull) {
167     binderTestIoctlErr2(BINDER_SET_MAX_THREADS, nullptr, EFAULT, EINVAL); /* TODO: don't accept EINVAL */
168 }
169 
TEST_F(BinderDriverInterfaceTest,SetIdlePriorityNull)170 TEST_F(BinderDriverInterfaceTest, SetIdlePriorityNull) {
171     binderTestIoctlErr2(BINDER_SET_IDLE_PRIORITY, nullptr, EFAULT, EINVAL);
172 }
173 
TEST_F(BinderDriverInterfaceTest,VersionNull)174 TEST_F(BinderDriverInterfaceTest, VersionNull) {
175     binderTestIoctlErr2(BINDER_VERSION, nullptr, EFAULT, EINVAL); /* TODO: don't accept EINVAL */
176 }
177 
TEST_F(BinderDriverInterfaceTest,SetIdleTimeoutNoTest)178 TEST_F(BinderDriverInterfaceTest, SetIdleTimeoutNoTest) {
179     int64_t idle_timeout = 100000;
180     binderTestIoctlUnimplemented(BINDER_SET_IDLE_TIMEOUT, &idle_timeout);
181 }
182 
TEST_F(BinderDriverInterfaceTest,SetMaxThreads)183 TEST_F(BinderDriverInterfaceTest, SetMaxThreads) {
184     uint32_t max_threads = 0;
185     binderTestIoctl(BINDER_SET_MAX_THREADS, &max_threads);
186 }
187 
TEST_F(BinderDriverInterfaceTest,SetIdlePriorityNoTest)188 TEST_F(BinderDriverInterfaceTest, SetIdlePriorityNoTest) {
189     int idle_priority = 0;
190     binderTestIoctlUnimplemented(BINDER_SET_IDLE_PRIORITY, &idle_priority);
191 }
192 
TEST_F(BinderDriverInterfaceTest,SetContextMgrBusy)193 TEST_F(BinderDriverInterfaceTest, SetContextMgrBusy) {
194     int32_t dummy = 0;
195     binderTestIoctlErr1(BINDER_SET_CONTEXT_MGR, &dummy, EBUSY);
196 }
197 
TEST_F(BinderDriverInterfaceTest,ThreadExit)198 TEST_F(BinderDriverInterfaceTest, ThreadExit) {
199     int32_t dummy = 0;
200     binderTestIoctl(BINDER_THREAD_EXIT, &dummy);
201     static_cast<BinderDriverInterfaceTestEnv *>(binder_env)->EnterLooper();
202 }
203 
TEST_F(BinderDriverInterfaceTest,WriteReadEmpty)204 TEST_F(BinderDriverInterfaceTest, WriteReadEmpty) {
205     struct binder_write_read bwr = binder_write_read();
206     binderTestIoctl(BINDER_WRITE_READ, &bwr);
207 }
208 
TEST_F(BinderDriverInterfaceTest,Read)209 TEST_F(BinderDriverInterfaceTest, Read) {
210     binderTestReadEmpty();
211 }
212 
TEST_F(BinderDriverInterfaceTest,IncRefsAcquireReleaseDecRefs)213 TEST_F(BinderDriverInterfaceTest, IncRefsAcquireReleaseDecRefs) {
214     const uint32_t bc[] = {
215         BC_INCREFS,
216         0,
217         BC_ACQUIRE,
218         0,
219         BC_RELEASE,
220         0,
221         BC_DECREFS,
222         0,
223     };
224     struct binder_write_read bwr = binder_write_read();
225     bwr.write_buffer = (uintptr_t)bc;
226     bwr.write_size = sizeof(bc);
227     binderTestIoctl(BINDER_WRITE_READ, &bwr);
228     EXPECT_EQ(sizeof(bc), bwr.write_consumed);
229     binderTestReadEmpty();
230 }
231 
TEST_F(BinderDriverInterfaceTest,Transaction)232 TEST_F(BinderDriverInterfaceTest, Transaction) {
233     binder_uintptr_t cookie = 1234;
234     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,
248             .data = {
249                 .ptr = {0, 0},
250             },
251         },
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 
262     bwr.write_buffer = (uintptr_t)&bc1;
263     bwr.write_size = sizeof(bc1);
264     bwr.read_buffer = (uintptr_t)&br;
265     bwr.read_size = sizeof(br);
266 
267     {
268         SCOPED_TRACE("1st WriteRead");
269         binderTestIoctlSuccessOrError(BINDER_WRITE_READ, &bwr, EAGAIN);
270     }
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)) {
285         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);
289         EXPECT_EQ(0u, br.arg2.data_size);
290         EXPECT_EQ(0u, br.arg2.offsets_size);
291 
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 
304         bwr.write_buffer = (uintptr_t)&bc2;
305         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 
TEST_F(BinderDriverInterfaceTest,RequestDeathNotification)315 TEST_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 
350     bwr.write_buffer = (uintptr_t)&bc;
351     bwr.write_size = sizeof(bc);
352     bwr.read_buffer = (uintptr_t)&br;
353     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 
main(int argc,char ** argv)364 int main(int argc, char **argv) {
365     ::testing::InitGoogleTest(&argc, argv);
366 
367     binder_env = AddGlobalTestEnvironment(new BinderDriverInterfaceTestEnv());
368 
369     return RUN_ALL_TESTS();
370 }
371