diff options
author | Mark Johnston <markj@FreeBSD.org> | 2021-04-12 15:20:39 +0000 |
---|---|---|
committer | Mark Johnston <markj@FreeBSD.org> | 2021-04-12 15:25:49 +0000 |
commit | d0e943077d94e6266ece9856789c5d5313676e38 (patch) | |
tree | 9393d25e2a4b541a17fe9a641c14378cd9794961 | |
parent | c59f30a57b509d88ab47e5cf2e1509fdc8a2749c (diff) |
Update capsicum-test to ea66424d921bb393539b298c108a46edee5c3051vendor/google/capsicum-test/ea66424d921bb393539b298c108a46edee5c3051
This adds regression tests for a recent FreeBSD commit to restrict
certain socket operations in capability mode.
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | capmode.cc | 37 | ||||
-rw-r--r-- | capsicum-test.cc | 7 |
3 files changed, 43 insertions, 3 deletions
diff --git a/README.md b/README.md index 918534557725..a8c8c6686759 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ object-capabilities. The tests exercise the syscall interface to a Capsicum-enab currently either [FreeBSD >=10.x](http://www.freebsd.org) or a modified Linux kernel (the [capsicum-linux](http://github.com/google/capsicum-linux) project). -The tests are written in C++98, and use the [Google Test](https://code.google.com/p/googletest/) +The tests are written in C++11 and use the [Google Test](https://code.google.com/p/googletest/) framework, with some additions to fork off particular tests (because a process that enters capability mode cannot leave it again). diff --git a/capmode.cc b/capmode.cc index c274f5e1c9f3..ba2de19879a0 100644 --- a/capmode.cc +++ b/capmode.cc @@ -3,6 +3,9 @@ // whether or not they return the expected ECAPMODE. #include <sys/types.h> #include <sys/socket.h> +#ifdef __FreeBSD__ +#include <sys/sockio.h> +#endif #include <sys/stat.h> #include <sys/mount.h> #include <sys/mman.h> @@ -11,6 +14,7 @@ #include <sys/resource.h> #include <sys/ptrace.h> #include <dirent.h> +#include <net/if.h> #include <netinet/in.h> #include <fcntl.h> #include <sched.h> @@ -203,6 +207,39 @@ FORK_TEST_F(WithFiles, AllowedSocketSyscalls) { if (fd_pair[1] >= 0) close(fd_pair[1]); } +FORK_TEST_F(WithFiles, AllowedSocketSyscallsIfRoot) { + GTEST_SKIP_IF_NOT_ROOT(); + + EXPECT_OK(cap_enter()); // Enter capability mode. + + // Creation of raw sockets is not permitted in capability mode. + EXPECT_CAPMODE(socket(AF_INET, SOCK_RAW, 0)); + EXPECT_CAPMODE(socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)); + EXPECT_CAPMODE(socket(AF_INET, SOCK_RAW, IPPROTO_TCP)); + EXPECT_CAPMODE(socket(AF_INET, SOCK_RAW, IPPROTO_UDP)); + + EXPECT_CAPMODE(socket(AF_INET6, SOCK_RAW, IPPROTO_ICMP)); + EXPECT_CAPMODE(socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)); + EXPECT_CAPMODE(socket(AF_INET6, SOCK_RAW, IPPROTO_TCP)); + EXPECT_CAPMODE(socket(AF_INET6, SOCK_RAW, IPPROTO_UDP)); + + EXPECT_CAPMODE(socket(AF_ROUTE, SOCK_RAW, 0)); + + // Interface configuration ioctls are not permitted in capability + // mode. +#ifdef __FreeBSD__ + struct if_clonereq req; + + req.ifcr_total = 0; + req.ifcr_count = 1; + req.ifcr_buffer = static_cast<char *>(malloc(IFNAMSIZ)); + + EXPECT_CAPMODE(ioctl(fd_socket_, SIOCIFGCLONERS, &req)); + + free(req.ifcr_buffer); +#endif +} + #ifdef HAVE_SEND_RECV_MMSG FORK_TEST(Capmode, AllowedMmsgSendRecv) { int fd_socket = socket(PF_INET, SOCK_DGRAM, 0); diff --git a/capsicum-test.cc b/capsicum-test.cc index dedad464a4d9..1e722089761f 100644 --- a/capsicum-test.cc +++ b/capsicum-test.cc @@ -72,11 +72,14 @@ char ProcessState(int pid) { } unsigned int count = 0; struct procstat *prstat = procstat_open_sysctl(); - EXPECT_NE(NULL, prstat) << "procstat_open_sysctl failed."; + EXPECT_NE(nullptr, prstat) << "procstat_open_sysctl failed."; errno = 0; struct kinfo_proc *p = procstat_getprocs(prstat, KERN_PROC_PID, pid, &count); if (p == NULL || count == 0) { - if (verbose) fprintf(stderr, "procstat_getprocs failed with %p/%d: %s\n", p, count, strerror(errno)); + if (verbose) { + fprintf(stderr, "procstat_getprocs failed with %p/%d: %s\n", (void *)p, + count, strerror(errno)); + } procstat_close(prstat); return '\0'; } |