Skip to content

Commit 9ebea92

Browse files
committed
seccomp: skip supervisor for nested calls
The old code returned a fake epoll fd as the supervisor fd to avoid refactoring the fd passing code, but it was just a hack. This commit does things properly by allowing send_fd to accept -1 to signify "send no file descriptor". A matching recv_fd will in turn return -1. This allows us to return -1 when the supervisor already exists somewhere up the chain and skip the nested supervisor loop if that's the case.
1 parent 727b48f commit 9ebea92

File tree

4 files changed

+23
-12
lines changed

4 files changed

+23
-12
lines changed

enter.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,8 +472,8 @@ int enter(struct entry_settings *opts)
472472

473473
#ifdef HAVE_SECCOMP_UNOTIFY
474474
int seccomp_fd = sec_seccomp_install_filter();
475+
send_fd(outer_helper.fd, seccomp_fd);
475476
if (seccomp_fd != -1) {
476-
send_fd(outer_helper.fd, seccomp_fd);
477477
close(seccomp_fd);
478478
}
479479
#endif

fd.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <fcntl.h>
99
#include <stdarg.h>
1010
#include <stddef.h>
11+
#include <string.h>
1112
#include <sys/socket.h>
1213
#include <unistd.h>
1314

@@ -43,7 +44,7 @@ int recv_fd(int socket)
4344

4445
struct cmsghdr *pCm = CMSG_FIRSTHDR(&msg);
4546
if (pCm == NULL || pCm->cmsg_len != CMSG_LEN(sizeof (int))) {
46-
errx(1, "recv_fd: no descriptor passed");
47+
return -1;
4748
}
4849
if (pCm->cmsg_level != SOL_SOCKET) {
4950
errx(1, "recv_fd: control level != SOL_SOCKET");
@@ -64,19 +65,26 @@ void send_fd(int socket, int fd)
6465
struct cmsghdr _align;
6566
char ctrl[CMSG_SPACE(sizeof(int))];
6667
} uCtrl;
68+
memset(&uCtrl, 0, sizeof(uCtrl));
69+
6770
struct msghdr msg = {
68-
.msg_control = uCtrl.ctrl,
69-
.msg_controllen = sizeof(uCtrl.ctrl),
7071
.msg_name = NULL,
7172
.msg_namelen = 0,
7273
.msg_iov = iov,
7374
.msg_iovlen = 1,
7475
};
75-
struct cmsghdr *pCm = CMSG_FIRSTHDR(&msg);
76-
pCm->cmsg_len = CMSG_LEN(sizeof(int));
77-
pCm->cmsg_level = SOL_SOCKET;
78-
pCm->cmsg_type = SCM_RIGHTS;
79-
*((int*) CMSG_DATA(pCm)) = fd;
76+
77+
if (fd != -1) {
78+
msg.msg_control = uCtrl.ctrl;
79+
msg.msg_controllen = sizeof(uCtrl.ctrl);
80+
81+
struct cmsghdr *pCm = CMSG_FIRSTHDR(&msg);
82+
pCm->cmsg_len = CMSG_LEN(sizeof(int));
83+
pCm->cmsg_level = SOL_SOCKET;
84+
pCm->cmsg_type = SCM_RIGHTS;
85+
*((int*) CMSG_DATA(pCm)) = fd;
86+
}
87+
8088
if (sendmsg(socket, &msg, 0) < 0) {
8189
err(1, "send_fd: sendmsg");
8290
}

outer.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,10 @@ void outer_helper_spawn(struct outer_helper *helper)
404404

405405
#ifdef HAVE_SECCOMP_UNOTIFY
406406
int seccomp_fd = recv_fd(fd);
407+
if (seccomp_fd == -1) {
408+
/* We could not install seccomp */
409+
_exit(0);
410+
}
407411

408412
/* Don't hold onto any file descriptors before running our supervisor loop,
409413
because doing so may keep other children stuck waiting on fds that

sec.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -748,9 +748,8 @@ int sec_seccomp_install_filter(void)
748748
int fd = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_NEW_LISTENER, &prog);
749749
if (fd == -1) {
750750
if (errno == EBUSY) {
751-
// We're likely running bst in bst; ignore the error, and return
752-
// a useless file descriptor to pass to the seccomp supervisor
753-
return epoll_create1(EPOLL_CLOEXEC);
751+
// We're likely running bst in bst; this error is nonfatal.
752+
return -1;
754753
}
755754
err(1, "seccomp SECCOMP_SET_MODE_FILTER");
756755
}

0 commit comments

Comments
 (0)