aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tests/sys/capsicum/capability-fd.cc10
-rw-r--r--tests/sys/capsicum/capmode.cc2
-rw-r--r--tests/sys/capsicum/capsicum-freebsd.h15
-rw-r--r--tests/sys/capsicum/capsicum-test-main.cc8
-rw-r--r--tests/sys/capsicum/capsicum-test.h36
-rw-r--r--tests/sys/capsicum/fexecve.cc12
-rw-r--r--tests/sys/capsicum/procdesc.cc6
-rw-r--r--tests/sys/capsicum/sctp.cc30
-rw-r--r--tests/sys/capsicum/socket.cc70
9 files changed, 107 insertions, 82 deletions
diff --git a/tests/sys/capsicum/capability-fd.cc b/tests/sys/capsicum/capability-fd.cc
index a9e4d30ac4b9..d79f3e4be917 100644
--- a/tests/sys/capsicum/capability-fd.cc
+++ b/tests/sys/capsicum/capability-fd.cc
@@ -974,6 +974,8 @@ FORK_TEST_ON(Capability, SocketTransfer, TmpFile("cap_fd_transfer")) {
pid_t child = fork();
if (child == 0) {
+ int child_cap_fd;
+
// Child: enter cap mode
EXPECT_OK(cap_enter());
// Child: send startup notification
@@ -984,16 +986,16 @@ FORK_TEST_ON(Capability, SocketTransfer, TmpFile("cap_fd_transfer")) {
EXPECT_OK(rc);
EXPECT_LE(CMSG_LEN(sizeof(int)), mh.msg_controllen);
cmptr = CMSG_FIRSTHDR(&mh);
- int cap_fd = *(int*)CMSG_DATA(cmptr);
+ memcpy(&child_cap_fd, CMSG_DATA(cmptr), sizeof(child_cap_fd));
EXPECT_EQ(CMSG_LEN(sizeof(int)), cmptr->cmsg_len);
cmptr = CMSG_NXTHDR(&mh, cmptr);
EXPECT_TRUE(cmptr == NULL);
// Child: confirm we can do the right operations on the capability
cap_rights_t rights;
- EXPECT_OK(cap_rights_get(cap_fd, &rights));
+ EXPECT_OK(cap_rights_get(child_cap_fd, &rights));
EXPECT_RIGHTS_EQ(&r_rs, &rights);
- TryReadWrite(cap_fd);
+ TryReadWrite(child_cap_fd);
// Child: acknowledge that we have received and tested the file descriptor
SEND_INT_MESSAGE(sock_fds[0], MSG_CHILD_FD_RECEIVED);
@@ -1024,7 +1026,7 @@ FORK_TEST_ON(Capability, SocketTransfer, TmpFile("cap_fd_transfer")) {
cmptr->cmsg_level = SOL_SOCKET;
cmptr->cmsg_type = SCM_RIGHTS;
cmptr->cmsg_len = CMSG_LEN(sizeof(int));
- *(int *)CMSG_DATA(cmptr) = cap_fd;
+ memcpy(CMSG_DATA(cmptr), &cap_fd, sizeof(cap_fd));
buffer1[0] = 0;
iov[0].iov_len = 1;
int rc = sendmsg(sock_fds[1], &mh, 0);
diff --git a/tests/sys/capsicum/capmode.cc b/tests/sys/capsicum/capmode.cc
index fdc572f11b5b..4cf6f24420e3 100644
--- a/tests/sys/capsicum/capmode.cc
+++ b/tests/sys/capsicum/capmode.cc
@@ -158,7 +158,7 @@ FORK_TEST_F(WithFiles, AllowedSocketSyscalls) {
if (rc < 0) {
EXPECT_EQ(EAGAIN, errno);
}
- char ch;
+ char ch = 'a';
EXPECT_OK(write(fd_file_, &ch, sizeof(ch)));
// These calls will fail for lack of e.g. a proper name to send to,
diff --git a/tests/sys/capsicum/capsicum-freebsd.h b/tests/sys/capsicum/capsicum-freebsd.h
index 9cb3149a05a4..82ee9cf9d91c 100644
--- a/tests/sys/capsicum/capsicum-freebsd.h
+++ b/tests/sys/capsicum/capsicum-freebsd.h
@@ -4,15 +4,15 @@
* FreeBSD Capsicum Functionality.
************************************************************/
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
/* FreeBSD definitions. */
-#include <errno.h>
#include <sys/param.h>
#include <sys/capsicum.h>
#include <sys/procdesc.h>
+#include <errno.h>
#define AT_SYSCALLS_IN_CAPMODE
#define HAVE_CAP_RIGHTS_GET
@@ -27,9 +27,7 @@ typedef unsigned long cap_ioctl_t;
#define HAVE_OPENAT_INTERMEDIATE_DOTDOT
-#ifdef __cplusplus
-}
-#endif
+__END_DECLS
// Use fexecve_() in tests to allow Linux variant to bypass glibc version.
#define fexecve_(F, A, E) fexecve(F, A, E)
@@ -50,4 +48,7 @@ typedef unsigned long cap_ioctl_t;
// FreeBSD generates a capability from sctp_peeloff(cap_fd,...).
#define CAP_FROM_PEELOFF
+#define HAVE_PIPE2
+#define HAVE_SEND_RECV_MMSG
+
#endif /*__CAPSICUM_FREEBSD_H__*/
diff --git a/tests/sys/capsicum/capsicum-test-main.cc b/tests/sys/capsicum/capsicum-test-main.cc
index 2a2c75000039..2e9839a755d9 100644
--- a/tests/sys/capsicum/capsicum-test-main.cc
+++ b/tests/sys/capsicum/capsicum-test-main.cc
@@ -75,12 +75,16 @@ std::string capsicum_test_bindir;
// Adds a directory to $PATH.
static void AddDirectoryToPath(const char *dir) {
char *new_path, *old_path;
+ int rc [[maybe_unused]];
old_path = getenv("PATH");
assert(old_path);
- assert(asprintf(&new_path, "%s:%s", dir, old_path) > 0);
- assert(setenv("PATH", new_path, 1) == 0);
+ rc = asprintf(&new_path, "%s:%s", dir, old_path);
+ assert(rc != -1);
+ rc = setenv("PATH", new_path, 1);
+ assert(rc == 0);
+ free(new_path);
}
int main(int argc, char* argv[]) {
diff --git a/tests/sys/capsicum/capsicum-test.h b/tests/sys/capsicum/capsicum-test.h
index 7433814b31c8..5503a7ef260f 100644
--- a/tests/sys/capsicum/capsicum-test.h
+++ b/tests/sys/capsicum/capsicum-test.h
@@ -67,7 +67,7 @@ const char *TmpFile(const char *pathname);
// Implemented as a macro to allow access to the test case instance's
// HasFailure() method, which is reported as the forked process's
// exit status.
-#define _RUN_FORKED(INNERCODE, TESTCASENAME, TESTNAME) \
+#define _RUN_FORKED(INNERCODE, TESTCASENAME, TESTNAME) do { \
pid_t pid = force_nofork ? 0 : fork(); \
if (pid == 0) { \
INNERCODE; \
@@ -95,10 +95,13 @@ const char *TmpFile(const char *pathname);
strerror(errno), errno); \
ADD_FAILURE() << "Failed to wait for child"; \
} else { \
- int rc = WIFEXITED(status) ? WEXITSTATUS(status) : -1; \
- EXPECT_EQ(0, rc); \
+ int exit_status = \
+ WIFEXITED(status) ? WEXITSTATUS(status) : -1; \
+ EXPECT_EQ(0, exit_status); \
} \
- }
+ } \
+} while (0)
+
#define _RUN_FORKED_MEM(THIS, TESTFN, TESTCASENAME, TESTNAME) \
_RUN_FORKED(MaybeRunWithThread(THIS, &TESTFN), TESTCASENAME, TESTNAME);
#define _RUN_FORKED_FN(TESTFN, TESTCASENAME, TESTNAME) \
@@ -137,15 +140,28 @@ const char *TmpFile(const char *pathname);
// Emit errno information on failure
#define EXPECT_OK(v) EXPECT_LE(0, v) << " errno " << errno << " " << strerror(errno)
-// Expect a syscall to fail with the given error.
-#define EXPECT_SYSCALL_FAIL(E, C) \
+// Expect a syscall to fail with the given error (inner).
+//
+// This is required because unfortunately googletest "computes" trace variables
+// using line numbers instead of another unique ID and 2 calls to
+// `SCOPED_TRACE(..)` via the same macro results in `-Wshadow`-related compiler
+// errors: https://github.com/google/googletest/issues/5143
+#define EXPECT_SYSCALL_FAIL_NO_TRACE(E, C) \
do { \
- SCOPED_TRACE(#C); \
EXPECT_GT(0, C); \
EXPECT_EQ(E, errno) << "expected '" << strerror(E) \
<< "' but got '" << strerror(errno) << "'"; \
} while (0)
+// Expect a syscall to fail with the given error (with tracing).
+//
+// See the comment above (for `EXPECT_SYSCALL_FAIL_NO_TRACE`).
+#define EXPECT_SYSCALL_FAIL(E, C) \
+ do { \
+ SCOPED_TRACE(#C); \
+ EXPECT_SYSCALL_FAIL_NO_TRACE((E), (C)); \
+ } while (0)
+
// Expect a syscall to fail with anything other than the given error.
#define EXPECT_SYSCALL_FAIL_NOT(E, C) \
do { \
@@ -169,9 +185,9 @@ const char *TmpFile(const char *pathname);
SCOPED_TRACE(GTEST_STRINGIFY_(openat((fd), (path), (flags)))); \
const int result = openat((fd), (path), (flags)); \
if (((flags) & O_BENEATH) == O_BENEATH) { \
- EXPECT_SYSCALL_FAIL(E_NO_TRAVERSE_O_BENEATH, result); \
+ EXPECT_SYSCALL_FAIL_NO_TRACE(E_NO_TRAVERSE_O_BENEATH, result); \
} else { \
- EXPECT_SYSCALL_FAIL(E_NO_TRAVERSE_CAPABILITY, result); \
+ EXPECT_SYSCALL_FAIL_NO_TRACE(E_NO_TRAVERSE_CAPABILITY, result); \
} \
if (result >= 0) { close(result); } \
} while (0)
@@ -180,7 +196,7 @@ const char *TmpFile(const char *pathname);
do { \
SCOPED_TRACE(GTEST_STRINGIFY_(openat((fd), (path), (flags)))); \
const int result = openat((fd), (path), (flags)); \
- EXPECT_SYSCALL_FAIL(E_NO_TRAVERSE_CAPABILITY, result); \
+ EXPECT_SYSCALL_FAIL_NO_TRACE(E_NO_TRAVERSE_CAPABILITY, result); \
if (result >= 0) { close(result); } \
} while (0)
#endif
diff --git a/tests/sys/capsicum/fexecve.cc b/tests/sys/capsicum/fexecve.cc
index 86df2af06388..6ff5a657c35a 100644
--- a/tests/sys/capsicum/fexecve.cc
+++ b/tests/sys/capsicum/fexecve.cc
@@ -32,9 +32,9 @@ class Execve : public ::testing::Test {
if (exec_fd_ < 0) {
fprintf(stderr, "Error! Failed to open %s\n", exec_prog_.c_str());
}
- argv_checkroot_[0] = (char*)exec_prog_.c_str();
- argv_fail_[0] = (char*)exec_prog_.c_str();
- argv_pass_[0] = (char*)exec_prog_.c_str();
+ argv_checkroot_[0] = __DECONST(char*, exec_prog_.c_str());
+ argv_fail_[0] = __DECONST(char*, exec_prog_.c_str());
+ argv_pass_[0] = __DECONST(char*, exec_prog_.c_str());
}
~Execve() {
if (exec_fd_ >= 0) {
@@ -43,9 +43,9 @@ class Execve : public ::testing::Test {
}
}
protected:
- char* argv_checkroot_[3] = {nullptr, (char*)"--checkroot", nullptr};
- char* argv_fail_[3] = {nullptr, (char*)"--fail", nullptr};
- char* argv_pass_[3] = {nullptr, (char*)"--pass", nullptr};
+ char* argv_checkroot_[3] = {nullptr, __DECONST(char*, "--checkroot"), nullptr};
+ char* argv_fail_[3] = {nullptr, __DECONST(char*, "--fail"), nullptr};
+ char* argv_pass_[3] = {nullptr, __DECONST(char*, "--pass"), nullptr};
std::string exec_prog_, exec_prog_noexec_, exec_prog_setuid_;
int exec_fd_;
};
diff --git a/tests/sys/capsicum/procdesc.cc b/tests/sys/capsicum/procdesc.cc
index f25324e4efc7..c92edaf4b695 100644
--- a/tests/sys/capsicum/procdesc.cc
+++ b/tests/sys/capsicum/procdesc.cc
@@ -983,6 +983,8 @@ TEST_F(PipePdfork, PassProcessDescriptor) {
if (verbose) fprintf(stderr, "[%d] about to fork()\n", getpid_());
pid_t child2 = fork();
if (child2 == 0) {
+ int pd;
+
// Child: close our copy of the original process descriptor.
close(pd_);
SEND_INT_MESSAGE(sock_fds[0], MSG_CHILD_STARTED);
@@ -992,7 +994,7 @@ TEST_F(PipePdfork, PassProcessDescriptor) {
EXPECT_OK(rc);
EXPECT_LE(CMSG_LEN(sizeof(int)), mh.msg_controllen);
cmptr = CMSG_FIRSTHDR(&mh);
- int pd = *(int*)CMSG_DATA(cmptr);
+ memcpy(&pd, CMSG_DATA(cmptr), sizeof(pd));
EXPECT_EQ(CMSG_LEN(sizeof(int)), cmptr->cmsg_len);
cmptr = CMSG_NXTHDR(&mh, cmptr);
EXPECT_TRUE(cmptr == NULL);
@@ -1024,7 +1026,7 @@ TEST_F(PipePdfork, PassProcessDescriptor) {
cmptr->cmsg_level = SOL_SOCKET;
cmptr->cmsg_type = SCM_RIGHTS;
cmptr->cmsg_len = CMSG_LEN(sizeof(int));
- *(int *)CMSG_DATA(cmptr) = pd_;
+ memcpy(CMSG_DATA(cmptr), &pd_, sizeof(pd_));
buffer1[0] = 0;
iov[0].iov_len = 1;
if (verbose) fprintf(stderr, "[%d] send process descriptor %d on socket\n", getpid_(), pd_);
diff --git a/tests/sys/capsicum/sctp.cc b/tests/sys/capsicum/sctp.cc
index aa84653c5b2a..a36a242f8c9b 100644
--- a/tests/sys/capsicum/sctp.cc
+++ b/tests/sys/capsicum/sctp.cc
@@ -92,13 +92,13 @@ TEST(Sctp, Socket) {
addr.sin_family = AF_INET;
addr.sin_port = htons(0);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
- socklen_t len = sizeof(addr);
+ socklen_t addr_len = sizeof(addr);
// Can only bind the fully-capable socket.
- EXPECT_NOTCAPABLE(bind(cap_sock_rw, (struct sockaddr *)&addr, len));
- EXPECT_OK(bind(cap_sock_all, (struct sockaddr *)&addr, len));
+ EXPECT_NOTCAPABLE(bind(cap_sock_rw, (struct sockaddr *)&addr, addr_len));
+ EXPECT_OK(bind(cap_sock_all, (struct sockaddr *)&addr, addr_len));
- EXPECT_OK(getsockname(cap_sock_all, (struct sockaddr *)&addr, &len));
+ EXPECT_OK(getsockname(cap_sock_all, (struct sockaddr *)&addr, &addr_len));
int port = ntohs(addr.sin_port);
// Now we know the port involved, fork off children to run clients.
@@ -128,43 +128,43 @@ TEST(Sctp, Socket) {
EXPECT_OK(listen(cap_sock_all, 3));
// Can only do socket operations on the fully-capable socket.
- len = sizeof(addr);
- EXPECT_NOTCAPABLE(getsockname(cap_sock_rw, (struct sockaddr*)&addr, &len));
+ addr_len = sizeof(addr);
+ EXPECT_NOTCAPABLE(getsockname(cap_sock_rw, (struct sockaddr*)&addr, &addr_len));
struct sctp_event_subscribe events;
memset(&events, 0, sizeof(events));
events.sctp_association_event = 1;
events.sctp_data_io_event = 1;
EXPECT_NOTCAPABLE(setsockopt(cap_sock_rw, IPPROTO_SCTP, SCTP_EVENTS, &events, sizeof(events)));
- len = sizeof(events);
- EXPECT_NOTCAPABLE(getsockopt(cap_sock_rw, IPPROTO_SCTP, SCTP_EVENTS, &events, &len));
+ socklen_t eventslen = sizeof(events);
+ EXPECT_NOTCAPABLE(getsockopt(cap_sock_rw, IPPROTO_SCTP, SCTP_EVENTS, &events, &eventslen));
memset(&events, 0, sizeof(events));
events.sctp_association_event = 1;
events.sctp_data_io_event = 1;
EXPECT_OK(setsockopt(cap_sock_all, IPPROTO_SCTP, SCTP_EVENTS, &events, sizeof(events)));
- len = sizeof(events);
- EXPECT_OK(getsockopt(cap_sock_all, IPPROTO_SCTP, SCTP_EVENTS, &events, &len));
+ eventslen = sizeof(events);
+ EXPECT_OK(getsockopt(cap_sock_all, IPPROTO_SCTP, SCTP_EVENTS, &events, &eventslen));
- len = sizeof(addr);
+ addr_len = sizeof(addr);
memset(&addr, 0, sizeof(addr));
- EXPECT_OK(getsockname(cap_sock_all, (struct sockaddr*)&addr, &len));
+ EXPECT_OK(getsockname(cap_sock_all, (struct sockaddr*)&addr, &addr_len));
EXPECT_EQ(AF_INET, addr.sin_family);
EXPECT_EQ(htons(port), addr.sin_port);
struct sockaddr_in client_addr;
- socklen_t addr_len = sizeof(client_addr);
+ socklen_t client_addr_len = sizeof(client_addr);
unsigned char buffer[1024];
struct sctp_sndrcvinfo sri;
memset(&sri, 0, sizeof(sri));
int flags = 0;
EXPECT_NOTCAPABLE(sctp_recvmsg(cap_sock_wo, buffer, sizeof(buffer),
- (struct sockaddr*)&client_addr, &addr_len,
+ (struct sockaddr*)&client_addr, &client_addr_len,
&sri, &flags));
while (true) {
retry:
memset(&sri, 0, sizeof(sri));
int len = sctp_recvmsg(cap_sock_rw, buffer, sizeof(buffer),
- (struct sockaddr*)&client_addr, &addr_len,
+ (struct sockaddr*)&client_addr, &client_addr_len,
&sri, &flags);
if (len < 0 && errno == EAGAIN) goto retry;
EXPECT_OK(len);
diff --git a/tests/sys/capsicum/socket.cc b/tests/sys/capsicum/socket.cc
index 5bb7e9d3e180..ff21d3020a83 100644
--- a/tests/sys/capsicum/socket.cc
+++ b/tests/sys/capsicum/socket.cc
@@ -166,26 +166,26 @@ TEST(Socket, TCP) {
AWAIT_INT_MESSAGE(pipefds[1], MSG_PARENT_CHILD_SHOULD_RUN);
// Create sockets
- int sock = socket(AF_INET, SOCK_STREAM, 0);
- EXPECT_OK(sock);
- if (sock < 0) return;
- int cap_sock_rw = dup(sock);
- EXPECT_OK(cap_sock_rw);
- EXPECT_OK(cap_rights_limit(cap_sock_rw, &r_rw));
- int cap_sock_all = dup(sock);
- EXPECT_OK(cap_sock_all);
- EXPECT_OK(cap_rights_limit(cap_sock_all, &r_all));
- close(sock);
+ int child_sock = socket(AF_INET, SOCK_STREAM, 0);
+ EXPECT_OK(child_sock);
+ if (child_sock < 0) return;
+ int child_cap_sock_rw = dup(child_sock);
+ EXPECT_OK(child_cap_sock_rw);
+ EXPECT_OK(cap_rights_limit(child_cap_sock_rw, &r_rw));
+ int child_cap_sock_all = dup(child_sock);
+ EXPECT_OK(child_cap_sock_all);
+ EXPECT_OK(cap_rights_limit(child_cap_sock_all, &r_all));
+ close(child_sock);
// Connect socket
- struct sockaddr_in addr;
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port); // Pick unused port
- addr.sin_addr.s_addr = inet_addr("127.0.0.1");
- socklen_t len = sizeof(addr);
- EXPECT_NOTCAPABLE(connect_(cap_sock_rw, (struct sockaddr *)&addr, len));
- EXPECT_OK(connect_(cap_sock_all, (struct sockaddr *)&addr, len));
+ struct sockaddr_in child_addr;
+ memset(&child_addr, 0, sizeof(child_addr));
+ child_addr.sin_family = AF_INET;
+ child_addr.sin_port = htons(port); // Pick unused port
+ child_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
+ socklen_t child_addr_len = sizeof(child_addr);
+ EXPECT_NOTCAPABLE(connect_(child_cap_sock_rw, (struct sockaddr *)&child_addr, child_addr_len));
+ EXPECT_OK(connect_(child_cap_sock_all, (struct sockaddr *)&child_addr, child_addr_len));
exit(HasFailure());
}
@@ -291,15 +291,15 @@ TEST(Socket, UDP) {
pid_t child = fork();
if (child == 0) {
- int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- EXPECT_OK(sock);
- int cap_sock_rw = dup(sock);
- EXPECT_OK(cap_sock_rw);
- EXPECT_OK(cap_rights_limit(cap_sock_rw, &r_rw));
- int cap_sock_connect = dup(sock);
+ int child_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ EXPECT_OK(child_sock);
+ int child_cap_sock_rw = dup(child_sock);
+ EXPECT_OK(child_cap_sock_rw);
+ EXPECT_OK(cap_rights_limit(child_cap_sock_rw, &r_rw));
+ int cap_sock_connect = dup(child_sock);
EXPECT_OK(cap_sock_connect);
EXPECT_OK(cap_rights_limit(cap_sock_connect, &r_connect));
- close(sock);
+ close(child_sock);
// Can only sendmsg(2) to an address over a socket with CAP_CONNECT.
unsigned char buffer[256];
@@ -313,25 +313,25 @@ TEST(Socket, UDP) {
mh.msg_iov = &iov;
mh.msg_iovlen = 1;
- struct sockaddr_in addr;
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port);
- addr.sin_addr.s_addr = inet_addr("127.0.0.1");
- mh.msg_name = &addr;
- mh.msg_namelen = sizeof(addr);
+ struct sockaddr_in child_addr;
+ memset(&child_addr, 0, sizeof(child_addr));
+ child_addr.sin_family = AF_INET;
+ child_addr.sin_port = htons(port);
+ child_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
+ mh.msg_name = &child_addr;
+ mh.msg_namelen = sizeof(child_addr);
- EXPECT_NOTCAPABLE(sendmsg(cap_sock_rw, &mh, 0));
+ EXPECT_NOTCAPABLE(sendmsg(child_cap_sock_rw, &mh, 0));
EXPECT_OK(sendmsg(cap_sock_connect, &mh, 0));
#ifdef HAVE_SEND_RECV_MMSG
struct mmsghdr mv;
memset(&mv, 0, sizeof(mv));
memcpy(&mv.msg_hdr, &mh, sizeof(struct msghdr));
- EXPECT_NOTCAPABLE(sendmmsg(cap_sock_rw, &mv, 1, 0));
+ EXPECT_NOTCAPABLE(sendmmsg(child_cap_sock_rw, &mv, 1, 0));
EXPECT_OK(sendmmsg(cap_sock_connect, &mv, 1, 0));
#endif
- close(cap_sock_rw);
+ close(child_cap_sock_rw);
close(cap_sock_connect);
exit(HasFailure());
}