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.
26class 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
56FORK_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
97FORK_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
112FORK_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
173FORK_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
207FORK_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
235FORK_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
282FORK_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
300FORK_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
317FORK_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
324FORK_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
337FORK_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
365FORK_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
393TEST(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
455TEST(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
512TEST(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
528FORK_TEST_F(WithFiles, AllowedMiscSyscalls) {
529  umask(022);
530  mode_t um_before = umask(022);
531  int pipefds[2];
532  EXPECT_OK(pipe(pipefds));
533  EXPECT_OK(cap_enter());  // Enter capability mode.
534
535  mode_t um = umask(022);
536  EXPECT_NE(-ECAPMODE, (int)um);
537  EXPECT_EQ(um_before, um);
538  stack_t ss;
539  EXPECT_OK(sigaltstack(NULL, &ss));
540
541  // Finally, tests for system calls that don't fit the pattern very well.
542  pid_t pid = fork();
543  EXPECT_OK(pid);
544  if (pid == 0) {
545    // Child: wait for an exit message from parent (so we can test waitpid).
546    EXPECT_OK(close(pipefds[0]));
547    SEND_INT_MESSAGE(pipefds[1], MSG_CHILD_STARTED);
548    AWAIT_INT_MESSAGE(pipefds[1], MSG_PARENT_REQUEST_CHILD_EXIT);
549    exit(0);
550  } else if (pid > 0) {
551    EXPECT_OK(close(pipefds[1]));
552    AWAIT_INT_MESSAGE(pipefds[0], MSG_CHILD_STARTED);
553    errno = 0;
554    EXPECT_CAPMODE(ptrace_(PTRACE_PEEKDATA_, pid, &pid, NULL));
555    EXPECT_CAPMODE(waitpid(pid, NULL, WNOHANG));
556    SEND_INT_MESSAGE(pipefds[0], MSG_PARENT_REQUEST_CHILD_EXIT);
557    if (verbose) fprintf(stderr, "  child finished\n");
558  }
559
560  // No error return from sync(2) to test, but check errno remains unset.
561  errno = 0;
562  sync();
563  EXPECT_EQ(0, errno);
564
565  // TODO(FreeBSD): ktrace
566
567#ifdef HAVE_SYSARCH
568  // sysarch() is, by definition, architecture-dependent
569#if defined (__amd64__) || defined (__i386__)
570  long sysarch_arg = 0;
571  EXPECT_CAPMODE(sysarch(I386_SET_IOPERM, &sysarch_arg));
572#else
573  // TOOD(jra): write a test for other architectures, like arm
574#endif
575#endif
576}
577
578void *thread_fn(void *p) {
579  int fd = (int)(intptr_t)p;
580  if (verbose) fprintf(stderr, "  thread waiting to run\n");
581  AWAIT_INT_MESSAGE(fd, MSG_PARENT_CHILD_SHOULD_RUN);
582  EXPECT_OK(getpid_());
583  EXPECT_CAPMODE(open("/dev/null", O_RDWR));
584  // Return whether there have been any failures to the main thread.
585  void *rval = (void *)(intptr_t)testing::Test::HasFailure();
586  if (verbose) fprintf(stderr, "  thread finished: %p\n", rval);
587  return rval;
588}
589
590// Check that restrictions are the same in subprocesses and threads
591FORK_TEST(Capmode, NewThread) {
592  // Fire off a new thread before entering capability mode
593  pthread_t early_thread;
594  void *thread_rval;
595  // Create two pipes, one for synchronization with the threads, the other to
596  // synchronize with the children (since we can't use waitpid after cap_enter).
597  // Note: Could use pdfork+pdwait instead, but that is tested in procdesc.cc.
598  int thread_pipe[2];
599  EXPECT_OK(pipe(thread_pipe));
600  int proc_pipe[2];
601  EXPECT_OK(pipe(proc_pipe));
602  EXPECT_OK(pthread_create(&early_thread, NULL, thread_fn,
603                           (void *)(intptr_t)thread_pipe[1]));
604
605  // Fire off a new process before entering capability mode.
606  if (verbose) fprintf(stderr, "  starting second child (non-capability mode)\n");
607  int early_child = fork();
608  EXPECT_OK(early_child);
609  if (early_child == 0) {
610    if (verbose) fprintf(stderr, "  first child started\n");
611    EXPECT_OK(close(proc_pipe[0]));
612    // Child: wait and then confirm this process is unaffected by capability mode in the parent.
613    AWAIT_INT_MESSAGE(proc_pipe[1], MSG_PARENT_CHILD_SHOULD_RUN);
614    int fd = open("/dev/null", O_RDWR);
615    EXPECT_OK(fd);
616    close(fd);
617    // Notify the parent of success/failure.
618    int rval = (int)testing::Test::HasFailure();
619    SEND_INT_MESSAGE(proc_pipe[1], rval);
620    if (verbose) fprintf(stderr, "  first child finished: %d\n", rval);
621    exit(rval);
622  }
623
624  EXPECT_OK(cap_enter());  // Enter capability mode.
625  // At this point the current process has both a child process and a
626  // child thread that were created before entering capability mode.
627  //  - The child process is unaffected by capability mode.
628  //  - The child thread is affected by capability mode.
629  SEND_INT_MESSAGE(proc_pipe[0], MSG_PARENT_CHILD_SHOULD_RUN);
630
631  // Do an allowed syscall.
632  EXPECT_OK(getpid_());
633  // Wait for the first child to exit (should get a zero exit code message).
634  AWAIT_INT_MESSAGE(proc_pipe[0], 0);
635
636  // The child processes/threads return HasFailure(), so we depend on no prior errors.
637  ASSERT_FALSE(testing::Test::HasFailure())
638              << "Cannot continue test with pre-existing failures.";
639  // Now that we're in capability mode, if we create a second child process
640  // it will be affected by capability mode.
641  if (verbose) fprintf(stderr, "  starting second child (in capability mode)\n");
642  int child = fork();
643  EXPECT_OK(child);
644  if (child == 0) {
645    if (verbose) fprintf(stderr, "  second child started\n");
646    EXPECT_OK(close(proc_pipe[0]));
647    // Child: do an allowed and a disallowed syscall.
648    EXPECT_OK(getpid_());
649    EXPECT_CAPMODE(open("/dev/null", O_RDWR));
650    // Notify the parent of success/failure.
651    int rval = (int)testing::Test::HasFailure();
652    SEND_INT_MESSAGE(proc_pipe[1], rval);
653    if (verbose) fprintf(stderr, "  second child finished: %d\n", rval);
654    exit(rval);
655  }
656  // Now tell the early_started thread that it can run. We expect it to also
657  // be affected by capability mode since it's per-process not per-thread.
658  // Note: it is important that we don't allow the thread to run before fork(),
659  // since that could result in fork() being called while the thread holds one
660  // of the gtest-internal mutexes, so the child process deadlocks.
661  SEND_INT_MESSAGE(thread_pipe[0], MSG_PARENT_CHILD_SHOULD_RUN);
662  // Wait for the early-started thread.
663  EXPECT_OK(pthread_join(early_thread, &thread_rval));
664  EXPECT_FALSE((bool)(intptr_t)thread_rval) << "thread returned failure";
665
666  // Wait for the second child to exit (should get a zero exit code message).
667  AWAIT_INT_MESSAGE(proc_pipe[0], 0);
668
669  // Fire off a new (second) child thread, which is also affected by capability mode.
670  ASSERT_FALSE(testing::Test::HasFailure())
671      << "Cannot continue test with pre-existing failures.";
672  pthread_t child_thread;
673  EXPECT_OK(pthread_create(&child_thread, NULL, thread_fn,
674                           (void *)(intptr_t)thread_pipe[1]));
675  SEND_INT_MESSAGE(thread_pipe[0], MSG_PARENT_CHILD_SHOULD_RUN);
676  EXPECT_OK(pthread_join(child_thread, &thread_rval));
677  EXPECT_FALSE((bool)(intptr_t)thread_rval) << "thread returned failure";
678
679  // Fork a subprocess which fires off a new thread.
680  ASSERT_FALSE(testing::Test::HasFailure())
681              << "Cannot continue test with pre-existing failures.";
682  if (verbose) fprintf(stderr, "  starting third child (in capability mode)\n");
683  child = fork();
684  EXPECT_OK(child);
685  if (child == 0) {
686    if (verbose) fprintf(stderr, "  third child started\n");
687    EXPECT_OK(close(proc_pipe[0]));
688    pthread_t child_thread2;
689    EXPECT_OK(pthread_create(&child_thread2, NULL, thread_fn,
690                             (void *)(intptr_t)thread_pipe[1]));
691    SEND_INT_MESSAGE(thread_pipe[0], MSG_PARENT_CHILD_SHOULD_RUN);
692    EXPECT_OK(pthread_join(child_thread2, &thread_rval));
693    EXPECT_FALSE((bool)(intptr_t)thread_rval) << "thread returned failure";
694    // Notify the parent of success/failure.
695    int rval = (int)testing::Test::HasFailure();
696    SEND_INT_MESSAGE(proc_pipe[1], rval);
697    if (verbose) fprintf(stderr, "  third child finished: %d\n", rval);
698    exit(rval);
699  }
700  // Wait for the third child to exit (should get a zero exit code message).
701  AWAIT_INT_MESSAGE(proc_pipe[0], 0);
702  close(proc_pipe[0]);
703  close(proc_pipe[1]);
704  close(thread_pipe[0]);
705  close(thread_pipe[1]);
706}
707
708static volatile sig_atomic_t had_signal = 0;
709static void handle_signal(int) { had_signal = 1; }
710
711FORK_TEST(Capmode, SelfKill) {
712  pid_t me = getpid();
713  sighandler_t original = signal(SIGUSR1, handle_signal);
714
715  pid_t child = fork();
716  if (child == 0) {
717    // Child: sleep and exit
718    sleep(1);
719    exit(0);
720  }
721
722  EXPECT_OK(cap_enter());  // Enter capability mode.
723
724  // Can only kill(2) to own pid.
725  EXPECT_CAPMODE(kill(child, SIGUSR1));
726  EXPECT_OK(kill(me, SIGUSR1));
727  EXPECT_EQ(1, had_signal);
728
729  signal(SIGUSR1, original);
730}
731