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