xref: /freebsd/contrib/capsicum-test/capmode.cc (revision 8e8f1cc9)
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 #ifdef __FreeBSD__
7 #include <sys/sockio.h>
8 #endif
9 #include <sys/stat.h>
10 #include <sys/mount.h>
11 #include <sys/mman.h>
12 #include <sys/wait.h>
13 #include <sys/time.h>
14 #include <sys/resource.h>
15 #include <sys/ptrace.h>
16 #include <dirent.h>
17 #include <net/if.h>
18 #include <netinet/in.h>
19 #include <fcntl.h>
20 #include <sched.h>
21 #include <time.h>
22 #include <unistd.h>
23 #include <pthread.h>
24 
25 #include "capsicum.h"
26 #include "syscalls.h"
27 #include "capsicum-test.h"
28 
29 // Test fixture that opens (and closes) a bunch of files.
30 class WithFiles : public ::testing::Test {
31  public:
WithFiles()32   WithFiles() :
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)) {
38     EXPECT_OK(fd_file_);
39     EXPECT_OK(fd_close_);
40     EXPECT_OK(fd_dir_);
41     EXPECT_OK(fd_socket_);
42     EXPECT_OK(fd_tcp_socket_);
43   }
~WithFiles()44   ~WithFiles() {
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"));
51   }
52  protected:
53   int fd_file_;
54   int fd_close_;
55   int fd_dir_;
56   int fd_socket_;
57   int fd_tcp_socket_;
58 };
59 
FORK_TEST_F(WithFiles,DisallowedFileSyscalls)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);
67 
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")));
72 #ifdef HAVE_CHFLAGS
73   EXPECT_CAPMODE(chflags(TmpFile("cap_capmode_chflags"), UF_NODUMP));
74 #endif
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_));
80 #ifdef HAVE_GETFSSTAT
81   struct statfs statfs;
82   EXPECT_CAPMODE(getfsstat(&statfs, sizeof(statfs), MNT_NOWAIT));
83 #endif
84   EXPECT_CAPMODE(link(TmpFile("foo"), TmpFile("bar")));
85   struct stat sb;
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));
90   char buf[64];
91   EXPECT_CAPMODE(readlink(TmpFile("cap_capmode_readlink"), buf, sizeof(buf)));
92 #ifdef HAVE_REVOKE
93   EXPECT_CAPMODE(revoke(TmpFile("cap_capmode_revoke")));
94 #endif
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));
99 }
100 
FORK_TEST_F(WithFiles,DisallowedSocketSyscalls)101 FORK_TEST_F(WithFiles, DisallowedSocketSyscalls) {
102   EXPECT_OK(cap_enter());  // Enter capability mode.
103 
104   // System calls that are not permitted in capability mode.
105   struct sockaddr_in addr;
106   addr.sin_family = AF_INET;
107   addr.sin_port = 0;
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;
111   addr.sin_port = 53;
112   addr.sin_addr.s_addr = htonl(0x08080808);
113   EXPECT_CAPMODE(connect_(fd_tcp_socket_, (sockaddr*)&addr, sizeof(addr)));
114 }
115 
FORK_TEST_F(WithFiles,AllowedFileSyscalls)116 FORK_TEST_F(WithFiles, AllowedFileSyscalls) {
117   int rc;
118   EXPECT_OK(cap_enter());  // Enter capability mode.
119 
120   EXPECT_OK(close(fd_close_));
121   fd_close_ = -1;
122   int fd_dup = dup(fd_file_);
123   EXPECT_OK(fd_dup);
124   EXPECT_OK(dup2(fd_file_, fd_dup));
125 #ifdef HAVE_DUP3
126   EXPECT_OK(dup3(fd_file_, fd_dup, 0));
127 #endif
128   if (fd_dup >= 0) close(fd_dup);
129 
130   struct stat sb;
131   EXPECT_OK(fstat(fd_file_, &sb));
132   EXPECT_OK(lseek(fd_file_, 0, SEEK_SET));
133   char ch;
134   EXPECT_OK(read(fd_file_, &ch, sizeof(ch)));
135   EXPECT_OK(write(fd_file_, &ch, sizeof(ch)));
136 
137 #ifdef HAVE_CHFLAGS
138   rc = fchflags(fd_file_, UF_NODUMP);
139   if (rc < 0) {
140     EXPECT_NE(ECAPMODE, errno);
141   }
142 #endif
143 
144   char buf[1024];
145   rc = getdents_(fd_dir_, (void*)buf, sizeof(buf));
146   EXPECT_OK(rc);
147 
148   char data[] = "123";
149   EXPECT_OK(pwrite(fd_file_, data, 1, 0));
150   EXPECT_OK(pread(fd_file_, data, 1, 0));
151 
152   struct iovec io;
153   io.iov_base = data;
154   io.iov_len = 2;
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));
160 #endif
161   EXPECT_OK(writev(fd_file_, &io, 1));
162   EXPECT_OK(readv(fd_file_, &io, 1));
163 
164 #ifdef HAVE_SYNCFS
165   EXPECT_OK(syncfs(fd_file_));
166 #endif
167 #ifdef HAVE_SYNC_FILE_RANGE
168   EXPECT_OK(sync_file_range(fd_file_, 0, 1, 0));
169 #endif
170 #ifdef HAVE_READAHEAD
171   if (!tmpdir_on_tmpfs) {  // tmpfs doesn't support readahead(2)
172     EXPECT_OK(readahead(fd_file_, 0, 1));
173   }
174 #endif
175 }
176 
FORK_TEST_F(WithFiles,AllowedSocketSyscalls)177 FORK_TEST_F(WithFiles, AllowedSocketSyscalls) {
178   EXPECT_OK(cap_enter());  // Enter capability mode.
179 
180   // recvfrom() either returns -1 with EAGAIN, or 0.
181   int rc = recvfrom(fd_socket_, NULL, 0, MSG_DONTWAIT, NULL, NULL);
182   if (rc < 0) {
183     EXPECT_EQ(EAGAIN, errno);
184   }
185   char ch;
186   EXPECT_OK(write(fd_file_, &ch, sizeof(ch)));
187 
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));
196   off_t offset = 0;
197   EXPECT_FAIL_NOT_CAPMODE(sendfile_(fd_socket_, fd_file_, &offset, 1));
198 
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]);
208 }
209 
FORK_TEST_F(WithFiles,AllowedSocketSyscallsIfRoot)210 FORK_TEST_F(WithFiles, AllowedSocketSyscallsIfRoot) {
211   GTEST_SKIP_IF_NOT_ROOT();
212 
213   EXPECT_OK(cap_enter());  // Enter capability mode.
214 
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));
220 
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));
225 
226   EXPECT_CAPMODE(socket(AF_ROUTE, SOCK_RAW, 0));
227 
228   // Interface configuration ioctls are not permitted in capability
229   // mode.
230   //
231   // This test is disabled for now as the corresponding kernel change was
232   // disabled.
233 #if 0
234 #ifdef __FreeBSD__
235   struct if_clonereq req;
236 
237   req.ifcr_total = 0;
238   req.ifcr_count = 1;
239   req.ifcr_buffer = static_cast<char *>(malloc(IFNAMSIZ));
240 
241   EXPECT_CAPMODE(ioctl(fd_socket_, SIOCIFGCLONERS, &req));
242 
243   free(req.ifcr_buffer);
244 #endif
245 #endif
246 }
247 
248 #ifdef HAVE_SEND_RECV_MMSG
FORK_TEST(Capmode,AllowedMmsgSendRecv)249 FORK_TEST(Capmode, AllowedMmsgSendRecv) {
250   int fd_socket = socket(PF_INET, SOCK_DGRAM, 0);
251 
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)));
257 
258   EXPECT_OK(cap_enter());  // Enter capability mode.
259 
260   char buffer[256] = {0};
261   struct iovec iov;
262   iov.iov_base = buffer;
263   iov.iov_len = sizeof(buffer);
264   struct mmsghdr mm;
265   memset(&mm, 0, sizeof(mm));
266   mm.msg_hdr.msg_iov = &iov;
267   mm.msg_hdr.msg_iovlen = 1;
268   struct timespec ts;
269   ts.tv_sec = 1;
270   ts.tv_nsec = 100;
271   EXPECT_FAIL_NOT_CAPMODE(recvmmsg(fd_socket, &mm, 1, MSG_DONTWAIT, &ts));
272   EXPECT_FAIL_NOT_CAPMODE(sendmmsg(fd_socket, &mm, 1, 0));
273   close(fd_socket);
274 }
275 #endif
276 
FORK_TEST(Capmode,AllowedIdentifierSyscalls)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);
284 
285   EXPECT_OK(cap_enter());  // Enter capability mode.
286 
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));
294   gid_t grps[128];
295   EXPECT_OK(getgroups_(128, grps));
296   uid_t ruid;
297   uid_t euid;
298   uid_t suid;
299   EXPECT_OK(getresuid(&ruid, &euid, &suid));
300   gid_t rgid;
301   gid_t egid;
302   gid_t sgid;
303   EXPECT_OK(getresgid(&rgid, &egid, &sgid));
304 #ifdef HAVE_GETLOGIN
305   EXPECT_TRUE(getlogin() != NULL);
306 #endif
307 
308   // Set various identifiers (to their existing values).
309   EXPECT_OK(setgid(my_gid));
310 #ifdef HAVE_SETFSGID
311   EXPECT_OK(setfsgid(my_gid));
312 #endif
313   EXPECT_OK(setuid(my_uid));
314 #ifdef HAVE_SETFSUID
315   EXPECT_OK(setfsuid(my_uid));
316 #endif
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));
321   EXPECT_OK(setsid());
322 }
323 
FORK_TEST(Capmode,AllowedSchedSyscalls)324 FORK_TEST(Capmode, AllowedSchedSyscalls) {
325   EXPECT_OK(cap_enter());  // Enter capability mode.
326   int policy = sched_getscheduler(0);
327   EXPECT_OK(policy);
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));
332   }
333   EXPECT_OK(sched_setparam(0, &sp));
334   EXPECT_OK(sched_get_priority_max(policy));
335   EXPECT_OK(sched_get_priority_min(policy));
336   struct timespec ts;
337   EXPECT_OK(sched_rr_get_interval(0, &ts));
338   EXPECT_OK(sched_yield());
339 }
340 
341 
FORK_TEST(Capmode,AllowedTimerSyscalls)342 FORK_TEST(Capmode, AllowedTimerSyscalls) {
343   EXPECT_OK(cap_enter());  // Enter capability mode.
344   struct timespec ts;
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));
350   struct timeval tv;
351   struct timezone tz;
352   EXPECT_OK(gettimeofday(&tv, &tz));
353   ts.tv_sec = 0;
354   ts.tv_nsec = 1;
355   EXPECT_OK(nanosleep(&ts, NULL));
356 }
357 
358 
FORK_TEST(Capmode,AllowedProfilSyscall)359 FORK_TEST(Capmode, AllowedProfilSyscall) {
360   EXPECT_OK(cap_enter());  // Enter capability mode.
361   char sbuf[32];
362   EXPECT_OK(profil((profil_arg1_t*)sbuf, sizeof(sbuf), 0, 1));
363 }
364 
365 
FORK_TEST(Capmode,AllowedResourceSyscalls)366 FORK_TEST(Capmode, AllowedResourceSyscalls) {
367   EXPECT_OK(cap_enter());  // Enter capability mode.
368   errno = 0;
369   int rc = getpriority(PRIO_PROCESS, 0);
370   EXPECT_EQ(0, errno);
371   EXPECT_OK(setpriority(PRIO_PROCESS, 0, rc));
372   struct rlimit rlim;
373   EXPECT_OK(getrlimit_(RLIMIT_CORE, &rlim));
374   EXPECT_OK(setrlimit(RLIMIT_CORE, &rlim));
375   struct rusage ruse;
376   EXPECT_OK(getrusage(RUSAGE_SELF, &ruse));
377 }
378 
FORK_TEST(CapMode,AllowedMmapSyscalls)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.
385 
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));
391 
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);
396     if (rc != 0) {
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);
400     }
401     EXPECT_OK(munlockall());
402   }
403   // Unmap the memory.
404   EXPECT_OK(munmap(mem, mem_size));
405 }
406 
FORK_TEST(Capmode,AllowedPipeSyscalls)407 FORK_TEST(Capmode, AllowedPipeSyscalls) {
408   EXPECT_OK(cap_enter());  // Enter capability mode
409   int fd2[2];
410   int rc = pipe(fd2);
411   EXPECT_EQ(0, rc);
412 
413 #ifdef HAVE_VMSPLICE
414   char buf[11] = "0123456789";
415   struct iovec iov;
416   iov.iov_base = buf;
417   iov.iov_len = sizeof(buf);
418   EXPECT_FAIL_NOT_CAPMODE(vmsplice(fd2[0], &iov, 1, SPLICE_F_NONBLOCK));
419 #endif
420 
421   if (rc == 0) {
422     close(fd2[0]);
423     close(fd2[1]);
424   };
425 #ifdef HAVE_PIPE2
426   rc = pipe2(fd2, 0);
427   EXPECT_EQ(0, rc);
428   if (rc == 0) {
429     close(fd2[0]);
430     close(fd2[1]);
431   };
432 #endif
433 }
434 
TEST(Capmode,AllowedAtSyscalls)435 TEST(Capmode, AllowedAtSyscalls) {
436   int rc = mkdir(TmpFile("cap_at_syscalls"), 0755);
437   EXPECT_OK(rc);
438   if (rc < 0 && errno != EEXIST) return;
439   int dfd = open(TmpFile("cap_at_syscalls"), O_RDONLY);
440   EXPECT_OK(dfd);
441 
442   int file = openat(dfd, "testfile", O_RDONLY|O_CREAT, 0644);
443   EXPECT_OK(file);
444   EXPECT_OK(close(file));
445 
446 
447   pid_t child = fork();
448   if (child == 0) {
449     // Child: enter cap mode and run tests
450     EXPECT_OK(cap_enter());  // Enter capability mode
451 
452     struct stat fs;
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];
460     struct timezone tz;
461     EXPECT_OK(gettimeofday(&tv[0], &tz));
462     EXPECT_OK(gettimeofday(&tv[1], &tz));
463     EXPECT_OK(futimesat(dfd, "testfile", tv));
464 
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"));
468     char buffer[256];
469     EXPECT_OK(readlinkat(dfd, "symlink", buffer, sizeof(buffer)));
470     EXPECT_OK(unlinkat(dfd, "linky", 0));
471     EXPECT_OK(unlinkat(dfd, "subdir", AT_REMOVEDIR));
472 
473     // Check that invalid requests get a non-Capsicum errno.
474     errno = 0;
475     rc = readlinkat(-1, "symlink", buffer, sizeof(buffer));
476     EXPECT_GE(0, rc);
477     EXPECT_NE(ECAPMODE, errno);
478 
479     exit(HasFailure());
480   }
481 
482   // Wait for the child.
483   int status;
484   EXPECT_EQ(child, waitpid(child, &status, 0));
485   rc = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
486   EXPECT_EQ(0, rc);
487 
488   // Tidy up.
489   close(dfd);
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"));
495 }
496 
TEST(Capmode,AllowedAtSyscallsCwd)497 TEST(Capmode, AllowedAtSyscallsCwd) {
498   int rc = mkdir(TmpFile("cap_at_syscalls_cwd"), 0755);
499   EXPECT_OK(rc);
500   if (rc < 0 && errno != EEXIST) return;
501   int dfd = open(TmpFile("cap_at_syscalls_cwd"), O_RDONLY);
502   EXPECT_OK(dfd);
503 
504   int file = openat(dfd, "testfile", O_RDONLY|O_CREAT, 0644);
505   EXPECT_OK(file);
506   EXPECT_OK(close(file));
507 
508   pid_t child = fork();
509   if (child == 0) {
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
513 
514     // Test that *at(AT_FDCWD, path,...) is policed with ECAPMODE.
515     EXPECT_CAPMODE(openat(AT_FDCWD, "testfile", O_RDONLY));
516     struct stat fs;
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];
524     struct timezone tz;
525     EXPECT_OK(gettimeofday(&tv[0], &tz));
526     EXPECT_OK(gettimeofday(&tv[1], &tz));
527     EXPECT_CAPMODE(futimesat(AT_FDCWD, "testfile", tv));
528 
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"));
532     char buffer[256];
533     EXPECT_CAPMODE(readlinkat(AT_FDCWD, "symlink", buffer, sizeof(buffer)));
534     EXPECT_CAPMODE(unlinkat(AT_FDCWD, "linky", 0));
535 
536     exit(HasFailure());
537   }
538 
539   // Wait for the child.
540   int status;
541   EXPECT_EQ(child, waitpid(child, &status, 0));
542   rc = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
543   EXPECT_EQ(0, rc);
544 
545   // Tidy up.
546   close(dfd);
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"));
552 }
553 
TEST(Capmode,Abort)554 TEST(Capmode, Abort) {
555   // Check that abort(3) works even in capability mode.
556   pid_t child = fork();
557   if (child == 0) {
558     // Child: enter capability mode and call abort(3).
559     // Triggers something like kill(getpid(), SIGABRT).
560     cap_enter();  // Enter capability mode.
561     abort();
562     exit(99);
563   }
564   int status;
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;
568 }
569 
FORK_TEST_F(WithFiles,AllowedMiscSyscalls)570 FORK_TEST_F(WithFiles, AllowedMiscSyscalls) {
571   umask(022);
572   mode_t um_before = umask(022);
573   int pipefds[2];
574   EXPECT_OK(pipe(pipefds));
575   EXPECT_OK(cap_enter());  // Enter capability mode.
576 
577   mode_t um = umask(022);
578   EXPECT_NE(-ECAPMODE, (int)um);
579   EXPECT_EQ(um_before, um);
580   stack_t ss;
581   EXPECT_OK(sigaltstack(NULL, &ss));
582 
583   // Finally, tests for system calls that don't fit the pattern very well.
584   pid_t pid = fork();
585   EXPECT_OK(pid);
586   if (pid == 0) {
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);
591     exit(0);
592   } else if (pid > 0) {
593     EXPECT_OK(close(pipefds[1]));
594     AWAIT_INT_MESSAGE(pipefds[0], MSG_CHILD_STARTED);
595     errno = 0;
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");
600   }
601 
602   // No error return from sync(2) to test, but check errno remains unset.
603   errno = 0;
604   sync();
605   EXPECT_EQ(0, errno);
606 
607   // TODO(FreeBSD): ktrace
608 
609 #ifdef HAVE_SYSARCH
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));
614 #else
615   // TOOD(jra): write a test for other architectures, like arm
616 #endif
617 #endif
618 }
619 
thread_fn(void * p)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);
629   return rval;
630 }
631 
632 // Check that restrictions are the same in subprocesses and threads
FORK_TEST(Capmode,NewThread)633 FORK_TEST(Capmode, NewThread) {
634   // Fire off a new thread before entering capability mode
635   pthread_t early_thread;
636   void *thread_rval;
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.
640   int thread_pipe[2];
641   EXPECT_OK(pipe(thread_pipe));
642   int proc_pipe[2];
643   EXPECT_OK(pipe(proc_pipe));
644   EXPECT_OK(pthread_create(&early_thread, NULL, thread_fn,
645                            (void *)(intptr_t)thread_pipe[1]));
646 
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);
657     EXPECT_OK(fd);
658     close(fd);
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);
663     exit(rval);
664   }
665 
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);
672 
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);
677 
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");
684   int child = fork();
685   EXPECT_OK(child);
686   if (child == 0) {
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);
696     exit(rval);
697   }
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";
707 
708   // Wait for the second child to exit (should get a zero exit code message).
709   AWAIT_INT_MESSAGE(proc_pipe[0], 0);
710 
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";
720 
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");
725   child = fork();
726   EXPECT_OK(child);
727   if (child == 0) {
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);
740     exit(rval);
741   }
742   // Wait for the third child to exit (should get a zero exit code message).
743   AWAIT_INT_MESSAGE(proc_pipe[0], 0);
744   close(proc_pipe[0]);
745   close(proc_pipe[1]);
746   close(thread_pipe[0]);
747   close(thread_pipe[1]);
748 }
749 
750 static volatile sig_atomic_t had_signal = 0;
handle_signal(int)751 static void handle_signal(int) { had_signal = 1; }
752 
FORK_TEST(Capmode,SelfKill)753 FORK_TEST(Capmode, SelfKill) {
754   pid_t me = getpid();
755   sighandler_t original = signal(SIGUSR1, handle_signal);
756 
757   pid_t child = fork();
758   if (child == 0) {
759     // Child: sleep and exit
760     sleep(1);
761     exit(0);
762   }
763 
764   EXPECT_OK(cap_enter());  // Enter capability mode.
765 
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);
770 
771   signal(SIGUSR1, original);
772 }
773