• 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(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 = {
233                 .ptr = {0, 0},
234             },
235         },
236     };
237     struct {
238         uint32_t cmd0;
239         uint32_t cmd1;
240         uint32_t cmd2;
241         binder_transaction_data arg2;
242         uint32_t pad[16];
243     } __attribute__((packed)) br;
244     struct binder_write_read bwr = binder_write_read();
245 
246     bwr.write_buffer = (uintptr_t)&bc1;
247     bwr.write_size = sizeof(bc1);
248     bwr.read_buffer = (uintptr_t)&br;
249     bwr.read_size = sizeof(br);
250 
251     {
252         SCOPED_TRACE("1st WriteRead");
253         binderTestIoctl(BINDER_WRITE_READ, &bwr);
254     }
255     EXPECT_EQ(sizeof(bc1), bwr.write_consumed);
256     if (bwr.read_consumed < offsetof(typeof(br), pad)) {
257         SCOPED_TRACE("2nd WriteRead");
258         binderWaitForReadData(10000);
259         binderTestIoctl(BINDER_WRITE_READ, &bwr);
260     }
261     EXPECT_EQ(offsetof(typeof(br), pad), bwr.read_consumed);
262     if (bwr.read_consumed > offsetof(typeof(br), cmd0))
263         EXPECT_EQ(BR_NOOP, br.cmd0);
264     if (bwr.read_consumed > offsetof(typeof(br), cmd1))
265         EXPECT_EQ(BR_TRANSACTION_COMPLETE, br.cmd1);
266     if (bwr.read_consumed > offsetof(typeof(br), cmd2))
267         EXPECT_EQ(BR_REPLY, br.cmd2);
268     if (bwr.read_consumed >= offsetof(typeof(br), pad)) {
269         EXPECT_EQ(0u, br.arg2.target.ptr);
270         EXPECT_EQ(0u, br.arg2.cookie);
271         EXPECT_EQ(0u, br.arg2.code);
272         EXPECT_EQ(0u, br.arg2.flags);
273         EXPECT_EQ(0u, br.arg2.data_size);
274         EXPECT_EQ(0u, br.arg2.offsets_size);
275 
276         SCOPED_TRACE("3rd WriteRead");
277 
278         binderTestReadEmpty();
279 
280         struct {
281             uint32_t cmd1;
282             binder_uintptr_t arg1;
283         } __attribute__((packed)) bc2 = {
284             .cmd1 = BC_FREE_BUFFER,
285             .arg1 = br.arg2.data.ptr.buffer,
286         };
287 
288         bwr.write_buffer = (uintptr_t)&bc2;
289         bwr.write_size = sizeof(bc2);
290         bwr.write_consumed = 0;
291         bwr.read_size = 0;
292 
293         binderTestIoctl(BINDER_WRITE_READ, &bwr);
294         EXPECT_EQ(sizeof(bc2), bwr.write_consumed);
295     }
296     binderTestReadEmpty();
297 }
298 
TEST_F(BinderDriverInterfaceTest,RequestDeathNotification)299 TEST_F(BinderDriverInterfaceTest, RequestDeathNotification) {
300     binder_uintptr_t cookie = 1234;
301     struct {
302         uint32_t cmd0;
303         uint32_t arg0;
304         uint32_t cmd1;
305         struct binder_handle_cookie arg1;
306         uint32_t cmd2;
307         struct binder_handle_cookie arg2;
308         uint32_t cmd3;
309         uint32_t arg3;
310     } __attribute__((packed)) bc = {
311         .cmd0 = BC_INCREFS,
312         .arg0 = 0,
313         .cmd1 = BC_REQUEST_DEATH_NOTIFICATION,
314         .arg1 = {
315             .handle = 0,
316             .cookie = cookie,
317         },
318         .cmd2 = BC_CLEAR_DEATH_NOTIFICATION,
319         .arg2 = {
320             .handle = 0,
321             .cookie = cookie,
322         },
323         .cmd3 = BC_DECREFS,
324         .arg3 = 0,
325     };
326     struct {
327         uint32_t cmd0;
328         uint32_t cmd1;
329         binder_uintptr_t arg1;
330         uint32_t pad[16];
331     } __attribute__((packed)) br;
332     struct binder_write_read bwr = binder_write_read();
333 
334     bwr.write_buffer = (uintptr_t)&bc;
335     bwr.write_size = sizeof(bc);
336     bwr.read_buffer = (uintptr_t)&br;
337     bwr.read_size = sizeof(br);
338 
339     binderTestIoctl(BINDER_WRITE_READ, &bwr);
340     EXPECT_EQ(sizeof(bc), bwr.write_consumed);
341     EXPECT_EQ(sizeof(br) - sizeof(br.pad), bwr.read_consumed);
342     EXPECT_EQ(BR_NOOP, br.cmd0);
343     EXPECT_EQ(BR_CLEAR_DEATH_NOTIFICATION_DONE, br.cmd1);
344     EXPECT_EQ(cookie, br.arg1);
345     binderTestReadEmpty();
346 }
347 
main(int argc,char ** argv)348 int main(int argc, char **argv) {
349     ::testing::InitGoogleTest(&argc, argv);
350 
351     binder_env = AddGlobalTestEnvironment(new BinderDriverInterfaceTestEnv());
352 
353     return RUN_ALL_TESTS();
354 }
355