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 30testing::Environment* binder_env; 31 32class BinderDriverInterfaceTestEnv : public ::testing::Environment { 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 } 45 virtual void TearDown() { 46 close(m_binderFd); 47 } 48 private: 49 int m_binderFd; 50 void *m_buffer; 51 public: 52 int getBinderFd(void) { 53 return m_binderFd; 54 } 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 72class BinderDriverInterfaceTest : public ::testing::Test { 73 public: 74 virtual void SetUp() { 75 m_binderFd = static_cast<BinderDriverInterfaceTestEnv *>(binder_env)->getBinderFd(); 76 } 77 virtual void TearDown() { 78 } 79 protected: 80 /* The ioctl must either return 0, or if it doesn't errno should be 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 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 } 100 void binderTestIoctlErr2(int cmd, void *arg, int expect_errno, int accept_errno) { 101 binderTestIoctlRetErr2(cmd, arg, -1, expect_errno, accept_errno); 102 } 103 void binderTestIoctlErr1(int cmd, void *arg, int expect_errno) { 104 binderTestIoctlErr2(cmd, arg, expect_errno, expect_errno); 105 } 106 void binderTestIoctl(int cmd, void *arg) { 107 binderTestIoctlRetErr2(cmd, arg, 0, 0, 0); 108 } 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 } 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 } 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 146TEST_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 152TEST_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 158TEST_F(BinderDriverInterfaceTest, WriteReadNull) { 159 binderTestIoctlErr1(BINDER_WRITE_READ, NULL, EFAULT); 160} 161 162TEST_F(BinderDriverInterfaceTest, SetIdleTimeoutNull) { 163 binderTestIoctlErr2(BINDER_SET_IDLE_TIMEOUT, NULL, EFAULT, EINVAL); 164} 165 166TEST_F(BinderDriverInterfaceTest, SetMaxThreadsNull) { 167 binderTestIoctlErr2(BINDER_SET_MAX_THREADS, NULL, EFAULT, EINVAL); /* TODO: don't accept EINVAL */ 168} 169 170TEST_F(BinderDriverInterfaceTest, SetIdlePriorityNull) { 171 binderTestIoctlErr2(BINDER_SET_IDLE_PRIORITY, NULL, EFAULT, EINVAL); 172} 173 174TEST_F(BinderDriverInterfaceTest, VersionNull) { 175 binderTestIoctlErr2(BINDER_VERSION, NULL, EFAULT, EINVAL); /* TODO: don't accept EINVAL */ 176} 177 178TEST_F(BinderDriverInterfaceTest, SetIdleTimeoutNoTest) { 179 int64_t idle_timeout = 100000; 180 binderTestIoctlUnimplemented(BINDER_SET_IDLE_TIMEOUT, &idle_timeout); 181} 182 183TEST_F(BinderDriverInterfaceTest, SetMaxThreads) { 184 uint32_t max_threads = 0; 185 binderTestIoctl(BINDER_SET_MAX_THREADS, &max_threads); 186} 187 188TEST_F(BinderDriverInterfaceTest, SetIdlePriorityNoTest) { 189 int idle_priority = 0; 190 binderTestIoctlUnimplemented(BINDER_SET_IDLE_PRIORITY, &idle_priority); 191} 192 193TEST_F(BinderDriverInterfaceTest, SetContextMgrBusy) { 194 int32_t dummy = 0; 195 binderTestIoctlErr1(BINDER_SET_CONTEXT_MGR, &dummy, EBUSY); 196} 197 198TEST_F(BinderDriverInterfaceTest, ThreadExit) { 199 int32_t dummy = 0; 200 binderTestIoctl(BINDER_THREAD_EXIT, &dummy); 201 static_cast<BinderDriverInterfaceTestEnv *>(binder_env)->EnterLooper(); 202} 203 204TEST_F(BinderDriverInterfaceTest, WriteReadEmpty) { 205 struct binder_write_read bwr = binder_write_read(); 206 binderTestIoctl(BINDER_WRITE_READ, &bwr); 207} 208 209TEST_F(BinderDriverInterfaceTest, Read) { 210 binderTestReadEmpty(); 211} 212 213TEST_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 232TEST_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 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 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 364int 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