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.
5 #include <sys/socket.h>
7 #include <sys/sockio.h>
10 #include <sys/mount.h>
14 #include <sys/resource.h>
15 #include <sys/ptrace.h>
18 #include <netinet/in.h>
27 #include "capsicum-test.h"
29 // Test fixture that opens (and closes) a bunch of files.
30 class WithFiles : public ::testing::Test {
33 fd_file_(open(TmpFile("cap_capmode"), O_RDWR|O_CREAT, 0644)),
34 fd_close_(open("/dev/null", O_RDWR)),
35 fd_dir_(open(tmpdir.c_str(), O_RDONLY)),
36 fd_socket_(socket(PF_INET, SOCK_DGRAM, 0)),
37 fd_tcp_socket_(socket(PF_INET, SOCK_STREAM, 0)) {
41 EXPECT_OK(fd_socket_);
42 EXPECT_OK(fd_tcp_socket_);
45 if (fd_tcp_socket_ >= 0) close(fd_tcp_socket_);
46 if (fd_socket_ >= 0) close(fd_socket_);
47 if (fd_dir_ >= 0) close(fd_dir_);
48 if (fd_close_ >= 0) close(fd_close_);
49 if (fd_file_ >= 0) close(fd_file_);
50 unlink(TmpFile("cap_capmode"));
60 FORK_TEST_F(WithFiles, DisallowedFileSyscalls) {
61 unsigned int mode = -1;
62 EXPECT_OK(cap_getmode(&mode));
63 EXPECT_EQ(0, (int)mode);
64 EXPECT_OK(cap_enter()); // Enter capability mode.
65 EXPECT_OK(cap_getmode(&mode));
66 EXPECT_EQ(1, (int)mode);
68 // System calls that are not permitted in capability mode.
69 EXPECT_CAPMODE(access(TmpFile("cap_capmode_access"), F_OK));
70 EXPECT_CAPMODE(acct(TmpFile("cap_capmode_acct")));
71 EXPECT_CAPMODE(chdir(TmpFile("cap_capmode_chdir")));
73 EXPECT_CAPMODE(chflags(TmpFile("cap_capmode_chflags"), UF_NODUMP));
75 EXPECT_CAPMODE(chmod(TmpFile("cap_capmode_chmod"), 0644));
76 EXPECT_CAPMODE(chown(TmpFile("cap_capmode_chown"), -1, -1));
77 EXPECT_CAPMODE(chroot(TmpFile("cap_capmode_chroot")));
78 EXPECT_CAPMODE(creat(TmpFile("cap_capmode_creat"), 0644));
79 EXPECT_CAPMODE(fchdir(fd_dir_));
82 EXPECT_CAPMODE(getfsstat(&statfs, sizeof(statfs), MNT_NOWAIT));
84 EXPECT_CAPMODE(link(TmpFile("foo"), TmpFile("bar")));
86 EXPECT_CAPMODE(lstat(TmpFile("cap_capmode_lstat"), &sb));
87 EXPECT_CAPMODE(mknod(TmpFile("capmode_mknod"), 0644 | S_IFIFO, 0));
88 EXPECT_CAPMODE(bogus_mount_());
89 EXPECT_CAPMODE(open("/dev/null", O_RDWR));
91 EXPECT_CAPMODE(readlink(TmpFile("cap_capmode_readlink"), buf, sizeof(buf)));
93 EXPECT_CAPMODE(revoke(TmpFile("cap_capmode_revoke")));
95 EXPECT_CAPMODE(stat(TmpFile("cap_capmode_stat"), &sb));
96 EXPECT_CAPMODE(symlink(TmpFile("cap_capmode_symlink_from"), TmpFile("cap_capmode_symlink_to")));
97 EXPECT_CAPMODE(unlink(TmpFile("cap_capmode_unlink")));
98 EXPECT_CAPMODE(umount2("/not_mounted", 0));
101 FORK_TEST_F(WithFiles, DisallowedSocketSyscalls) {
102 EXPECT_OK(cap_enter()); // Enter capability mode.
104 // System calls that are not permitted in capability mode.
105 struct sockaddr_in addr;
106 addr.sin_family = AF_INET;
108 addr.sin_addr.s_addr = htonl(INADDR_ANY);
109 EXPECT_CAPMODE(bind_(fd_socket_, (sockaddr*)&addr, sizeof(addr)));
110 addr.sin_family = AF_INET;
112 addr.sin_addr.s_addr = htonl(0x08080808);
113 EXPECT_CAPMODE(connect_(fd_tcp_socket_, (sockaddr*)&addr, sizeof(addr)));
116 FORK_TEST_F(WithFiles, AllowedFileSyscalls) {
118 EXPECT_OK(cap_enter()); // Enter capability mode.
120 EXPECT_OK(close(fd_close_));
122 int fd_dup = dup(fd_file_);
124 EXPECT_OK(dup2(fd_file_, fd_dup));
126 EXPECT_OK(dup3(fd_file_, fd_dup, 0));
128 if (fd_dup >= 0) close(fd_dup);
131 EXPECT_OK(fstat(fd_file_, &sb));
132 EXPECT_OK(lseek(fd_file_, 0, SEEK_SET));
134 EXPECT_OK(read(fd_file_, &ch, sizeof(ch)));
135 EXPECT_OK(write(fd_file_, &ch, sizeof(ch)));
138 rc = fchflags(fd_file_, UF_NODUMP);
140 EXPECT_NE(ECAPMODE, errno);
145 rc = getdents_(fd_dir_, (void*)buf, sizeof(buf));
149 EXPECT_OK(pwrite(fd_file_, data, 1, 0));
150 EXPECT_OK(pread(fd_file_, data, 1, 0));
155 #if !defined(__i386__) && !defined(__linux__)
156 // TODO(drysdale): reinstate these tests for 32-bit runs when possible
157 // libc bug is fixed.
158 EXPECT_OK(pwritev(fd_file_, &io, 1, 0));
159 EXPECT_OK(preadv(fd_file_, &io, 1, 0));
161 EXPECT_OK(writev(fd_file_, &io, 1));
162 EXPECT_OK(readv(fd_file_, &io, 1));
165 EXPECT_OK(syncfs(fd_file_));
167 #ifdef HAVE_SYNC_FILE_RANGE
168 EXPECT_OK(sync_file_range(fd_file_, 0, 1, 0));
170 #ifdef HAVE_READAHEAD
171 if (!tmpdir_on_tmpfs) { // tmpfs doesn't support readahead(2)
172 EXPECT_OK(readahead(fd_file_, 0, 1));
177 FORK_TEST_F(WithFiles, AllowedSocketSyscalls) {
178 EXPECT_OK(cap_enter()); // Enter capability mode.
180 // recvfrom() either returns -1 with EAGAIN, or 0.
181 int rc = recvfrom(fd_socket_, NULL, 0, MSG_DONTWAIT, NULL, NULL);
183 EXPECT_EQ(EAGAIN, errno);
186 EXPECT_OK(write(fd_file_, &ch, sizeof(ch)));
188 // These calls will fail for lack of e.g. a proper name to send to,
189 // but they are allowed in capability mode, so errno != ECAPMODE.
190 EXPECT_FAIL_NOT_CAPMODE(accept(fd_socket_, NULL, NULL));
191 EXPECT_FAIL_NOT_CAPMODE(getpeername(fd_socket_, NULL, NULL));
192 EXPECT_FAIL_NOT_CAPMODE(getsockname(fd_socket_, NULL, NULL));
193 EXPECT_FAIL_NOT_CAPMODE(recvmsg(fd_socket_, NULL, 0));
194 EXPECT_FAIL_NOT_CAPMODE(sendmsg(fd_socket_, NULL, 0));
195 EXPECT_FAIL_NOT_CAPMODE(sendto(fd_socket_, NULL, 0, 0, NULL, 0));
197 EXPECT_FAIL_NOT_CAPMODE(sendfile_(fd_socket_, fd_file_, &offset, 1));
199 // The socket/socketpair syscalls are allowed, but they don't give
200 // anything externally useful (can't call bind/connect on them).
201 int fd_socket2 = socket(PF_INET, SOCK_DGRAM, 0);
202 EXPECT_OK(fd_socket2);
203 if (fd_socket2 >= 0) close(fd_socket2);
204 int fd_pair[2] = {-1, -1};
205 EXPECT_OK(socketpair(AF_UNIX, SOCK_STREAM, 0, fd_pair));
206 if (fd_pair[0] >= 0) close(fd_pair[0]);
207 if (fd_pair[1] >= 0) close(fd_pair[1]);
210 FORK_TEST_F(WithFiles, AllowedSocketSyscallsIfRoot) {
211 GTEST_SKIP_IF_NOT_ROOT();
213 EXPECT_OK(cap_enter()); // Enter capability mode.
215 // Creation of raw sockets is not permitted in capability mode.
216 EXPECT_CAPMODE(socket(AF_INET, SOCK_RAW, 0));
217 EXPECT_CAPMODE(socket(AF_INET, SOCK_RAW, IPPROTO_ICMP));
218 EXPECT_CAPMODE(socket(AF_INET, SOCK_RAW, IPPROTO_TCP));
219 EXPECT_CAPMODE(socket(AF_INET, SOCK_RAW, IPPROTO_UDP));
221 EXPECT_CAPMODE(socket(AF_INET6, SOCK_RAW, IPPROTO_ICMP));
222 EXPECT_CAPMODE(socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6));
223 EXPECT_CAPMODE(socket(AF_INET6, SOCK_RAW, IPPROTO_TCP));
224 EXPECT_CAPMODE(socket(AF_INET6, SOCK_RAW, IPPROTO_UDP));
226 EXPECT_CAPMODE(socket(AF_ROUTE, SOCK_RAW, 0));
228 // Interface configuration ioctls are not permitted in capability
231 // This test is disabled for now as the corresponding kernel change was
235 struct if_clonereq req;
239 req.ifcr_buffer = static_cast<char *>(malloc(IFNAMSIZ));
241 EXPECT_CAPMODE(ioctl(fd_socket_, SIOCIFGCLONERS, &req));
243 free(req.ifcr_buffer);
248 #ifdef HAVE_SEND_RECV_MMSG
249 FORK_TEST(Capmode, AllowedMmsgSendRecv) {
250 int fd_socket = socket(PF_INET, SOCK_DGRAM, 0);
252 struct sockaddr_in addr;
253 addr.sin_family = AF_INET;
254 addr.sin_port = htons(0);
255 addr.sin_addr.s_addr = htonl(INADDR_ANY);
256 EXPECT_OK(bind(fd_socket, (sockaddr*)&addr, sizeof(addr)));
258 EXPECT_OK(cap_enter()); // Enter capability mode.
260 char buffer[256] = {0};
262 iov.iov_base = buffer;
263 iov.iov_len = sizeof(buffer);
265 memset(&mm, 0, sizeof(mm));
266 mm.msg_hdr.msg_iov = &iov;
267 mm.msg_hdr.msg_iovlen = 1;
271 EXPECT_FAIL_NOT_CAPMODE(recvmmsg(fd_socket, &mm, 1, MSG_DONTWAIT, &ts));
272 EXPECT_FAIL_NOT_CAPMODE(sendmmsg(fd_socket, &mm, 1, 0));
277 FORK_TEST(Capmode, AllowedIdentifierSyscalls) {
278 // Record some identifiers
279 gid_t my_gid = getgid();
280 pid_t my_pid = getpid();
281 pid_t my_ppid = getppid();
282 uid_t my_uid = getuid();
283 pid_t my_sid = getsid(my_pid);
285 EXPECT_OK(cap_enter()); // Enter capability mode.
287 EXPECT_EQ(my_gid, getegid_());
288 EXPECT_EQ(my_uid, geteuid_());
289 EXPECT_EQ(my_gid, getgid_());
290 EXPECT_EQ(my_pid, getpid());
291 EXPECT_EQ(my_ppid, getppid());
292 EXPECT_EQ(my_uid, getuid_());
293 EXPECT_EQ(my_sid, getsid(my_pid));
295 EXPECT_OK(getgroups_(128, grps));
299 EXPECT_OK(getresuid(&ruid, &euid, &suid));
303 EXPECT_OK(getresgid(&rgid, &egid, &sgid));
305 EXPECT_TRUE(getlogin() != NULL);
308 // Set various identifiers (to their existing values).
309 EXPECT_OK(setgid(my_gid));
311 EXPECT_OK(setfsgid(my_gid));
313 EXPECT_OK(setuid(my_uid));
315 EXPECT_OK(setfsuid(my_uid));
317 EXPECT_OK(setregid(my_gid, my_gid));
318 EXPECT_OK(setresgid(my_gid, my_gid, my_gid));
319 EXPECT_OK(setreuid(my_uid, my_uid));
320 EXPECT_OK(setresuid(my_uid, my_uid, my_uid));
324 FORK_TEST(Capmode, AllowedSchedSyscalls) {
325 EXPECT_OK(cap_enter()); // Enter capability mode.
326 int policy = sched_getscheduler(0);
328 struct sched_param sp;
329 EXPECT_OK(sched_getparam(0, &sp));
330 if (policy >= 0 && (!SCHED_SETSCHEDULER_REQUIRES_ROOT || getuid() == 0)) {
331 EXPECT_OK(sched_setscheduler(0, policy, &sp));
333 EXPECT_OK(sched_setparam(0, &sp));
334 EXPECT_OK(sched_get_priority_max(policy));
335 EXPECT_OK(sched_get_priority_min(policy));
337 EXPECT_OK(sched_rr_get_interval(0, &ts));
338 EXPECT_OK(sched_yield());
342 FORK_TEST(Capmode, AllowedTimerSyscalls) {
343 EXPECT_OK(cap_enter()); // Enter capability mode.
345 EXPECT_OK(clock_getres(CLOCK_REALTIME, &ts));
346 EXPECT_OK(clock_gettime(CLOCK_REALTIME, &ts));
347 struct itimerval itv;
348 EXPECT_OK(getitimer(ITIMER_REAL, &itv));
349 EXPECT_OK(setitimer(ITIMER_REAL, &itv, NULL));
352 EXPECT_OK(gettimeofday(&tv, &tz));
355 EXPECT_OK(nanosleep(&ts, NULL));
359 FORK_TEST(Capmode, AllowedProfilSyscall) {
360 EXPECT_OK(cap_enter()); // Enter capability mode.
362 EXPECT_OK(profil((profil_arg1_t*)sbuf, sizeof(sbuf), 0, 1));
366 FORK_TEST(Capmode, AllowedResourceSyscalls) {
367 EXPECT_OK(cap_enter()); // Enter capability mode.
369 int rc = getpriority(PRIO_PROCESS, 0);
371 EXPECT_OK(setpriority(PRIO_PROCESS, 0, rc));
373 EXPECT_OK(getrlimit_(RLIMIT_CORE, &rlim));
374 EXPECT_OK(setrlimit(RLIMIT_CORE, &rlim));
376 EXPECT_OK(getrusage(RUSAGE_SELF, &ruse));
379 FORK_TEST(CapMode, AllowedMmapSyscalls) {
380 // mmap() some memory.
381 size_t mem_size = getpagesize();
382 void *mem = mmap(NULL, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
383 EXPECT_TRUE(mem != NULL);
384 EXPECT_OK(cap_enter()); // Enter capability mode.
386 EXPECT_OK(msync(mem, mem_size, MS_ASYNC));
387 EXPECT_OK(madvise(mem, mem_size, MADV_NORMAL));
388 unsigned char vec[2];
389 EXPECT_OK(mincore_(mem, mem_size, vec));
390 EXPECT_OK(mprotect(mem, mem_size, PROT_READ|PROT_WRITE));
392 if (!MLOCK_REQUIRES_ROOT || getuid() == 0) {
393 EXPECT_OK(mlock(mem, mem_size));
394 EXPECT_OK(munlock(mem, mem_size));
395 int rc = mlockall(MCL_CURRENT);
397 // mlockall may well fail with ENOMEM for non-root users, as the
398 // default RLIMIT_MEMLOCK value isn't that big.
399 EXPECT_NE(ECAPMODE, errno);
401 EXPECT_OK(munlockall());
404 EXPECT_OK(munmap(mem, mem_size));
407 FORK_TEST(Capmode, AllowedPipeSyscalls) {
408 EXPECT_OK(cap_enter()); // Enter capability mode
414 char buf[11] = "0123456789";
417 iov.iov_len = sizeof(buf);
418 EXPECT_FAIL_NOT_CAPMODE(vmsplice(fd2[0], &iov, 1, SPLICE_F_NONBLOCK));
435 TEST(Capmode, AllowedAtSyscalls) {
436 int rc = mkdir(TmpFile("cap_at_syscalls"), 0755);
438 if (rc < 0 && errno != EEXIST) return;
439 int dfd = open(TmpFile("cap_at_syscalls"), O_RDONLY);
442 int file = openat(dfd, "testfile", O_RDONLY|O_CREAT, 0644);
444 EXPECT_OK(close(file));
447 pid_t child = fork();
449 // Child: enter cap mode and run tests
450 EXPECT_OK(cap_enter()); // Enter capability mode
453 EXPECT_OK(fstatat(dfd, "testfile", &fs, 0));
454 EXPECT_OK(mkdirat(dfd, "subdir", 0600));
455 EXPECT_OK(fchmodat(dfd, "subdir", 0644, 0));
456 EXPECT_OK(faccessat(dfd, "subdir", F_OK, 0));
457 EXPECT_OK(renameat(dfd, "subdir", dfd, "subdir2"));
458 EXPECT_OK(renameat(dfd, "subdir2", dfd, "subdir"));
459 struct timeval tv[2];
461 EXPECT_OK(gettimeofday(&tv[0], &tz));
462 EXPECT_OK(gettimeofday(&tv[1], &tz));
463 EXPECT_OK(futimesat(dfd, "testfile", tv));
465 EXPECT_OK(fchownat(dfd, "testfile", fs.st_uid, fs.st_gid, 0));
466 EXPECT_OK(linkat(dfd, "testfile", dfd, "linky", 0));
467 EXPECT_OK(symlinkat("testfile", dfd, "symlink"));
469 EXPECT_OK(readlinkat(dfd, "symlink", buffer, sizeof(buffer)));
470 EXPECT_OK(unlinkat(dfd, "linky", 0));
471 EXPECT_OK(unlinkat(dfd, "subdir", AT_REMOVEDIR));
473 // Check that invalid requests get a non-Capsicum errno.
475 rc = readlinkat(-1, "symlink", buffer, sizeof(buffer));
477 EXPECT_NE(ECAPMODE, errno);
482 // Wait for the child.
484 EXPECT_EQ(child, waitpid(child, &status, 0));
485 rc = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
490 rmdir(TmpFile("cap_at_syscalls/subdir"));
491 unlink(TmpFile("cap_at_syscalls/symlink"));
492 unlink(TmpFile("cap_at_syscalls/linky"));
493 unlink(TmpFile("cap_at_syscalls/testfile"));
494 rmdir(TmpFile("cap_at_syscalls"));
497 TEST(Capmode, AllowedAtSyscallsCwd) {
498 int rc = mkdir(TmpFile("cap_at_syscalls_cwd"), 0755);
500 if (rc < 0 && errno != EEXIST) return;
501 int dfd = open(TmpFile("cap_at_syscalls_cwd"), O_RDONLY);
504 int file = openat(dfd, "testfile", O_RDONLY|O_CREAT, 0644);
506 EXPECT_OK(close(file));
508 pid_t child = fork();
510 // Child: move into temp dir, enter cap mode and run tests
511 EXPECT_OK(fchdir(dfd));
512 EXPECT_OK(cap_enter()); // Enter capability mode
514 // Test that *at(AT_FDCWD, path,...) is policed with ECAPMODE.
515 EXPECT_CAPMODE(openat(AT_FDCWD, "testfile", O_RDONLY));
517 EXPECT_CAPMODE(fstatat(AT_FDCWD, "testfile", &fs, 0));
518 EXPECT_CAPMODE(mkdirat(AT_FDCWD, "subdir", 0600));
519 EXPECT_CAPMODE(fchmodat(AT_FDCWD, "subdir", 0644, 0));
520 EXPECT_CAPMODE(faccessat(AT_FDCWD, "subdir", F_OK, 0));
521 EXPECT_CAPMODE(renameat(AT_FDCWD, "subdir", AT_FDCWD, "subdir2"));
522 EXPECT_CAPMODE(renameat(AT_FDCWD, "subdir2", AT_FDCWD, "subdir"));
523 struct timeval tv[2];
525 EXPECT_OK(gettimeofday(&tv[0], &tz));
526 EXPECT_OK(gettimeofday(&tv[1], &tz));
527 EXPECT_CAPMODE(futimesat(AT_FDCWD, "testfile", tv));
529 EXPECT_CAPMODE(fchownat(AT_FDCWD, "testfile", fs.st_uid, fs.st_gid, 0));
530 EXPECT_CAPMODE(linkat(AT_FDCWD, "testfile", AT_FDCWD, "linky", 0));
531 EXPECT_CAPMODE(symlinkat("testfile", AT_FDCWD, "symlink"));
533 EXPECT_CAPMODE(readlinkat(AT_FDCWD, "symlink", buffer, sizeof(buffer)));
534 EXPECT_CAPMODE(unlinkat(AT_FDCWD, "linky", 0));
539 // Wait for the child.
541 EXPECT_EQ(child, waitpid(child, &status, 0));
542 rc = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
547 rmdir(TmpFile("cap_at_syscalls_cwd/subdir"));
548 unlink(TmpFile("cap_at_syscalls_cwd/symlink"));
549 unlink(TmpFile("cap_at_syscalls_cwd/linky"));
550 unlink(TmpFile("cap_at_syscalls_cwd/testfile"));
551 rmdir(TmpFile("cap_at_syscalls_cwd"));
554 TEST(Capmode, Abort) {
555 // Check that abort(3) works even in capability mode.
556 pid_t child = fork();
558 // Child: enter capability mode and call abort(3).
559 // Triggers something like kill(getpid(), SIGABRT).
560 cap_enter(); // Enter capability mode.
565 EXPECT_EQ(child, waitpid(child, &status, 0));
566 EXPECT_TRUE(WIFSIGNALED(status)) << " status = " << std::hex << status;
567 EXPECT_EQ(SIGABRT, WTERMSIG(status)) << " status = " << std::hex << status;
570 FORK_TEST_F(WithFiles, AllowedMiscSyscalls) {
572 mode_t um_before = umask(022);
574 EXPECT_OK(pipe(pipefds));
575 EXPECT_OK(cap_enter()); // Enter capability mode.
577 mode_t um = umask(022);
578 EXPECT_NE(-ECAPMODE, (int)um);
579 EXPECT_EQ(um_before, um);
581 EXPECT_OK(sigaltstack(NULL, &ss));
583 // Finally, tests for system calls that don't fit the pattern very well.
587 // Child: wait for an exit message from parent (so we can test waitpid).
588 EXPECT_OK(close(pipefds[0]));
589 SEND_INT_MESSAGE(pipefds[1], MSG_CHILD_STARTED);
590 AWAIT_INT_MESSAGE(pipefds[1], MSG_PARENT_REQUEST_CHILD_EXIT);
592 } else if (pid > 0) {
593 EXPECT_OK(close(pipefds[1]));
594 AWAIT_INT_MESSAGE(pipefds[0], MSG_CHILD_STARTED);
596 EXPECT_CAPMODE(ptrace_(PTRACE_PEEKDATA_, pid, &pid, NULL));
597 EXPECT_CAPMODE(waitpid(pid, NULL, WNOHANG));
598 SEND_INT_MESSAGE(pipefds[0], MSG_PARENT_REQUEST_CHILD_EXIT);
599 if (verbose) fprintf(stderr, " child finished\n");
602 // No error return from sync(2) to test, but check errno remains unset.
607 // TODO(FreeBSD): ktrace
610 // sysarch() is, by definition, architecture-dependent
611 #if defined (__amd64__) || defined (__i386__)
612 long sysarch_arg = 0;
613 EXPECT_CAPMODE(sysarch(I386_SET_IOPERM, &sysarch_arg));
615 // TOOD(jra): write a test for other architectures, like arm
620 void *thread_fn(void *p) {
621 int fd = (int)(intptr_t)p;
622 if (verbose) fprintf(stderr, " thread waiting to run\n");
623 AWAIT_INT_MESSAGE(fd, MSG_PARENT_CHILD_SHOULD_RUN);
624 EXPECT_OK(getpid_());
625 EXPECT_CAPMODE(open("/dev/null", O_RDWR));
626 // Return whether there have been any failures to the main thread.
627 void *rval = (void *)(intptr_t)testing::Test::HasFailure();
628 if (verbose) fprintf(stderr, " thread finished: %p\n", rval);
632 // Check that restrictions are the same in subprocesses and threads
633 FORK_TEST(Capmode, NewThread) {
634 // Fire off a new thread before entering capability mode
635 pthread_t early_thread;
637 // Create two pipes, one for synchronization with the threads, the other to
638 // synchronize with the children (since we can't use waitpid after cap_enter).
639 // Note: Could use pdfork+pdwait instead, but that is tested in procdesc.cc.
641 EXPECT_OK(pipe(thread_pipe));
643 EXPECT_OK(pipe(proc_pipe));
644 EXPECT_OK(pthread_create(&early_thread, NULL, thread_fn,
645 (void *)(intptr_t)thread_pipe[1]));
647 // Fire off a new process before entering capability mode.
648 if (verbose) fprintf(stderr, " starting second child (non-capability mode)\n");
649 int early_child = fork();
650 EXPECT_OK(early_child);
651 if (early_child == 0) {
652 if (verbose) fprintf(stderr, " first child started\n");
653 EXPECT_OK(close(proc_pipe[0]));
654 // Child: wait and then confirm this process is unaffected by capability mode in the parent.
655 AWAIT_INT_MESSAGE(proc_pipe[1], MSG_PARENT_CHILD_SHOULD_RUN);
656 int fd = open("/dev/null", O_RDWR);
659 // Notify the parent of success/failure.
660 int rval = (int)testing::Test::HasFailure();
661 SEND_INT_MESSAGE(proc_pipe[1], rval);
662 if (verbose) fprintf(stderr, " first child finished: %d\n", rval);
666 EXPECT_OK(cap_enter()); // Enter capability mode.
667 // At this point the current process has both a child process and a
668 // child thread that were created before entering capability mode.
669 // - The child process is unaffected by capability mode.
670 // - The child thread is affected by capability mode.
671 SEND_INT_MESSAGE(proc_pipe[0], MSG_PARENT_CHILD_SHOULD_RUN);
673 // Do an allowed syscall.
674 EXPECT_OK(getpid_());
675 // Wait for the first child to exit (should get a zero exit code message).
676 AWAIT_INT_MESSAGE(proc_pipe[0], 0);
678 // The child processes/threads return HasFailure(), so we depend on no prior errors.
679 ASSERT_FALSE(testing::Test::HasFailure())
680 << "Cannot continue test with pre-existing failures.";
681 // Now that we're in capability mode, if we create a second child process
682 // it will be affected by capability mode.
683 if (verbose) fprintf(stderr, " starting second child (in capability mode)\n");
687 if (verbose) fprintf(stderr, " second child started\n");
688 EXPECT_OK(close(proc_pipe[0]));
689 // Child: do an allowed and a disallowed syscall.
690 EXPECT_OK(getpid_());
691 EXPECT_CAPMODE(open("/dev/null", O_RDWR));
692 // Notify the parent of success/failure.
693 int rval = (int)testing::Test::HasFailure();
694 SEND_INT_MESSAGE(proc_pipe[1], rval);
695 if (verbose) fprintf(stderr, " second child finished: %d\n", rval);
698 // Now tell the early_started thread that it can run. We expect it to also
699 // be affected by capability mode since it's per-process not per-thread.
700 // Note: it is important that we don't allow the thread to run before fork(),
701 // since that could result in fork() being called while the thread holds one
702 // of the gtest-internal mutexes, so the child process deadlocks.
703 SEND_INT_MESSAGE(thread_pipe[0], MSG_PARENT_CHILD_SHOULD_RUN);
704 // Wait for the early-started thread.
705 EXPECT_OK(pthread_join(early_thread, &thread_rval));
706 EXPECT_FALSE((bool)(intptr_t)thread_rval) << "thread returned failure";
708 // Wait for the second child to exit (should get a zero exit code message).
709 AWAIT_INT_MESSAGE(proc_pipe[0], 0);
711 // Fire off a new (second) child thread, which is also affected by capability mode.
712 ASSERT_FALSE(testing::Test::HasFailure())
713 << "Cannot continue test with pre-existing failures.";
714 pthread_t child_thread;
715 EXPECT_OK(pthread_create(&child_thread, NULL, thread_fn,
716 (void *)(intptr_t)thread_pipe[1]));
717 SEND_INT_MESSAGE(thread_pipe[0], MSG_PARENT_CHILD_SHOULD_RUN);
718 EXPECT_OK(pthread_join(child_thread, &thread_rval));
719 EXPECT_FALSE((bool)(intptr_t)thread_rval) << "thread returned failure";
721 // Fork a subprocess which fires off a new thread.
722 ASSERT_FALSE(testing::Test::HasFailure())
723 << "Cannot continue test with pre-existing failures.";
724 if (verbose) fprintf(stderr, " starting third child (in capability mode)\n");
728 if (verbose) fprintf(stderr, " third child started\n");
729 EXPECT_OK(close(proc_pipe[0]));
730 pthread_t child_thread2;
731 EXPECT_OK(pthread_create(&child_thread2, NULL, thread_fn,
732 (void *)(intptr_t)thread_pipe[1]));
733 SEND_INT_MESSAGE(thread_pipe[0], MSG_PARENT_CHILD_SHOULD_RUN);
734 EXPECT_OK(pthread_join(child_thread2, &thread_rval));
735 EXPECT_FALSE((bool)(intptr_t)thread_rval) << "thread returned failure";
736 // Notify the parent of success/failure.
737 int rval = (int)testing::Test::HasFailure();
738 SEND_INT_MESSAGE(proc_pipe[1], rval);
739 if (verbose) fprintf(stderr, " third child finished: %d\n", rval);
742 // Wait for the third child to exit (should get a zero exit code message).
743 AWAIT_INT_MESSAGE(proc_pipe[0], 0);
746 close(thread_pipe[0]);
747 close(thread_pipe[1]);
750 static volatile sig_atomic_t had_signal = 0;
751 static void handle_signal(int) { had_signal = 1; }
753 FORK_TEST(Capmode, SelfKill) {
755 sighandler_t original = signal(SIGUSR1, handle_signal);
757 pid_t child = fork();
759 // Child: sleep and exit
764 EXPECT_OK(cap_enter()); // Enter capability mode.
766 // Can only kill(2) to own pid.
767 EXPECT_CAPMODE(kill(child, SIGUSR1));
768 EXPECT_OK(kill(me, SIGUSR1));
769 EXPECT_EQ(1, had_signal);
771 signal(SIGUSR1, original);