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(×)))
654 .WillOnce(Return(kDummyInt));
655 EXPECT_EQ(kDummyInt, utime(kDummyConstChar, ×));
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