aboutgitcodebugslistschat
path: root/passt.c
diff options
context:
space:
mode:
authorStefano Brivio <sbrivio@redhat.com>2021-10-13 22:25:03 +0200
committerStefano Brivio <sbrivio@redhat.com>2021-10-14 13:15:46 +0200
commit66d5930ec77caed942404ceef4829f2c4ca431bd (patch)
treecef75db6ce37ddd50de819f1dc53dcd602b97c36 /passt.c
parentf318174a9387ecd94d83ed0b9356940c60753846 (diff)
downloadpasst-66d5930ec77caed942404ceef4829f2c4ca431bd.tar
passt-66d5930ec77caed942404ceef4829f2c4ca431bd.tar.gz
passt-66d5930ec77caed942404ceef4829f2c4ca431bd.tar.bz2
passt-66d5930ec77caed942404ceef4829f2c4ca431bd.tar.lz
passt-66d5930ec77caed942404ceef4829f2c4ca431bd.tar.xz
passt-66d5930ec77caed942404ceef4829f2c4ca431bd.tar.zst
passt-66d5930ec77caed942404ceef4829f2c4ca431bd.zip
passt, pasta: Add seccomp support
List of allowed syscalls comes from comments in the form: #syscalls <list> for syscalls needed both in passt and pasta mode, and: #syscalls:pasta <list> #syscalls:passt <list> for syscalls specifically needed in pasta or passt mode only. seccomp.sh builds a list of BPF statements from those comments, prefixed by a binary search tree to keep lookup fast. While at it, clean up a bit the Makefile using wildcards. Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'passt.c')
-rw-r--r--passt.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/passt.c b/passt.c
index b411657..0628d8c 100644
--- a/passt.c
+++ b/passt.c
@@ -51,7 +51,12 @@
#include <time.h>
#include <syslog.h>
#include <sys/stat.h>
+#include <seccomp.h>
+#include <sys/prctl.h>
+#include <linux/filter.h>
+#include <stddef.h>
+#include "seccomp.h"
#include "util.h"
#include "passt.h"
#include "dhcp.h"
@@ -158,11 +163,40 @@ void proto_update_l2_buf(unsigned char *eth_d, unsigned char *eth_s,
}
/**
+ * seccomp() - Set up seccomp filters depending on mode, won't return on failure
+ * @c: Execution context
+ */
+static void seccomp(struct ctx *c)
+{
+ struct sock_fprog prog;
+
+ if (c->mode == MODE_PASST) {
+ prog.len = (unsigned short)ARRAY_SIZE(filter_passt);
+ prog.filter = filter_passt;
+ } else {
+ prog.len = (unsigned short)ARRAY_SIZE(filter_pasta);
+ prog.filter = filter_pasta;
+ }
+
+ if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) ||
+ prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
+ perror("prctl");
+ exit(EXIT_FAILURE);
+ }
+}
+
+/**
* main() - Entry point and main loop
* @argc: Argument count
* @argv: Options, plus optional target PID for pasta mode
*
* Return: 0 once interrupted, non-zero on failure
+ *
+ * #syscalls read write open close fork dup2 exit chdir brk ioctl writev syslog
+ * #syscalls prlimit64 epoll_ctl epoll_create1 epoll_wait accept4 accept listen
+ * #syscalls socket bind connect getsockopt setsockopt recvfrom sendto shutdown
+ * #syscalls openat fstat fcntl lseek
+ * #syscalls:pasta rt_sigreturn
*/
int main(int argc, char **argv)
{
@@ -198,6 +232,8 @@ int main(int argc, char **argv)
conf(&c, argc, argv);
+ seccomp(&c);
+
if (!c.debug && (c.stderr || isatty(fileno(stdout))))
openlog(log_name, LOG_PERROR, LOG_DAEMON);