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 #include "binderAbiHelper.h"
29 
30 #define BINDER_DEV_NAME "/dev/binder"
31 
32 testing::Environment* binder_env;
33 
34 class BinderDriverInterfaceTestEnv : public ::testing::Environment {
SetUp()35         virtual void SetUp() {
36             int ret;
37             uint32_t max_threads = 0;
38 
39             m_binderFd = open(BINDER_DEV_NAME, O_RDWR | O_NONBLOCK | O_CLOEXEC);
40             ASSERT_GE(m_binderFd, 0);
41             m_buffer = mmap(nullptr, 64*1024, PROT_READ, MAP_SHARED, m_binderFd, 0);
42             ASSERT_NE(m_buffer, (void *)nullptr);
43             ret = ioctl(m_binderFd, BINDER_SET_MAX_THREADS, &max_threads);
44             EXPECT_EQ(0, ret);
45             EnterLooper();
46         }
TearDown()47         virtual void TearDown() {
48             close(m_binderFd);
49         }
50     private:
51         int m_binderFd;
52         void *m_buffer;
53     public:
getBinderFd(void)54         int getBinderFd(void) {
55             return m_binderFd;
56         }
EnterLooper(void)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();
63             bwr.write_buffer = (uintptr_t)bc;
64             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 
74 class BinderDriverInterfaceTest : public ::testing::Test {
75     public:
SetUp()76         virtual void SetUp() {
77             m_binderFd = static_cast<BinderDriverInterfaceTestEnv *>(binder_env)->getBinderFd();
78         }
TearDown()79         virtual void TearDown() {
80         }
81     protected:
82         /* The ioctl must either return 0, or if it doesn't errno should be accepted_errno */
binderTestIoctlSuccessOrError(int cmd,void * arg,int 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 
binderTestIoctlRetErr2(int cmd,void * arg,int expect_ret,int expect_errno,int accept_errno)92         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         }
binderTestIoctlErr2(int cmd,void * arg,int expect_errno,int accept_errno)102         void binderTestIoctlErr2(int cmd, void *arg, int expect_errno, int accept_errno) {
103             binderTestIoctlRetErr2(cmd, arg, -1, expect_errno, accept_errno);
104         }
binderTestIoctlErr1(int cmd,void * arg,int expect_errno)105         void binderTestIoctlErr1(int cmd, void *arg, int expect_errno) {
106             binderTestIoctlErr2(cmd, arg, expect_errno, expect_errno);
107         }
binderTestIoctl(int cmd,void * arg)108         void binderTestIoctl(int cmd, void *arg) {
109             binderTestIoctlRetErr2(cmd, arg, 0, 0, 0);
110         }
binderTestIoctlUnimplemented(int cmd,void * arg)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         }
binderTestReadEmpty(void)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");
126             bwr.read_buffer = (uintptr_t)br;
127             bwr.read_size = sizeof(br);
128             binderTestIoctlErr1(BINDER_WRITE_READ, &bwr, EAGAIN);
129             EXPECT_EQ(0u, bwr.read_consumed);
130             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         }
binderWaitForReadData(int timeout_ms)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 
TEST_F(BinderDriverInterfaceTest,Version)148 TEST_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 
TEST_F(BinderDriverInterfaceTest,OpenNoMmap)154 TEST_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 
TEST_F(BinderDriverInterfaceTest,WriteReadNull)160 TEST_F(BinderDriverInterfaceTest, WriteReadNull) {
161     binderTestIoctlErr1(BINDER_WRITE_READ, nullptr, EFAULT);
162 }
163 
TEST_F(BinderDriverInterfaceTest,SetIdleTimeoutNull)164 TEST_F(BinderDriverInterfaceTest, SetIdleTimeoutNull) {
165     binderTestIoctlErr2(BINDER_SET_IDLE_TIMEOUT, nullptr, EFAULT, EINVAL);
166 }
167 
TEST_F(BinderDriverInterfaceTest,SetMaxThreadsNull)168 TEST_F(BinderDriverInterfaceTest, SetMaxThreadsNull) {
169     binderTestIoctlErr2(BINDER_SET_MAX_THREADS, nullptr, EFAULT, EINVAL); /* TODO: don't accept EINVAL */
170 }
171 
TEST_F(BinderDriverInterfaceTest,SetIdlePriorityNull)172 TEST_F(BinderDriverInterfaceTest, SetIdlePriorityNull) {
173     binderTestIoctlErr2(BINDER_SET_IDLE_PRIORITY, nullptr, EFAULT, EINVAL);
174 }
175 
TEST_F(BinderDriverInterfaceTest,VersionNull)176 TEST_F(BinderDriverInterfaceTest, VersionNull) {
177     binderTestIoctlErr2(BINDER_VERSION, nullptr, EFAULT, EINVAL); /* TODO: don't accept EINVAL */
178 }
179 
TEST_F(BinderDriverInterfaceTest,SetIdleTimeoutNoTest)180 TEST_F(BinderDriverInterfaceTest, SetIdleTimeoutNoTest) {
181     int64_t idle_timeout = 100000;
182     binderTestIoctlUnimplemented(BINDER_SET_IDLE_TIMEOUT, &idle_timeout);
183 }
184 
TEST_F(BinderDriverInterfaceTest,SetMaxThreads)185 TEST_F(BinderDriverInterfaceTest, SetMaxThreads) {
186     uint32_t max_threads = 0;
187     binderTestIoctl(BINDER_SET_MAX_THREADS, &max_threads);
188 }
189 
TEST_F(BinderDriverInterfaceTest,SetIdlePriorityNoTest)190 TEST_F(BinderDriverInterfaceTest, SetIdlePriorityNoTest) {
191     int idle_priority = 0;
192     binderTestIoctlUnimplemented(BINDER_SET_IDLE_PRIORITY, &idle_priority);
193 }
194 
TEST_F(BinderDriverInterfaceTest,SetContextMgrBusy)195 TEST_F(BinderDriverInterfaceTest, SetContextMgrBusy) {
196     int32_t dummy = 0;
197     binderTestIoctlErr1(BINDER_SET_CONTEXT_MGR, &dummy, EBUSY);
198 }
199 
TEST_F(BinderDriverInterfaceTest,ThreadExit)200 TEST_F(BinderDriverInterfaceTest, ThreadExit) {
201     int32_t dummy = 0;
202     binderTestIoctl(BINDER_THREAD_EXIT, &dummy);
203     static_cast<BinderDriverInterfaceTestEnv *>(binder_env)->EnterLooper();
204 }
205 
TEST_F(BinderDriverInterfaceTest,WriteReadEmpty)206 TEST_F(BinderDriverInterfaceTest, WriteReadEmpty) {
207     struct binder_write_read bwr = binder_write_read();
208     binderTestIoctl(BINDER_WRITE_READ, &bwr);
209 }
210 
TEST_F(BinderDriverInterfaceTest,Read)211 TEST_F(BinderDriverInterfaceTest, Read) {
212     binderTestReadEmpty();
213 }
214 
TEST_F(BinderDriverInterfaceTest,IncRefsAcquireReleaseDecRefs)215 TEST_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();
227     bwr.write_buffer = (uintptr_t)bc;
228     bwr.write_size = sizeof(bc);
229     binderTestIoctl(BINDER_WRITE_READ, &bwr);
230     EXPECT_EQ(sizeof(bc), bwr.write_consumed);
231     binderTestReadEmpty();
232 }
233 
TEST_F(BinderDriverInterfaceTest,Transaction)234 TEST_F(BinderDriverInterfaceTest, Transaction) {
235     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,
249             .data = {
250                 .ptr = {0, 0},
251             },
252         },
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 
263     bwr.write_buffer = (uintptr_t)&bc1;
264     bwr.write_size = sizeof(bc1);
265     bwr.read_buffer = (uintptr_t)&br;
266     bwr.read_size = sizeof(br);
267 
268     {
269         SCOPED_TRACE("1st WriteRead");
270         binderTestIoctlSuccessOrError(BINDER_WRITE_READ, &bwr, EAGAIN);
271     }
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)) {
286         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);
290         EXPECT_EQ(0u, br.arg2.data_size);
291         EXPECT_EQ(0u, br.arg2.offsets_size);
292 
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 
305         bwr.write_buffer = (uintptr_t)&bc2;
306         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 
TEST_F(BinderDriverInterfaceTest,RequestDeathNotification)316 TEST_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 
351     bwr.write_buffer = (uintptr_t)&bc;
352     bwr.write_size = sizeof(bc);
353     bwr.read_buffer = (uintptr_t)&br;
354     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 
main(int argc,char ** argv)365 int main(int argc, char **argv) {
366     ExitIfWrongAbi();
367     ::testing::InitGoogleTest(&argc, argv);
368 
369     binder_env = AddGlobalTestEnvironment(new BinderDriverInterfaceTestEnv());
370 
371     return RUN_ALL_TESTS();
372 }
373