kernel_wrap_test.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
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__) 26extern "C" { 27// TODO(sbc): remove once this gets added to the newlib toolchain headers. 28int fchdir(int fd); 29} 30#endif 31 32using namespace nacl_io; 33 34using ::testing::_; 35using ::testing::AnyNumber; 36using ::testing::DoAll; 37using ::testing::Invoke; 38using ::testing::Return; 39using ::testing::StrEq; 40 41namespace { 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 53MATCHER_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 68MATCHER_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 74MATCHER_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 86ACTION_P(SetErrno, value) { 87 errno = value; 88} 89 90ACTION_P2(SetString, target, source) { 91 strcpy(target, source); 92} 93 94ACTION_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 109void 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 124const mode_t kDummyMode = 0xbeef; 125const int kDummyErrno = 0xfeeb; 126const int kDummyInt = 0xdedbeef; 127const int kDummyInt2 = 0xcabba6e; 128const int kDummyInt3 = 0xf00ba4; 129const int kDummyInt4 = 0xabacdba; 130const size_t kDummySizeT = 0x60067e; 131const char* kDummyConstChar = "foobar"; 132const char* kDummyConstChar2 = "g00gl3"; 133const char* kDummyConstChar3 = "fr00gl3"; 134const void* kDummyVoidPtr = "blahblah"; 135const uid_t kDummyUid = 1001; 136const gid_t kDummyGid = 1002; 137 138class 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 187TEST_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 198TEST_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 208TEST_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 215TEST_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 222TEST_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 236TEST_F(KernelWrapTest, dup) { 237 EXPECT_CALL(mock, dup(kDummyInt)).WillOnce(Return(kDummyInt2)); 238 EXPECT_EQ(kDummyInt2, dup(kDummyInt)); 239} 240 241TEST_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 253TEST_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 261TEST_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 271TEST_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 277TEST_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 284TEST_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 293TEST_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 310TEST_F(KernelWrapTest, ftruncate) { 311 EXPECT_CALL(mock, ftruncate(kDummyInt, kDummyInt2)) 312 .WillOnce(Return(kDummyInt3)); 313 EXPECT_EQ(kDummyInt3, ftruncate(kDummyInt, kDummyInt2)); 314} 315 316TEST_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 323TEST_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 331TEST_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 341TEST_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 359TEST_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 369TEST_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__) 377TEST_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 391TEST_F(KernelWrapTest, kill) { 392 EXPECT_CALL(mock, kill(kDummyInt, kDummyInt2)).WillOnce(Return(kDummyInt3)); 393 EXPECT_EQ(kDummyInt3, kill(kDummyInt, kDummyInt2)); 394} 395 396TEST_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 402TEST_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 409TEST_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 415TEST_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 427TEST_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 452TEST_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 467TEST_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 477TEST_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 487TEST_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 493TEST_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 501TEST_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(). 516TEST_F(KernelWrapTest, remove) { 517 EXPECT_CALL(mock, remove(kDummyConstChar)).WillOnce(Return(-1)); 518 EXPECT_EQ(-1, remove(kDummyConstChar)); 519} 520#endif 521 522TEST_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 532TEST_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 539static void new_handler(int) {} 540 541TEST_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 549TEST_F(KernelWrapTest, sigset) { 550 EXPECT_CALL(mock, sigaction(kDummyInt, _, _)) 551 .WillOnce(Return(0)); 552 EXPECT_EQ(NULL, sigset(kDummyInt, new_handler)); 553} 554 555TEST_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 562TEST_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 579TEST_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__ 586TEST_F(KernelWrapTest, tcflush) { 587 EXPECT_CALL(mock, tcflush(kDummyInt, kDummyInt2)) 588 .WillOnce(Return(kDummyInt3)); 589 EXPECT_EQ(kDummyInt3, tcflush(kDummyInt, kDummyInt2)); 590} 591 592TEST_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 598TEST_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 606TEST_F(KernelWrapTest, umount) { 607 EXPECT_CALL(mock, umount(kDummyConstChar)).WillOnce(Return(kDummyInt)); 608 EXPECT_EQ(kDummyInt, umount(kDummyConstChar)); 609} 610 611TEST_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 621TEST_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 636TEST_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 643TEST_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 650TEST_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 658TEST_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 664class 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 676TEST_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 685TEST_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__) 699TEST_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 706TEST_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 717TEST_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 725TEST_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 737TEST_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 749TEST_F(KernelWrapTest, gethostbyname) { 750 struct hostent result; 751 EXPECT_CALL(mock, gethostbyname(kDummyConstChar)).WillOnce(Return(&result)); 752 EXPECT_EQ(&result, gethostbyname(kDummyConstChar)); 753} 754 755TEST_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 768TEST_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 782TEST_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 801TEST_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 812TEST_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 821TEST_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__ 836TEST_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 844TEST_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 851TEST_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 870TEST_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 877TEST_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 898TEST_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 909TEST_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 915TEST_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