]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/capsicum-test/capmode.cc
bhyvectl(8): Normalize the man page date
[FreeBSD/FreeBSD.git] / contrib / capsicum-test / capmode.cc
1 // Test routines to make sure a variety of system calls are or are not
2 // available in capability mode.  The goal is not to see if they work, just
3 // whether or not they return the expected ECAPMODE.
4 #include <sys/types.h>
5 #include <sys/socket.h>
6 #include <sys/stat.h>
7 #include <sys/mount.h>
8 #include <sys/mman.h>
9 #include <sys/wait.h>
10 #include <sys/time.h>
11 #include <sys/resource.h>
12 #include <sys/ptrace.h>
13 #include <dirent.h>
14 #include <netinet/in.h>
15 #include <fcntl.h>
16 #include <sched.h>
17 #include <time.h>
18 #include <unistd.h>
19 #include <pthread.h>
20
21 #include "capsicum.h"
22 #include "syscalls.h"
23 #include "capsicum-test.h"
24
25 // Test fixture that opens (and closes) a bunch of files.
26 class WithFiles : public ::testing::Test {
27  public:
28   WithFiles() :
29     fd_file_(open(TmpFile("cap_capmode"), O_RDWR|O_CREAT, 0644)),
30     fd_close_(open("/dev/null", O_RDWR)),
31     fd_dir_(open(tmpdir.c_str(), O_RDONLY)),
32     fd_socket_(socket(PF_INET, SOCK_DGRAM, 0)),
33     fd_tcp_socket_(socket(PF_INET, SOCK_STREAM, 0)) {
34     EXPECT_OK(fd_file_);
35     EXPECT_OK(fd_close_);
36     EXPECT_OK(fd_dir_);
37     EXPECT_OK(fd_socket_);
38     EXPECT_OK(fd_tcp_socket_);
39   }
40   ~WithFiles() {
41     if (fd_tcp_socket_ >= 0) close(fd_tcp_socket_);
42     if (fd_socket_ >= 0) close(fd_socket_);
43     if (fd_dir_ >= 0) close(fd_dir_);
44     if (fd_close_ >= 0) close(fd_close_);
45     if (fd_file_ >= 0) close(fd_file_);
46     unlink(TmpFile("cap_capmode"));
47   }
48  protected:
49   int fd_file_;
50   int fd_close_;
51   int fd_dir_;
52   int fd_socket_;
53   int fd_tcp_socket_;
54 };
55
56 FORK_TEST_F(WithFiles, DisallowedFileSyscalls) {
57   unsigned int mode = -1;
58   EXPECT_OK(cap_getmode(&mode));
59   EXPECT_EQ(0, (int)mode);
60   EXPECT_OK(cap_enter());  // Enter capability mode.
61   EXPECT_OK(cap_getmode(&mode));
62   EXPECT_EQ(1, (int)mode);
63
64   // System calls that are not permitted in capability mode.
65   EXPECT_CAPMODE(access(TmpFile("cap_capmode_access"), F_OK));
66   EXPECT_CAPMODE(acct(TmpFile("cap_capmode_acct")));
67   EXPECT_CAPMODE(chdir(TmpFile("cap_capmode_chdir")));
68 #ifdef HAVE_CHFLAGS
69   EXPECT_CAPMODE(chflags(TmpFile("cap_capmode_chflags"), UF_NODUMP));
70 #endif
71   EXPECT_CAPMODE(chmod(TmpFile("cap_capmode_chmod"), 0644));
72   EXPECT_CAPMODE(chown(TmpFile("cap_capmode_chown"), -1, -1));
73   EXPECT_CAPMODE(chroot(TmpFile("cap_capmode_chroot")));
74   EXPECT_CAPMODE(creat(TmpFile("cap_capmode_creat"), 0644));
75   EXPECT_CAPMODE(fchdir(fd_dir_));
76 #ifdef HAVE_GETFSSTAT
77   struct statfs statfs;
78   EXPECT_CAPMODE(getfsstat(&statfs, sizeof(statfs), MNT_NOWAIT));
79 #endif
80   EXPECT_CAPMODE(link(TmpFile("foo"), TmpFile("bar")));
81   struct stat sb;
82   EXPECT_CAPMODE(lstat(TmpFile("cap_capmode_lstat"), &sb));
83   EXPECT_CAPMODE(mknod(TmpFile("capmode_mknod"), 0644 | S_IFIFO, 0));
84   EXPECT_CAPMODE(bogus_mount_());
85   EXPECT_CAPMODE(open("/dev/null", O_RDWR));
86   char buf[64];
87   EXPECT_CAPMODE(readlink(TmpFile("cap_capmode_readlink"), buf, sizeof(buf)));
88 #ifdef HAVE_REVOKE
89   EXPECT_CAPMODE(revoke(TmpFile("cap_capmode_revoke")));
90 #endif
91   EXPECT_CAPMODE(stat(TmpFile("cap_capmode_stat"), &sb));
92   EXPECT_CAPMODE(symlink(TmpFile("cap_capmode_symlink_from"), TmpFile("cap_capmode_symlink_to")));
93   EXPECT_CAPMODE(unlink(TmpFile("cap_capmode_unlink")));
94   EXPECT_CAPMODE(umount2("/not_mounted", 0));
95 }
96
97 FORK_TEST_F(WithFiles, DisallowedSocketSyscalls) {
98   EXPECT_OK(cap_enter());  // Enter capability mode.
99
100   // System calls that are not permitted in capability mode.
101   struct sockaddr_in addr;
102   addr.sin_family = AF_INET;
103   addr.sin_port = 0;
104   addr.sin_addr.s_addr = htonl(INADDR_ANY);
105   EXPECT_CAPMODE(bind_(fd_socket_, (sockaddr*)&addr, sizeof(addr)));
106   addr.sin_family = AF_INET;
107   addr.sin_port = 53;
108   addr.sin_addr.s_addr = htonl(0x08080808);
109   EXPECT_CAPMODE(connect_(fd_tcp_socket_, (sockaddr*)&addr, sizeof(addr)));
110 }
111
112 FORK_TEST_F(WithFiles, AllowedFileSyscalls) {
113   int rc;
114   EXPECT_OK(cap_enter());  // Enter capability mode.
115
116   EXPECT_OK(close(fd_close_));
117   fd_close_ = -1;
118   int fd_dup = dup(fd_file_);
119   EXPECT_OK(fd_dup);
120   EXPECT_OK(dup2(fd_file_, fd_dup));
121 #ifdef HAVE_DUP3
122   EXPECT_OK(dup3(fd_file_, fd_dup, 0));
123 #endif
124   if (fd_dup >= 0) close(fd_dup);
125
126   struct stat sb;
127   EXPECT_OK(fstat(fd_file_, &sb));
128   EXPECT_OK(lseek(fd_file_, 0, SEEK_SET));
129   char ch;
130   EXPECT_OK(read(fd_file_, &ch, sizeof(ch)));
131   EXPECT_OK(write(fd_file_, &ch, sizeof(ch)));
132
133 #ifdef HAVE_CHFLAGS
134   rc = fchflags(fd_file_, UF_NODUMP);
135   if (rc < 0) {
136     EXPECT_NE(ECAPMODE, errno);
137   }
138 #endif
139
140   char buf[1024];
141   rc = getdents_(fd_dir_, (void*)buf, sizeof(buf));
142   EXPECT_OK(rc);
143
144   char data[] = "123";
145   EXPECT_OK(pwrite(fd_file_, data, 1, 0));
146   EXPECT_OK(pread(fd_file_, data, 1, 0));
147
148   struct iovec io;
149   io.iov_base = data;
150   io.iov_len = 2;
151 #if !defined(__i386__) && !defined(__linux__)
152   // TODO(drysdale): reinstate these tests for 32-bit runs when possible
153   // libc bug is fixed.
154   EXPECT_OK(pwritev(fd_file_, &io, 1, 0));
155   EXPECT_OK(preadv(fd_file_, &io, 1, 0));
156 #endif
157   EXPECT_OK(writev(fd_file_, &io, 1));
158   EXPECT_OK(readv(fd_file_, &io, 1));
159
160 #ifdef HAVE_SYNCFS
161   EXPECT_OK(syncfs(fd_file_));
162 #endif
163 #ifdef HAVE_SYNC_FILE_RANGE
164   EXPECT_OK(sync_file_range(fd_file_, 0, 1, 0));
165 #endif
166 #ifdef HAVE_READAHEAD
167   if (!tmpdir_on_tmpfs) {  // tmpfs doesn't support readahead(2)
168     EXPECT_OK(readahead(fd_file_, 0, 1));
169   }
170 #endif
171 }
172
173 FORK_TEST_F(WithFiles, AllowedSocketSyscalls) {
174   EXPECT_OK(cap_enter());  // Enter capability mode.
175
176   // recvfrom() either returns -1 with EAGAIN, or 0.
177   int rc = recvfrom(fd_socket_, NULL, 0, MSG_DONTWAIT, NULL, NULL);
178   if (rc < 0) {
179     EXPECT_EQ(EAGAIN, errno);
180   }
181   char ch;
182   EXPECT_OK(write(fd_file_, &ch, sizeof(ch)));
183
184   // These calls will fail for lack of e.g. a proper name to send to,
185   // but they are allowed in capability mode, so errno != ECAPMODE.
186   EXPECT_FAIL_NOT_CAPMODE(accept(fd_socket_, NULL, NULL));
187   EXPECT_FAIL_NOT_CAPMODE(getpeername(fd_socket_, NULL, NULL));
188   EXPECT_FAIL_NOT_CAPMODE(getsockname(fd_socket_, NULL, NULL));
189   EXPECT_FAIL_NOT_CAPMODE(recvmsg(fd_socket_, NULL, 0));
190   EXPECT_FAIL_NOT_CAPMODE(sendmsg(fd_socket_, NULL, 0));
191   EXPECT_FAIL_NOT_CAPMODE(sendto(fd_socket_, NULL, 0, 0, NULL, 0));
192   off_t offset = 0;
193   EXPECT_FAIL_NOT_CAPMODE(sendfile_(fd_socket_, fd_file_, &offset, 1));
194
195   // The socket/socketpair syscalls are allowed, but they don't give
196   // anything externally useful (can't call bind/connect on them).
197   int fd_socket2 = socket(PF_INET, SOCK_DGRAM, 0);
198   EXPECT_OK(fd_socket2);
199   if (fd_socket2 >= 0) close(fd_socket2);
200   int fd_pair[2] = {-1, -1};
201   EXPECT_OK(socketpair(AF_UNIX, SOCK_STREAM, 0, fd_pair));
202   if (fd_pair[0] >= 0) close(fd_pair[0]);
203   if (fd_pair[1] >= 0) close(fd_pair[1]);
204 }
205
206 #ifdef HAVE_SEND_RECV_MMSG
207 FORK_TEST(Capmode, AllowedMmsgSendRecv) {
208   int fd_socket = socket(PF_INET, SOCK_DGRAM, 0);
209
210   struct sockaddr_in addr;
211   addr.sin_family = AF_INET;
212   addr.sin_port = htons(0);
213   addr.sin_addr.s_addr = htonl(INADDR_ANY);
214   EXPECT_OK(bind(fd_socket, (sockaddr*)&addr, sizeof(addr)));
215
216   EXPECT_OK(cap_enter());  // Enter capability mode.
217
218   char buffer[256] = {0};
219   struct iovec iov;
220   iov.iov_base = buffer;
221   iov.iov_len = sizeof(buffer);
222   struct mmsghdr mm;
223   memset(&mm, 0, sizeof(mm));
224   mm.msg_hdr.msg_iov = &iov;
225   mm.msg_hdr.msg_iovlen = 1;
226   struct timespec ts;
227   ts.tv_sec = 1;
228   ts.tv_nsec = 100;
229   EXPECT_FAIL_NOT_CAPMODE(recvmmsg(fd_socket, &mm, 1, MSG_DONTWAIT, &ts));
230   EXPECT_FAIL_NOT_CAPMODE(sendmmsg(fd_socket, &mm, 1, 0));
231   close(fd_socket);
232 }
233 #endif
234
235 FORK_TEST(Capmode, AllowedIdentifierSyscalls) {
236   // Record some identifiers
237   gid_t my_gid = getgid();
238   pid_t my_pid = getpid();
239   pid_t my_ppid = getppid();
240   uid_t my_uid = getuid();
241   pid_t my_sid = getsid(my_pid);
242
243   EXPECT_OK(cap_enter());  // Enter capability mode.
244
245   EXPECT_EQ(my_gid, getegid_());
246   EXPECT_EQ(my_uid, geteuid_());
247   EXPECT_EQ(my_gid, getgid_());
248   EXPECT_EQ(my_pid, getpid());
249   EXPECT_EQ(my_ppid, getppid());
250   EXPECT_EQ(my_uid, getuid_());
251   EXPECT_EQ(my_sid, getsid(my_pid));
252   gid_t grps[128];
253   EXPECT_OK(getgroups_(128, grps));
254   uid_t ruid;
255   uid_t euid;
256   uid_t suid;
257   EXPECT_OK(getresuid(&ruid, &euid, &suid));
258   gid_t rgid;
259   gid_t egid;
260   gid_t sgid;
261   EXPECT_OK(getresgid(&rgid, &egid, &sgid));
262 #ifdef HAVE_GETLOGIN
263   EXPECT_TRUE(getlogin() != NULL);
264 #endif
265
266   // Set various identifiers (to their existing values).
267   EXPECT_OK(setgid(my_gid));
268 #ifdef HAVE_SETFSGID
269   EXPECT_OK(setfsgid(my_gid));
270 #endif
271   EXPECT_OK(setuid(my_uid));
272 #ifdef HAVE_SETFSUID
273   EXPECT_OK(setfsuid(my_uid));
274 #endif
275   EXPECT_OK(setregid(my_gid, my_gid));
276   EXPECT_OK(setresgid(my_gid, my_gid, my_gid));
277   EXPECT_OK(setreuid(my_uid, my_uid));
278   EXPECT_OK(setresuid(my_uid, my_uid, my_uid));
279   EXPECT_OK(setsid());
280 }
281
282 FORK_TEST(Capmode, AllowedSchedSyscalls) {
283   EXPECT_OK(cap_enter());  // Enter capability mode.
284   int policy = sched_getscheduler(0);
285   EXPECT_OK(policy);
286   struct sched_param sp;
287   EXPECT_OK(sched_getparam(0, &sp));
288   if (policy >= 0 && (!SCHED_SETSCHEDULER_REQUIRES_ROOT || getuid() == 0)) {
289     EXPECT_OK(sched_setscheduler(0, policy, &sp));
290   }
291   EXPECT_OK(sched_setparam(0, &sp));
292   EXPECT_OK(sched_get_priority_max(policy));
293   EXPECT_OK(sched_get_priority_min(policy));
294   struct timespec ts;
295   EXPECT_OK(sched_rr_get_interval(0, &ts));
296   EXPECT_OK(sched_yield());
297 }
298
299
300 FORK_TEST(Capmode, AllowedTimerSyscalls) {
301   EXPECT_OK(cap_enter());  // Enter capability mode.
302   struct timespec ts;
303   EXPECT_OK(clock_getres(CLOCK_REALTIME, &ts));
304   EXPECT_OK(clock_gettime(CLOCK_REALTIME, &ts));
305   struct itimerval itv;
306   EXPECT_OK(getitimer(ITIMER_REAL, &itv));
307   EXPECT_OK(setitimer(ITIMER_REAL, &itv, NULL));
308   struct timeval tv;
309   struct timezone tz;
310   EXPECT_OK(gettimeofday(&tv, &tz));
311   ts.tv_sec = 0;
312   ts.tv_nsec = 1;
313   EXPECT_OK(nanosleep(&ts, NULL));
314 }
315
316
317 FORK_TEST(Capmode, AllowedProfilSyscall) {
318   EXPECT_OK(cap_enter());  // Enter capability mode.
319   char sbuf[32];
320   EXPECT_OK(profil((profil_arg1_t*)sbuf, sizeof(sbuf), 0, 1));
321 }
322
323
324 FORK_TEST(Capmode, AllowedResourceSyscalls) {
325   EXPECT_OK(cap_enter());  // Enter capability mode.
326   errno = 0;
327   int rc = getpriority(PRIO_PROCESS, 0);
328   EXPECT_EQ(0, errno);
329   EXPECT_OK(setpriority(PRIO_PROCESS, 0, rc));
330   struct rlimit rlim;
331   EXPECT_OK(getrlimit_(RLIMIT_CORE, &rlim));
332   EXPECT_OK(setrlimit(RLIMIT_CORE, &rlim));
333   struct rusage ruse;
334   EXPECT_OK(getrusage(RUSAGE_SELF, &ruse));
335 }
336
337 FORK_TEST(CapMode, AllowedMmapSyscalls) {
338   // mmap() some memory.
339   size_t mem_size = getpagesize();
340   void *mem = mmap(NULL, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
341   EXPECT_TRUE(mem != NULL);
342   EXPECT_OK(cap_enter());  // Enter capability mode.
343
344   EXPECT_OK(msync(mem, mem_size, MS_ASYNC));
345   EXPECT_OK(madvise(mem, mem_size, MADV_NORMAL));
346   unsigned char vec[2];
347   EXPECT_OK(mincore_(mem, mem_size, vec));
348   EXPECT_OK(mprotect(mem, mem_size, PROT_READ|PROT_WRITE));
349
350   if (!MLOCK_REQUIRES_ROOT || getuid() == 0) {
351     EXPECT_OK(mlock(mem, mem_size));
352     EXPECT_OK(munlock(mem, mem_size));
353     int rc = mlockall(MCL_CURRENT);
354     if (rc != 0) {
355       // mlockall may well fail with ENOMEM for non-root users, as the
356       // default RLIMIT_MEMLOCK value isn't that big.
357       EXPECT_NE(ECAPMODE, errno);
358     }
359     EXPECT_OK(munlockall());
360   }
361   // Unmap the memory.
362   EXPECT_OK(munmap(mem, mem_size));
363 }
364
365 FORK_TEST(Capmode, AllowedPipeSyscalls) {
366   EXPECT_OK(cap_enter());  // Enter capability mode
367   int fd2[2];
368   int rc = pipe(fd2);
369   EXPECT_EQ(0, rc);
370
371 #ifdef HAVE_VMSPLICE
372   char buf[11] = "0123456789";
373   struct iovec iov;
374   iov.iov_base = buf;
375   iov.iov_len = sizeof(buf);
376   EXPECT_FAIL_NOT_CAPMODE(vmsplice(fd2[0], &iov, 1, SPLICE_F_NONBLOCK));
377 #endif
378
379   if (rc == 0) {
380     close(fd2[0]);
381     close(fd2[1]);
382   };
383 #ifdef HAVE_PIPE2
384   rc = pipe2(fd2, 0);
385   EXPECT_EQ(0, rc);
386   if (rc == 0) {
387     close(fd2[0]);
388     close(fd2[1]);
389   };
390 #endif
391 }
392
393 TEST(Capmode, AllowedAtSyscalls) {
394   int rc = mkdir(TmpFile("cap_at_syscalls"), 0755);
395   EXPECT_OK(rc);
396   if (rc < 0 && errno != EEXIST) return;
397   int dfd = open(TmpFile("cap_at_syscalls"), O_RDONLY);
398   EXPECT_OK(dfd);
399
400   int file = openat(dfd, "testfile", O_RDONLY|O_CREAT, 0644);
401   EXPECT_OK(file);
402   EXPECT_OK(close(file));
403
404
405   pid_t child = fork();
406   if (child == 0) {
407     // Child: enter cap mode and run tests
408     EXPECT_OK(cap_enter());  // Enter capability mode
409
410     struct stat fs;
411     EXPECT_OK(fstatat(dfd, "testfile", &fs, 0));
412     EXPECT_OK(mkdirat(dfd, "subdir", 0600));
413     EXPECT_OK(fchmodat(dfd, "subdir", 0644, 0));
414     EXPECT_OK(faccessat(dfd, "subdir", F_OK, 0));
415     EXPECT_OK(renameat(dfd, "subdir", dfd, "subdir2"));
416     EXPECT_OK(renameat(dfd, "subdir2", dfd, "subdir"));
417     struct timeval tv[2];
418     struct timezone tz;
419     EXPECT_OK(gettimeofday(&tv[0], &tz));
420     EXPECT_OK(gettimeofday(&tv[1], &tz));
421     EXPECT_OK(futimesat(dfd, "testfile", tv));
422
423     EXPECT_OK(fchownat(dfd, "testfile",  fs.st_uid, fs.st_gid, 0));
424     EXPECT_OK(linkat(dfd, "testfile", dfd, "linky", 0));
425     EXPECT_OK(symlinkat("testfile", dfd, "symlink"));
426     char buffer[256];
427     EXPECT_OK(readlinkat(dfd, "symlink", buffer, sizeof(buffer)));
428     EXPECT_OK(unlinkat(dfd, "linky", 0));
429     EXPECT_OK(unlinkat(dfd, "subdir", AT_REMOVEDIR));
430
431     // Check that invalid requests get a non-Capsicum errno.
432     errno = 0;
433     rc = readlinkat(-1, "symlink", buffer, sizeof(buffer));
434     EXPECT_GE(0, rc);
435     EXPECT_NE(ECAPMODE, errno);
436
437     exit(HasFailure());
438   }
439
440   // Wait for the child.
441   int status;
442   EXPECT_EQ(child, waitpid(child, &status, 0));
443   rc = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
444   EXPECT_EQ(0, rc);
445
446   // Tidy up.
447   close(dfd);
448   rmdir(TmpFile("cap_at_syscalls/subdir"));
449   unlink(TmpFile("cap_at_syscalls/symlink"));
450   unlink(TmpFile("cap_at_syscalls/linky"));
451   unlink(TmpFile("cap_at_syscalls/testfile"));
452   rmdir(TmpFile("cap_at_syscalls"));
453 }
454
455 TEST(Capmode, AllowedAtSyscallsCwd) {
456   int rc = mkdir(TmpFile("cap_at_syscalls_cwd"), 0755);
457   EXPECT_OK(rc);
458   if (rc < 0 && errno != EEXIST) return;
459   int dfd = open(TmpFile("cap_at_syscalls_cwd"), O_RDONLY);
460   EXPECT_OK(dfd);
461
462   int file = openat(dfd, "testfile", O_RDONLY|O_CREAT, 0644);
463   EXPECT_OK(file);
464   EXPECT_OK(close(file));
465
466   pid_t child = fork();
467   if (child == 0) {
468     // Child: move into temp dir, enter cap mode and run tests
469     EXPECT_OK(fchdir(dfd));
470     EXPECT_OK(cap_enter());  // Enter capability mode
471
472     // Test that *at(AT_FDCWD, path,...) is policed with ECAPMODE.
473     EXPECT_CAPMODE(openat(AT_FDCWD, "testfile", O_RDONLY));
474     struct stat fs;
475     EXPECT_CAPMODE(fstatat(AT_FDCWD, "testfile", &fs, 0));
476     EXPECT_CAPMODE(mkdirat(AT_FDCWD, "subdir", 0600));
477     EXPECT_CAPMODE(fchmodat(AT_FDCWD, "subdir", 0644, 0));
478     EXPECT_CAPMODE(faccessat(AT_FDCWD, "subdir", F_OK, 0));
479     EXPECT_CAPMODE(renameat(AT_FDCWD, "subdir", AT_FDCWD, "subdir2"));
480     EXPECT_CAPMODE(renameat(AT_FDCWD, "subdir2", AT_FDCWD, "subdir"));
481     struct timeval tv[2];
482     struct timezone tz;
483     EXPECT_OK(gettimeofday(&tv[0], &tz));
484     EXPECT_OK(gettimeofday(&tv[1], &tz));
485     EXPECT_CAPMODE(futimesat(AT_FDCWD, "testfile", tv));
486
487     EXPECT_CAPMODE(fchownat(AT_FDCWD, "testfile",  fs.st_uid, fs.st_gid, 0));
488     EXPECT_CAPMODE(linkat(AT_FDCWD, "testfile", AT_FDCWD, "linky", 0));
489     EXPECT_CAPMODE(symlinkat("testfile", AT_FDCWD, "symlink"));
490     char buffer[256];
491     EXPECT_CAPMODE(readlinkat(AT_FDCWD, "symlink", buffer, sizeof(buffer)));
492     EXPECT_CAPMODE(unlinkat(AT_FDCWD, "linky", 0));
493
494     exit(HasFailure());
495   }
496
497   // Wait for the child.
498   int status;
499   EXPECT_EQ(child, waitpid(child, &status, 0));
500   rc = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
501   EXPECT_EQ(0, rc);
502
503   // Tidy up.
504   close(dfd);
505   rmdir(TmpFile("cap_at_syscalls_cwd/subdir"));
506   unlink(TmpFile("cap_at_syscalls_cwd/symlink"));
507   unlink(TmpFile("cap_at_syscalls_cwd/linky"));
508   unlink(TmpFile("cap_at_syscalls_cwd/testfile"));
509   rmdir(TmpFile("cap_at_syscalls_cwd"));
510 }
511
512 TEST(Capmode, Abort) {
513   // Check that abort(3) works even in capability mode.
514   pid_t child = fork();
515   if (child == 0) {
516     // Child: enter capability mode and call abort(3).
517     // Triggers something like kill(getpid(), SIGABRT).
518     cap_enter();  // Enter capability mode.
519     abort();
520     exit(99);
521   }
522   int status;
523   EXPECT_EQ(child, waitpid(child, &status, 0));
524   EXPECT_TRUE(WIFSIGNALED(status)) << " status = " << std::hex << status;
525   EXPECT_EQ(SIGABRT, WTERMSIG(status)) << " status = " << std::hex << status;
526 }
527
528 FORK_TEST_F(WithFiles, AllowedMiscSyscalls) {
529   umask(022);
530   mode_t um_before = umask(022);
531   EXPECT_OK(cap_enter());  // Enter capability mode.
532
533   mode_t um = umask(022);
534   EXPECT_NE(-ECAPMODE, (int)um);
535   EXPECT_EQ(um_before, um);
536   stack_t ss;
537   EXPECT_OK(sigaltstack(NULL, &ss));
538
539   // Finally, tests for system calls that don't fit the pattern very well.
540   pid_t pid = fork();
541   EXPECT_OK(pid);
542   if (pid == 0) {
543     // Child: almost immediately exit.
544     sleep(1);
545     exit(0);
546   } else if (pid > 0) {
547     errno = 0;
548     EXPECT_CAPMODE(ptrace_(PTRACE_PEEKDATA_, pid, &pid, NULL));
549     EXPECT_CAPMODE(waitpid(pid, NULL, 0));
550   }
551
552   // No error return from sync(2) to test, but check errno remains unset.
553   errno = 0;
554   sync();
555   EXPECT_EQ(0, errno);
556
557   // TODO(FreeBSD): ktrace
558
559 #ifdef HAVE_SYSARCH
560   // sysarch() is, by definition, architecture-dependent
561 #if defined (__amd64__) || defined (__i386__)
562   long sysarch_arg = 0;
563   EXPECT_CAPMODE(sysarch(I386_SET_IOPERM, &sysarch_arg));
564 #else
565   // TOOD(jra): write a test for other architectures, like arm
566 #endif
567 #endif
568 }
569
570 void *thread_fn(void *p) {
571   int delay = *(int *)p;
572   sleep(delay);
573   EXPECT_OK(getpid_());
574   EXPECT_CAPMODE(open("/dev/null", O_RDWR));
575   return NULL;
576 }
577
578 // Check that restrictions are the same in subprocesses and threads
579 FORK_TEST(Capmode, NewThread) {
580   // Fire off a new thread before entering capability mode
581   pthread_t early_thread;
582   int one = 1;  // second
583   EXPECT_OK(pthread_create(&early_thread, NULL, thread_fn, &one));
584
585   // Fire off a new process before entering capability mode.
586   int early_child = fork();
587   EXPECT_OK(early_child);
588   if (early_child == 0) {
589     // Child: wait and then confirm this process is unaffect by capability mode in the parent.
590     sleep(1);
591     int fd = open("/dev/null", O_RDWR);
592     EXPECT_OK(fd);
593     close(fd);
594     exit(0);
595   }
596
597   EXPECT_OK(cap_enter());  // Enter capability mode.
598   // Do an allowed syscall.
599   EXPECT_OK(getpid_());
600   int child = fork();
601   EXPECT_OK(child);
602   if (child == 0) {
603     // Child: do an allowed and a disallowed syscall.
604     EXPECT_OK(getpid_());
605     EXPECT_CAPMODE(open("/dev/null", O_RDWR));
606     exit(0);
607   }
608   // Don't (can't) wait for either child.
609
610   // Wait for the early-started thread.
611   EXPECT_OK(pthread_join(early_thread, NULL));
612
613   // Fire off a new thread.
614   pthread_t child_thread;
615   int zero = 0; // seconds
616   EXPECT_OK(pthread_create(&child_thread, NULL, thread_fn, &zero));
617   EXPECT_OK(pthread_join(child_thread, NULL));
618
619   // Fork a subprocess which fires off a new thread.
620   child = fork();
621   EXPECT_OK(child);
622   if (child == 0) {
623     pthread_t child_thread2;
624     EXPECT_OK(pthread_create(&child_thread2, NULL, thread_fn, &zero));
625     EXPECT_OK(pthread_join(child_thread2, NULL));
626     exit(0);
627   }
628   // Sleep for a bit to allow the subprocess to finish.
629   sleep(2);
630 }
631
632 static int had_signal = 0;
633 static void handle_signal(int) { had_signal = 1; }
634
635 FORK_TEST(Capmode, SelfKill) {
636   pid_t me = getpid();
637   sighandler_t original = signal(SIGUSR1, handle_signal);
638
639   pid_t child = fork();
640   if (child == 0) {
641     // Child: sleep and exit
642     sleep(1);
643     exit(0);
644   }
645
646   EXPECT_OK(cap_enter());  // Enter capability mode.
647
648   // Can only kill(2) to own pid.
649   EXPECT_CAPMODE(kill(child, SIGUSR1));
650   EXPECT_OK(kill(me, SIGUSR1));
651   EXPECT_EQ(1, had_signal);
652
653   signal(SIGUSR1, original);
654 }