1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // The linux host build of nacl_io can't do wrapping of syscalls so all 6 // these tests must be disabled. 7 #if !defined(__linux__) 8 9 #include <unistd.h> 10 11 #include <string> 12 #include <vector> 13 14 #include "gtest/gtest.h" 15 #include "mock_kernel_proxy.h" 16 #include "nacl_io/kernel_intercept.h" 17 #include "nacl_io/kernel_wrap.h" 18 #include "nacl_io/kernel_wrap_real.h" 19 #include "nacl_io/osmman.h" 20 #include "nacl_io/ossocket.h" 21 #include "nacl_io/ostermios.h" 22 #include "nacl_io/ostime.h" 23 #include "ppapi_simple/ps.h" 24 25 #if defined(__native_client__) && !defined(__GLIBC__) 26 extern "C" { 27 // TODO(sbc): remove once this gets added to the newlib toolchain headers. 28 int fchdir(int fd); 29 } 30 #endif 31 32 using namespace nacl_io; 33 34 using ::testing::_; 35 using ::testing::AnyNumber; 36 using ::testing::DoAll; 37 using ::testing::Invoke; 38 using ::testing::Return; 39 using ::testing::StrEq; 40 41 namespace { 42 43 #define COMPARE_FIELD(actual, expected, f) \ 44 if (actual != expected) { \ 45 *result_listener << "mismatch of field \"" f \ 46 "\". " \ 47 "expected: " << expected << " actual: " << actual; \ 48 return false; \ 49 } 50 51 #define COMPARE_FIELD_SIMPLE(f) COMPARE_FIELD(arg->f, other->f, #f) 52 53 MATCHER_P(IsEqualToStatbuf, other, "") { 54 COMPARE_FIELD_SIMPLE(st_dev); 55 COMPARE_FIELD_SIMPLE(st_ino); 56 COMPARE_FIELD_SIMPLE(st_mode); 57 COMPARE_FIELD_SIMPLE(st_nlink); 58 COMPARE_FIELD_SIMPLE(st_uid); 59 COMPARE_FIELD_SIMPLE(st_gid); 60 COMPARE_FIELD_SIMPLE(st_rdev); 61 COMPARE_FIELD_SIMPLE(st_size); 62 COMPARE_FIELD_SIMPLE(st_atime); 63 COMPARE_FIELD_SIMPLE(st_mtime); 64 COMPARE_FIELD_SIMPLE(st_ctime); 65 return true; 66 } 67 68 MATCHER_P(IsEqualToUtimbuf, other, "") { 69 COMPARE_FIELD(arg[0].tv_sec, other->actime, "actime"); 70 COMPARE_FIELD(arg[1].tv_sec, other->modtime, "modtime"); 71 return true; 72 } 73 74 MATCHER_P(IsEqualToTimeval, other, "") { 75 COMPARE_FIELD(arg[0].tv_sec, other[0].tv_sec, "[0].tv_sec"); 76 COMPARE_FIELD(arg[0].tv_nsec, other[0].tv_usec * 1000, "[0].tv_usec"); 77 COMPARE_FIELD(arg[1].tv_sec, other[1].tv_sec, "[1].tv_sec"); 78 COMPARE_FIELD(arg[1].tv_nsec, other[1].tv_usec * 1000, "[1].tv_usec"); 79 return true; 80 } 81 82 #undef COMPARE_FIELD 83 #undef COMPARE_FIELD_SIMPLE 84 85 86 ACTION_P(SetErrno, value) { 87 errno = value; 88 } 89 90 ACTION_P2(SetString, target, source) { 91 strcpy(target, source); 92 } 93 94 ACTION_P(SetStat, statbuf) { 95 memset(arg1, 0, sizeof(struct stat)); 96 arg1->st_dev = statbuf->st_dev; 97 arg1->st_ino = statbuf->st_ino; 98 arg1->st_mode = statbuf->st_mode; 99 arg1->st_nlink = statbuf->st_nlink; 100 arg1->st_uid = statbuf->st_uid; 101 arg1->st_gid = statbuf->st_gid; 102 arg1->st_rdev = statbuf->st_rdev; 103 arg1->st_size = statbuf->st_size; 104 arg1->st_atime = statbuf->st_atime; 105 arg1->st_mtime = statbuf->st_mtime; 106 arg1->st_ctime = statbuf->st_ctime; 107 } 108 109 void MakeDummyStatbuf(struct stat* statbuf) { 110 memset(&statbuf[0], 0, sizeof(struct stat)); 111 statbuf->st_dev = 1; 112 statbuf->st_ino = 2; 113 statbuf->st_mode = 3; 114 statbuf->st_nlink = 4; 115 statbuf->st_uid = 5; 116 statbuf->st_gid = 6; 117 statbuf->st_rdev = 7; 118 statbuf->st_size = 8; 119 statbuf->st_atime = 9; 120 statbuf->st_mtime = 10; 121 statbuf->st_ctime = 11; 122 } 123 124 const mode_t kDummyMode = 0xbeef; 125 const int kDummyErrno = 0xfeeb; 126 const int kDummyInt = 0xdedbeef; 127 const int kDummyInt2 = 0xcabba6e; 128 const int kDummyInt3 = 0xf00ba4; 129 const int kDummyInt4 = 0xabacdba; 130 const size_t kDummySizeT = 0x60067e; 131 const char* kDummyConstChar = "foobar"; 132 const char* kDummyConstChar2 = "g00gl3"; 133 const char* kDummyConstChar3 = "fr00gl3"; 134 const void* kDummyVoidPtr = "blahblah"; 135 const uid_t kDummyUid = 1001; 136 const gid_t kDummyGid = 1002; 137 138 class KernelWrapTest : public ::testing::Test { 139 public: 140 KernelWrapTest() {} 141 142 virtual void SetUp() { 143 // Initialize the global errno value to a consistent value rather than 144 // relying on its value from previous test runs. 145 errno = 0; 146 147 // Initializing the KernelProxy opens stdin/stdout/stderr. 148 EXPECT_CALL(mock, open(_, _, _)) 149 .WillOnce(Return(0)) 150 .WillOnce(Return(1)) 151 .WillOnce(Return(2)); 152 153 ASSERT_EQ(0, ki_push_state_for_testing()); 154 ASSERT_EQ(0, ki_init(&mock)); 155 156 // We allow write to be called any number of times, and it forwards to 157 // _real_write. This prevents an infinite loop writing output if there is a 158 // failure. 159 ON_CALL(mock, write(_, _, _)) 160 .WillByDefault(Invoke(this, &KernelWrapTest::DefaultWrite)); 161 EXPECT_CALL(mock, write(_, _, _)).Times(AnyNumber()); 162 } 163 164 void TearDown() { 165 // Uninitialize the kernel proxy so wrapped functions passthrough to their 166 // unwrapped versions. 167 ki_uninit(); 168 } 169 170 MockKernelProxy mock; 171 172 private: 173 ssize_t DefaultWrite(int fd, const void* buf, size_t count) { 174 assert(fd <= 2); 175 size_t nwrote; 176 int rtn = _real_write(fd, buf, count, &nwrote); 177 if (rtn != 0) { 178 errno = rtn; 179 return -1; 180 } 181 return nwrote; 182 } 183 }; 184 185 } // namespace 186 187 TEST_F(KernelWrapTest, access) { 188 EXPECT_CALL(mock, access(kDummyConstChar, kDummyInt)) .WillOnce(Return(0)); 189 EXPECT_EQ(0, access(kDummyConstChar, kDummyInt)); 190 191 EXPECT_CALL(mock, access(kDummyConstChar, kDummyInt)) 192 .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1))); 193 EXPECT_EQ(-1, access(kDummyConstChar, kDummyInt)); 194 EXPECT_EQ(kDummyErrno, errno); 195 196 } 197 198 TEST_F(KernelWrapTest, chdir) { 199 EXPECT_CALL(mock, chdir(kDummyConstChar)).WillOnce(Return(0)); 200 EXPECT_EQ(0, chdir(kDummyConstChar)); 201 202 EXPECT_CALL(mock, chdir(kDummyConstChar)) 203 .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1))); 204 EXPECT_EQ(-1, chdir(kDummyConstChar)); 205 ASSERT_EQ(kDummyErrno, errno); 206 } 207 208 TEST_F(KernelWrapTest, chmod) { 209 EXPECT_CALL(mock, chmod(kDummyConstChar, kDummyMode)) 210 .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1))); 211 EXPECT_EQ(-1, chmod(kDummyConstChar, kDummyMode)); 212 ASSERT_EQ(kDummyErrno, errno); 213 } 214 215 TEST_F(KernelWrapTest, chown) { 216 EXPECT_CALL(mock, chown(kDummyConstChar, kDummyUid, kDummyGid)) 217 .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1))); 218 EXPECT_EQ(-1, chown(kDummyConstChar, kDummyUid, kDummyGid)); 219 ASSERT_EQ(kDummyErrno, errno); 220 } 221 222 TEST_F(KernelWrapTest, close) { 223 // The way we wrap close does not support returning arbitrary values, so we 224 // test 0 and -1. 225 EXPECT_CALL(mock, close(kDummyInt)) 226 .WillOnce(Return(0)); 227 228 EXPECT_EQ(0, close(kDummyInt)); 229 230 EXPECT_CALL(mock, close(kDummyInt)) 231 .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1))); 232 EXPECT_EQ(-1, close(kDummyInt)); 233 ASSERT_EQ(kDummyErrno, errno); 234 } 235 236 TEST_F(KernelWrapTest, dup) { 237 EXPECT_CALL(mock, dup(kDummyInt)).WillOnce(Return(kDummyInt2)); 238 EXPECT_EQ(kDummyInt2, dup(kDummyInt)); 239 } 240 241 TEST_F(KernelWrapTest, dup2) { 242 // The way we wrap dup2 does not support returning aribtrary values, only -1 243 // or the value of the new fd. 244 EXPECT_CALL(mock, dup2(kDummyInt, kDummyInt2)) 245 .WillOnce(Return(kDummyInt2)) 246 .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1))); 247 248 EXPECT_EQ(kDummyInt2, dup2(kDummyInt, kDummyInt2)); 249 EXPECT_EQ(-1, dup2(kDummyInt, kDummyInt2)); 250 ASSERT_EQ(kDummyErrno, errno); 251 } 252 253 TEST_F(KernelWrapTest, fchdir) { 254 EXPECT_CALL(mock, fchdir(kDummyInt)) 255 .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1))); 256 257 EXPECT_EQ(-1, fchdir(kDummyInt)); 258 ASSERT_EQ(kDummyErrno, errno); 259 } 260 261 TEST_F(KernelWrapTest, fchmod) { 262 EXPECT_CALL(mock, fchmod(kDummyInt, kDummyMode)) 263 .WillOnce(Return(0)) 264 .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1))); 265 266 EXPECT_EQ(0, fchmod(kDummyInt, kDummyMode)); 267 EXPECT_EQ(-1, fchmod(kDummyInt, kDummyMode)); 268 ASSERT_EQ(kDummyErrno, errno); 269 } 270 271 TEST_F(KernelWrapTest, fchown) { 272 EXPECT_CALL(mock, fchown(kDummyInt, kDummyUid, kDummyGid)) 273 .WillOnce(Return(kDummyInt)); 274 EXPECT_EQ(kDummyInt, fchown(kDummyInt, kDummyUid, kDummyGid)); 275 } 276 277 TEST_F(KernelWrapTest, fcntl) { 278 char buffer[] = "fcntl"; 279 EXPECT_CALL(mock, fcntl(kDummyInt, kDummyInt2, _)) 280 .WillOnce(Return(kDummyInt3)); 281 EXPECT_EQ(kDummyInt3, fcntl(kDummyInt, kDummyInt2, buffer)); 282 } 283 284 TEST_F(KernelWrapTest, fdatasync) { 285 EXPECT_CALL(mock, fdatasync(kDummyInt)).WillOnce(Return(0)) 286 .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1))); 287 288 EXPECT_EQ(0, fdatasync(kDummyInt)); 289 EXPECT_EQ(-1, fdatasync(kDummyInt)); 290 ASSERT_EQ(kDummyErrno, errno); 291 } 292 293 TEST_F(KernelWrapTest, fstat) { 294 // The way we wrap fstat does not support returning aribtrary values, only 0 295 // or -1. 296 struct stat in_statbuf; 297 MakeDummyStatbuf(&in_statbuf); 298 EXPECT_CALL(mock, fstat(kDummyInt, _)) 299 .WillOnce(DoAll(SetStat(&in_statbuf), Return(0))) 300 .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1))); 301 struct stat out_statbuf; 302 303 EXPECT_EQ(0, fstat(kDummyInt, &out_statbuf)); 304 EXPECT_THAT(&in_statbuf, IsEqualToStatbuf(&out_statbuf)); 305 306 EXPECT_EQ(-1, fstat(kDummyInt, &out_statbuf)); 307 ASSERT_EQ(kDummyErrno, errno); 308 } 309 310 TEST_F(KernelWrapTest, ftruncate) { 311 EXPECT_CALL(mock, ftruncate(kDummyInt, kDummyInt2)) 312 .WillOnce(Return(kDummyInt3)); 313 EXPECT_EQ(kDummyInt3, ftruncate(kDummyInt, kDummyInt2)); 314 } 315 316 TEST_F(KernelWrapTest, fsync) { 317 EXPECT_CALL(mock, fsync(kDummyInt)) 318 .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1))); 319 EXPECT_EQ(-1, fsync(kDummyInt)); 320 ASSERT_EQ(kDummyErrno, errno); 321 } 322 323 TEST_F(KernelWrapTest, futimes) { 324 struct timeval times[2] = {{123, 234}, {345, 456}}; 325 EXPECT_CALL(mock, futimens(kDummyInt, IsEqualToTimeval(times))) 326 .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1))); 327 EXPECT_EQ(-1, futimes(kDummyInt, times)); 328 ASSERT_EQ(kDummyErrno, errno); 329 } 330 331 TEST_F(KernelWrapTest, getcwd) { 332 char buffer[PATH_MAX]; 333 char result[PATH_MAX]; 334 memset(buffer, 0, PATH_MAX); 335 strcpy(result, "getcwd_result"); 336 EXPECT_CALL(mock, getcwd(buffer, kDummySizeT)) 337 .WillOnce(DoAll(SetString(buffer, result), Return(buffer))); 338 EXPECT_STREQ(result, getcwd(buffer, kDummySizeT)); 339 } 340 341 TEST_F(KernelWrapTest, getdents) { 342 #if !defined( __GLIBC__) && !defined(__BIONIC__) 343 // TODO(sbc): Find a way to test the getdents wrapper under glibc. 344 // It looks like the only way to exercise it is to call readdir(2). 345 // There is an internal glibc function __getdents that will call the 346 // IRT but that cannot be accessed from here as glibc does not export it. 347 int dummy_val; 348 void* void_ptr = &dummy_val; 349 EXPECT_CALL(mock, getdents(kDummyInt, void_ptr, kDummyInt2)) 350 .WillOnce(Return(kDummyInt2)); 351 EXPECT_EQ(kDummyInt2, getdents(kDummyInt, void_ptr, kDummyInt2)); 352 #endif 353 } 354 355 // gcc gives error: getwd is deprecated. 356 #if defined(__GNUC__) 357 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 358 #endif 359 TEST_F(KernelWrapTest, getwd) { 360 char result[] = "getwd_result"; 361 char buffer[] = "getwd"; 362 EXPECT_CALL(mock, getwd(buffer)).WillOnce(Return(result)); 363 EXPECT_EQ(result, getwd(buffer)); 364 } 365 #if defined(__GNUC__) 366 #pragma GCC diagnostic warning "-Wdeprecated-declarations" 367 #endif 368 369 TEST_F(KernelWrapTest, ioctl) { 370 char buffer[] = "ioctl"; 371 EXPECT_CALL(mock, ioctl(kDummyInt, kDummyInt2, _)) 372 .WillOnce(Return(kDummyInt3)); 373 EXPECT_EQ(kDummyInt3, ioctl(kDummyInt, kDummyInt2, buffer)); 374 } 375 376 #if !defined(__BIONIC__) 377 TEST_F(KernelWrapTest, isatty) { 378 EXPECT_CALL(mock, isatty(kDummyInt)).WillOnce(Return(kDummyInt2)); 379 EXPECT_EQ(kDummyInt2, isatty(kDummyInt)); 380 381 // This test verifies that the IRT interception wrapper for isatty 382 // ignores the value of errno when isatty() returns 1. We had a bug 383 // where returning 1 from ki_isatty resulted in errno being returned 384 // by the IRT interface. 385 errno = kDummyInt3; 386 EXPECT_CALL(mock, isatty(kDummyInt)).WillOnce(Return(1)); 387 EXPECT_EQ(1, isatty(kDummyInt)); 388 } 389 #endif 390 391 TEST_F(KernelWrapTest, kill) { 392 EXPECT_CALL(mock, kill(kDummyInt, kDummyInt2)).WillOnce(Return(kDummyInt3)); 393 EXPECT_EQ(kDummyInt3, kill(kDummyInt, kDummyInt2)); 394 } 395 396 TEST_F(KernelWrapTest, lchown) { 397 EXPECT_CALL(mock, lchown(kDummyConstChar, kDummyUid, kDummyGid)) 398 .WillOnce(Return(kDummyInt)); 399 EXPECT_EQ(kDummyInt, lchown(kDummyConstChar, kDummyUid, kDummyGid)); 400 } 401 402 TEST_F(KernelWrapTest, link) { 403 EXPECT_CALL(mock, link(kDummyConstChar, kDummyConstChar2)) 404 .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1))); 405 EXPECT_EQ(-1, link(kDummyConstChar, kDummyConstChar2)); 406 ASSERT_EQ(kDummyErrno, errno); 407 } 408 409 TEST_F(KernelWrapTest, lseek) { 410 EXPECT_CALL(mock, lseek(kDummyInt, kDummyInt2, kDummyInt3)) 411 .WillOnce(Return(kDummyInt4)); 412 EXPECT_EQ(kDummyInt4, lseek(kDummyInt, kDummyInt2, kDummyInt3)); 413 } 414 415 TEST_F(KernelWrapTest, mkdir) { 416 #if defined(WIN32) 417 EXPECT_CALL(mock, mkdir(kDummyConstChar, 0777)).WillOnce(Return(kDummyInt2)); 418 EXPECT_EQ(kDummyInt2, mkdir(kDummyConstChar)); 419 #else 420 EXPECT_CALL(mock, mkdir(kDummyConstChar, kDummyMode)) 421 .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1))); 422 EXPECT_EQ(-1, mkdir(kDummyConstChar, kDummyMode)); 423 ASSERT_EQ(kDummyErrno, errno); 424 #endif 425 } 426 427 TEST_F(KernelWrapTest, mmap) { 428 // We only wrap mmap if |flags| has the MAP_ANONYMOUS bit unset. 429 int flags = kDummyInt2 & ~MAP_ANONYMOUS; 430 431 const size_t kDummySizeT2 = 0xbadf00d; 432 int dummy1 = 123; 433 int dummy2 = 456; 434 void* kDummyVoidPtr1 = &dummy1; 435 void* kDummyVoidPtr2 = &dummy2; 436 EXPECT_CALL(mock, 437 mmap(kDummyVoidPtr1, 438 kDummySizeT, 439 kDummyInt, 440 flags, 441 kDummyInt3, 442 kDummySizeT2)).WillOnce(Return(kDummyVoidPtr2)); 443 EXPECT_EQ(kDummyVoidPtr2, 444 mmap(kDummyVoidPtr1, 445 kDummySizeT, 446 kDummyInt, 447 flags, 448 kDummyInt3, 449 kDummySizeT2)); 450 } 451 452 TEST_F(KernelWrapTest, mount) { 453 EXPECT_CALL(mock, 454 mount(kDummyConstChar, 455 kDummyConstChar2, 456 kDummyConstChar3, 457 kDummyInt, 458 kDummyVoidPtr)).WillOnce(Return(kDummyInt2)); 459 EXPECT_EQ(kDummyInt2, 460 mount(kDummyConstChar, 461 kDummyConstChar2, 462 kDummyConstChar3, 463 kDummyInt, 464 kDummyVoidPtr)); 465 } 466 467 TEST_F(KernelWrapTest, munmap) { 468 // The way we wrap munmap, calls the "real" mmap as well as the intercepted 469 // one. The result returned is from the "real" mmap. 470 int dummy1 = 123; 471 void* kDummyVoidPtr = &dummy1; 472 size_t kDummySizeT = sizeof(kDummyVoidPtr); 473 EXPECT_CALL(mock, munmap(kDummyVoidPtr, kDummySizeT)); 474 munmap(kDummyVoidPtr, kDummySizeT); 475 } 476 477 TEST_F(KernelWrapTest, open) { 478 // We pass O_RDONLY because we do not want an error in flags translation 479 EXPECT_CALL(mock, open(kDummyConstChar, 0, 0)) 480 .WillOnce(Return(kDummyInt2)) 481 .WillOnce(Return(kDummyInt2)); 482 483 EXPECT_EQ(kDummyInt2, open(kDummyConstChar, 0, 0)); 484 EXPECT_EQ(kDummyInt2, open(kDummyConstChar, 0, 0)); 485 } 486 487 TEST_F(KernelWrapTest, pipe) { 488 int fds[] = {1, 2}; 489 EXPECT_CALL(mock, pipe(fds)).WillOnce(Return(kDummyInt)); 490 EXPECT_EQ(kDummyInt, pipe(fds)); 491 } 492 493 TEST_F(KernelWrapTest, read) { 494 int dummy_value; 495 void* dummy_void_ptr = &dummy_value; 496 EXPECT_CALL(mock, read(kDummyInt, dummy_void_ptr, kDummyInt2)) 497 .WillOnce(Return(kDummyInt3)); 498 EXPECT_EQ(kDummyInt3, read(kDummyInt, dummy_void_ptr, kDummyInt2)); 499 } 500 501 TEST_F(KernelWrapTest, readlink) { 502 char buf[10]; 503 504 EXPECT_CALL(mock, readlink(kDummyConstChar, buf, 10)) 505 .WillOnce(Return(kDummyInt)) 506 .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1))); 507 508 EXPECT_EQ(kDummyInt, readlink(kDummyConstChar, buf, 10)); 509 EXPECT_EQ(-1, readlink(kDummyConstChar, buf, 10)); 510 ASSERT_EQ(kDummyErrno, errno); 511 } 512 513 #ifdef __GLIBC__ 514 // Under newlib there is no remove syscall. Instead it is implemented 515 // in terms of unlink()/rmdir(). 516 TEST_F(KernelWrapTest, remove) { 517 EXPECT_CALL(mock, remove(kDummyConstChar)).WillOnce(Return(-1)); 518 EXPECT_EQ(-1, remove(kDummyConstChar)); 519 } 520 #endif 521 522 TEST_F(KernelWrapTest, rename) { 523 EXPECT_CALL(mock, rename(kDummyConstChar, kDummyConstChar2)) 524 .WillOnce(Return(0)) 525 .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1))); 526 527 EXPECT_EQ(0, rename(kDummyConstChar, kDummyConstChar2)); 528 EXPECT_EQ(-1, rename(kDummyConstChar, kDummyConstChar2)); 529 ASSERT_EQ(kDummyErrno, errno); 530 } 531 532 TEST_F(KernelWrapTest, rmdir) { 533 EXPECT_CALL(mock, rmdir(kDummyConstChar)) 534 .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1))); 535 EXPECT_EQ(-1, rmdir(kDummyConstChar)); 536 ASSERT_EQ(kDummyErrno, errno); 537 } 538 539 static void new_handler(int) {} 540 541 TEST_F(KernelWrapTest, sigaction) { 542 struct sigaction action; 543 struct sigaction oaction; 544 EXPECT_CALL(mock, sigaction(kDummyInt, &action, &oaction)) 545 .WillOnce(Return(0)); 546 EXPECT_EQ(0, sigaction(kDummyInt, &action, &oaction)); 547 } 548 549 TEST_F(KernelWrapTest, sigset) { 550 EXPECT_CALL(mock, sigaction(kDummyInt, _, _)) 551 .WillOnce(Return(0)); 552 EXPECT_EQ(NULL, sigset(kDummyInt, new_handler)); 553 } 554 555 TEST_F(KernelWrapTest, signal) { 556 // KernelIntercept forwards calls to signal to KernelProxy::sigset. 557 EXPECT_CALL(mock, sigaction(kDummyInt, _, _)) 558 .WillOnce(Return(0)); 559 EXPECT_EQ(NULL, signal(kDummyInt, new_handler)); 560 } 561 562 TEST_F(KernelWrapTest, stat) { 563 // The way we wrap stat does not support returning aribtrary values, only 0 564 // or -1. 565 struct stat in_statbuf; 566 MakeDummyStatbuf(&in_statbuf); 567 EXPECT_CALL(mock, stat(StrEq(kDummyConstChar), _)) 568 .WillOnce(DoAll(SetStat(&in_statbuf), Return(0))) 569 .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1))); 570 struct stat out_statbuf; 571 572 EXPECT_EQ(0, stat(kDummyConstChar, &out_statbuf)); 573 EXPECT_THAT(&in_statbuf, IsEqualToStatbuf(&out_statbuf)); 574 575 EXPECT_EQ(-1, stat(kDummyConstChar, &out_statbuf)); 576 ASSERT_EQ(kDummyErrno, errno); 577 } 578 579 TEST_F(KernelWrapTest, symlink) { 580 EXPECT_CALL(mock, symlink(kDummyConstChar, kDummyConstChar2)) 581 .WillOnce(Return(kDummyInt)); 582 EXPECT_EQ(kDummyInt, symlink(kDummyConstChar, kDummyConstChar2)); 583 } 584 585 #ifndef __BIONIC__ 586 TEST_F(KernelWrapTest, tcflush) { 587 EXPECT_CALL(mock, tcflush(kDummyInt, kDummyInt2)) 588 .WillOnce(Return(kDummyInt3)); 589 EXPECT_EQ(kDummyInt3, tcflush(kDummyInt, kDummyInt2)); 590 } 591 592 TEST_F(KernelWrapTest, tcgetattr) { 593 struct termios term; 594 EXPECT_CALL(mock, tcgetattr(kDummyInt, &term)).WillOnce(Return(kDummyInt2)); 595 EXPECT_EQ(kDummyInt2, tcgetattr(kDummyInt, &term)); 596 } 597 598 TEST_F(KernelWrapTest, tcsetattr) { 599 struct termios term; 600 EXPECT_CALL(mock, tcsetattr(kDummyInt, kDummyInt2, &term)) 601 .WillOnce(Return(kDummyInt3)); 602 EXPECT_EQ(kDummyInt3, tcsetattr(kDummyInt, kDummyInt2, &term)); 603 } 604 #endif 605 606 TEST_F(KernelWrapTest, umount) { 607 EXPECT_CALL(mock, umount(kDummyConstChar)).WillOnce(Return(kDummyInt)); 608 EXPECT_EQ(kDummyInt, umount(kDummyConstChar)); 609 } 610 611 TEST_F(KernelWrapTest, truncate) { 612 EXPECT_CALL(mock, truncate(kDummyConstChar, kDummyInt3)) 613 .WillOnce(Return(0)) 614 .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1))); 615 616 EXPECT_EQ(0, truncate(kDummyConstChar, kDummyInt3)); 617 618 EXPECT_EQ(-1, truncate(kDummyConstChar, kDummyInt3)); 619 } 620 621 TEST_F(KernelWrapTest, lstat) { 622 struct stat in_statbuf; 623 MakeDummyStatbuf(&in_statbuf); 624 EXPECT_CALL(mock, lstat(StrEq(kDummyConstChar), _)) 625 .WillOnce(DoAll(SetStat(&in_statbuf), Return(0))) 626 .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1))); 627 struct stat out_statbuf; 628 629 EXPECT_EQ(0, lstat(kDummyConstChar, &out_statbuf)); 630 EXPECT_THAT(&in_statbuf, IsEqualToStatbuf(&out_statbuf)); 631 632 EXPECT_EQ(-1, lstat(kDummyConstChar, &out_statbuf)); 633 ASSERT_EQ(kDummyErrno, errno); 634 } 635 636 TEST_F(KernelWrapTest, unlink) { 637 EXPECT_CALL(mock, unlink(kDummyConstChar)) 638 .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1))); 639 EXPECT_EQ(-1, unlink(kDummyConstChar)); 640 ASSERT_EQ(kDummyErrno, errno); 641 } 642 643 TEST_F(KernelWrapTest, utime) { 644 const struct utimbuf times = {123, 456}; 645 EXPECT_CALL(mock, utimens(kDummyConstChar, IsEqualToUtimbuf(×))) 646 .WillOnce(Return(kDummyInt)); 647 EXPECT_EQ(kDummyInt, utime(kDummyConstChar, ×)); 648 } 649 650 TEST_F(KernelWrapTest, utimes) { 651 struct timeval times[2] = {{123, 234}, {345, 456}}; 652 EXPECT_CALL(mock, utimens(kDummyConstChar, IsEqualToTimeval(times))) 653 .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1))); 654 EXPECT_EQ(-1, utimes(kDummyConstChar, times)); 655 ASSERT_EQ(kDummyErrno, errno); 656 } 657 658 TEST_F(KernelWrapTest, write) { 659 EXPECT_CALL(mock, write(kDummyInt, kDummyVoidPtr, kDummyInt2)) 660 .WillOnce(Return(kDummyInt3)); 661 EXPECT_EQ(kDummyInt3, write(kDummyInt, kDummyVoidPtr, kDummyInt2)); 662 } 663 664 class KernelWrapTestUninit : public ::testing::Test { 665 void SetUp() { 666 ASSERT_EQ(0, ki_push_state_for_testing()); 667 kernel_wrap_uninit(); 668 } 669 670 void TearDown() { 671 kernel_wrap_init(); 672 ki_pop_state_for_testing(); 673 } 674 }; 675 676 TEST_F(KernelWrapTestUninit, Mkdir_Uninitialised) { 677 // If we are running within chrome we can't use these calls without 678 // nacl_io initialized. 679 if (PSGetInstanceId() != 0) 680 return; 681 EXPECT_EQ(0, mkdir("./foo", S_IREAD | S_IWRITE)); 682 EXPECT_EQ(0, rmdir("./foo")); 683 } 684 685 TEST_F(KernelWrapTestUninit, Getcwd_Uninitialised) { 686 // If we are running within chrome we can't use these calls without 687 // nacl_io initialized. 688 if (PSGetInstanceId() != 0) 689 return; 690 char dir[PATH_MAX]; 691 ASSERT_NE((char*)NULL, getcwd(dir, PATH_MAX)); 692 // Verify that the CWD ends with 'nacl_io_test' 693 const char* suffix = "nacl_io_test"; 694 ASSERT_GT(strlen(dir), strlen(suffix)); 695 ASSERT_EQ(0, strcmp(dir+strlen(dir)-strlen(suffix), suffix)); 696 } 697 698 #if defined(PROVIDES_SOCKET_API) and !defined(__BIONIC__) 699 TEST_F(KernelWrapTest, poll) { 700 struct pollfd fds; 701 EXPECT_CALL(mock, poll(&fds, kDummyInt, kDummyInt2)) 702 .WillOnce(Return(kDummyInt3)); 703 EXPECT_EQ(kDummyInt3, poll(&fds, kDummyInt, kDummyInt2)); 704 } 705 706 TEST_F(KernelWrapTest, select) { 707 fd_set readfds; 708 fd_set writefds; 709 fd_set exceptfds; 710 EXPECT_CALL(mock, select(kDummyInt, &readfds, &writefds, &exceptfds, NULL)) 711 .WillOnce(Return(kDummyInt2)); 712 EXPECT_EQ(kDummyInt2, 713 select(kDummyInt, &readfds, &writefds, &exceptfds, NULL)); 714 } 715 716 // Socket Functions 717 TEST_F(KernelWrapTest, accept) { 718 struct sockaddr addr; 719 socklen_t len; 720 EXPECT_CALL(mock, accept(kDummyInt, &addr, &len)) 721 .WillOnce(Return(kDummyInt2)); 722 EXPECT_EQ(kDummyInt2, accept(kDummyInt, &addr, &len)); 723 } 724 725 TEST_F(KernelWrapTest, bind) { 726 // The way we wrap bind does not support returning arbitrary values, so we 727 // test 0 and -1. 728 struct sockaddr addr; 729 EXPECT_CALL(mock, bind(kDummyInt, &addr, kDummyInt2)) 730 .WillOnce(Return(0)) 731 .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1))); 732 EXPECT_EQ(0, bind(kDummyInt, &addr, kDummyInt2)); 733 EXPECT_EQ(-1, bind(kDummyInt, &addr, kDummyInt2)); 734 EXPECT_EQ(kDummyErrno, errno); 735 } 736 737 TEST_F(KernelWrapTest, connect) { 738 // The way we wrap connect does not support returning arbitrary values, so we 739 // test 0 and -1. 740 struct sockaddr addr; 741 EXPECT_CALL(mock, connect(kDummyInt, &addr, kDummyInt2)) 742 .WillOnce(Return(0)) 743 .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1))); 744 EXPECT_EQ(0, connect(kDummyInt, &addr, kDummyInt2)); 745 EXPECT_EQ(-1, connect(kDummyInt, &addr, kDummyInt2)); 746 EXPECT_EQ(kDummyErrno, errno); 747 } 748 749 TEST_F(KernelWrapTest, gethostbyname) { 750 struct hostent result; 751 EXPECT_CALL(mock, gethostbyname(kDummyConstChar)).WillOnce(Return(&result)); 752 EXPECT_EQ(&result, gethostbyname(kDummyConstChar)); 753 } 754 755 TEST_F(KernelWrapTest, getpeername) { 756 // The way we wrap getpeername does not support returning arbitrary values, 757 // so we test 0 and -1. 758 struct sockaddr addr; 759 socklen_t len; 760 EXPECT_CALL(mock, getpeername(kDummyInt, &addr, &len)) 761 .WillOnce(Return(0)) 762 .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1))); 763 EXPECT_EQ(0, getpeername(kDummyInt, &addr, &len)); 764 EXPECT_EQ(-1, getpeername(kDummyInt, &addr, &len)); 765 EXPECT_EQ(kDummyErrno, errno); 766 } 767 768 TEST_F(KernelWrapTest, getsockname) { 769 // The way we wrap getsockname does not support returning arbitrary values, 770 // so we test 0 and -1. 771 struct sockaddr addr; 772 socklen_t len; 773 774 EXPECT_CALL(mock, getsockname(kDummyInt, &addr, &len)) 775 .WillOnce(Return(0)) 776 .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1))); 777 EXPECT_EQ(0, getsockname(kDummyInt, &addr, &len)); 778 EXPECT_EQ(-1, getsockname(kDummyInt, &addr, &len)); 779 EXPECT_EQ(kDummyErrno, errno); 780 } 781 782 TEST_F(KernelWrapTest, getsockopt) { 783 // The way we wrap getsockname does not support returning arbitrary values, 784 // so we test 0 and -1. 785 int dummy_val; 786 void* dummy_void_ptr = &dummy_val; 787 socklen_t len; 788 EXPECT_CALL( 789 mock, getsockopt(kDummyInt, kDummyInt2, kDummyInt3, dummy_void_ptr, &len)) 790 .WillOnce(Return(0)) 791 .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1))); 792 EXPECT_EQ( 793 0, 794 getsockopt(kDummyInt, kDummyInt2, kDummyInt3, dummy_void_ptr, &len)); 795 EXPECT_EQ( 796 -1, 797 getsockopt(kDummyInt, kDummyInt2, kDummyInt3, dummy_void_ptr, &len)); 798 EXPECT_EQ(kDummyErrno, errno); 799 } 800 801 TEST_F(KernelWrapTest, listen) { 802 // The way we wrap listen does not support returning arbitrary values, so we 803 // test 0 and -1. 804 EXPECT_CALL(mock, listen(kDummyInt, kDummyInt2)) 805 .WillOnce(Return(0)) 806 .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1))); 807 EXPECT_EQ(0, listen(kDummyInt, kDummyInt2)); 808 EXPECT_EQ(-1, listen(kDummyInt, kDummyInt2)); 809 EXPECT_EQ(kDummyErrno, errno); 810 } 811 812 TEST_F(KernelWrapTest, recv) { 813 int dummy_val; 814 void* dummy_void_ptr = &dummy_val; 815 EXPECT_CALL(mock, recv(kDummyInt, dummy_void_ptr, kDummySizeT, kDummyInt2)) 816 .WillOnce(Return(kDummyInt3)); 817 EXPECT_EQ(kDummyInt3, 818 recv(kDummyInt, dummy_void_ptr, kDummySizeT, kDummyInt2)); 819 } 820 821 TEST_F(KernelWrapTest, recvfrom) { 822 int dummy_val; 823 void* dummy_void_ptr = &dummy_val; 824 struct sockaddr addr; 825 socklen_t len; 826 EXPECT_CALL( 827 mock, 828 recvfrom(kDummyInt, dummy_void_ptr, kDummyInt2, kDummyInt3, &addr, &len)) 829 .WillOnce(Return(kDummyInt4)); 830 EXPECT_EQ( 831 kDummyInt4, 832 recvfrom(kDummyInt, dummy_void_ptr, kDummyInt2, kDummyInt3, &addr, &len)); 833 } 834 835 #ifndef __BIONIC__ 836 TEST_F(KernelWrapTest, recvmsg) { 837 struct msghdr msg; 838 EXPECT_CALL(mock, recvmsg(kDummyInt, &msg, kDummyInt2)) 839 .WillOnce(Return(kDummyInt3)); 840 EXPECT_EQ(kDummyInt3, recvmsg(kDummyInt, &msg, kDummyInt2)); 841 } 842 #endif 843 844 TEST_F(KernelWrapTest, send) { 845 EXPECT_CALL(mock, send(kDummyInt, kDummyVoidPtr, kDummySizeT, kDummyInt2)) 846 .WillOnce(Return(kDummyInt3)); 847 EXPECT_EQ(kDummyInt3, 848 send(kDummyInt, kDummyVoidPtr, kDummySizeT, kDummyInt2)); 849 } 850 851 TEST_F(KernelWrapTest, sendto) { 852 const socklen_t kDummySockLen = 0x50cc5; 853 struct sockaddr addr; 854 EXPECT_CALL(mock, 855 sendto(kDummyInt, 856 kDummyVoidPtr, 857 kDummyInt2, 858 kDummyInt3, 859 &addr, 860 kDummySockLen)).WillOnce(Return(kDummyInt4)); 861 EXPECT_EQ(kDummyInt4, 862 sendto(kDummyInt, 863 kDummyVoidPtr, 864 kDummyInt2, 865 kDummyInt3, 866 &addr, 867 kDummySockLen)); 868 } 869 870 TEST_F(KernelWrapTest, sendmsg) { 871 struct msghdr msg; 872 EXPECT_CALL(mock, sendmsg(kDummyInt, &msg, kDummyInt2)) 873 .WillOnce(Return(kDummyInt3)); 874 EXPECT_EQ(kDummyInt3, sendmsg(kDummyInt, &msg, kDummyInt2)); 875 } 876 877 TEST_F(KernelWrapTest, setsockopt) { 878 // The way we wrap setsockopt does not support returning arbitrary values, so 879 // we test 0 and -1. 880 const socklen_t kDummySockLen = 0x50cc5; 881 EXPECT_CALL( 882 mock, 883 setsockopt( 884 kDummyInt, kDummyInt2, kDummyInt3, kDummyVoidPtr, kDummySockLen)) 885 .WillOnce(Return(0)) 886 .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1))); 887 EXPECT_EQ( 888 0, 889 setsockopt( 890 kDummyInt, kDummyInt2, kDummyInt3, kDummyVoidPtr, kDummySockLen)); 891 EXPECT_EQ( 892 -1, 893 setsockopt( 894 kDummyInt, kDummyInt2, kDummyInt3, kDummyVoidPtr, kDummySockLen)); 895 EXPECT_EQ(kDummyErrno, errno); 896 } 897 898 TEST_F(KernelWrapTest, shutdown) { 899 // The way we wrap shutdown does not support returning arbitrary values, so we 900 // test 0 and -1. 901 EXPECT_CALL(mock, shutdown(kDummyInt, kDummyInt2)) 902 .WillOnce(Return(0)) 903 .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1))); 904 EXPECT_EQ(0, shutdown(kDummyInt, kDummyInt2)); 905 EXPECT_EQ(-1, shutdown(kDummyInt, kDummyInt2)); 906 EXPECT_EQ(kDummyErrno, errno); 907 } 908 909 TEST_F(KernelWrapTest, socket) { 910 EXPECT_CALL(mock, socket(kDummyInt, kDummyInt2, kDummyInt3)) 911 .WillOnce(Return(kDummyInt4)); 912 EXPECT_EQ(kDummyInt4, socket(kDummyInt, kDummyInt2, kDummyInt3)); 913 } 914 915 TEST_F(KernelWrapTest, socketpair) { 916 // The way we wrap socketpair does not support returning arbitrary values, 917 // so we test 0 and -1. 918 int dummy_val; 919 EXPECT_CALL(mock, socketpair(kDummyInt, kDummyInt2, kDummyInt3, &dummy_val)) 920 .WillOnce(Return(0)) 921 .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1))); 922 EXPECT_EQ(0, socketpair(kDummyInt, kDummyInt2, kDummyInt3, &dummy_val)); 923 EXPECT_EQ(-1, socketpair(kDummyInt, kDummyInt2, kDummyInt3, &dummy_val)); 924 EXPECT_EQ(kDummyErrno, errno); 925 } 926 927 #endif // PROVIDES_SOCKET_API 928 929 #endif // __linux__ 930