[lxc-devel] [lxd/master] seccomp: handle compat arch syscalls
brauner on Github
lxc-bot at linuxcontainers.org
Wed Jul 10 15:47:38 UTC 2019
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 364 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20190710/119cc9c2/attachment.bin>
-------------- next part --------------
From a5f31f5974bac05c022b5d67448818fcd0370661 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Wed, 10 Jul 2019 17:47:03 +0200
Subject: [PATCH] seccomp: handle compat arch syscalls
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
lxd/seccomp.go | 249 +++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 212 insertions(+), 37 deletions(-)
diff --git a/lxd/seccomp.go b/lxd/seccomp.go
index 63738515e3..be536b9bd5 100644
--- a/lxd/seccomp.go
+++ b/lxd/seccomp.go
@@ -138,6 +138,174 @@ static int device_allowed(dev_t dev, mode_t mode)
return -EPERM;
}
+#include <linux/audit.h>
+
+struct lxd_seccomp_data_arch {
+ int arch;
+ int nr_mknod;
+ int nr_mknodat;
+};
+
+// ordered by likelihood of usage...
+static const struct lxd_seccomp_data_arch seccomp_notify_syscall_table[] = {
+#ifdef AUDIT_ARCH_X86_64
+ { AUDIT_ARCH_X86_64, 133, 259 },
+#endif
+#ifdef AUDIT_ARCH_I386
+ { AUDIT_ARCH_I386, 14, 297 },
+#endif
+#ifdef AUDIT_ARCH_AARCH64
+ { AUDIT_ARCH_AARCH64, -1, 33 },
+#endif
+#ifdef AUDIT_ARCH_ARM
+ { AUDIT_ARCH_ARM, 14, 324 },
+#endif
+#ifdef AUDIT_ARCH_ARMEB
+ { AUDIT_ARCH_ARMEB, 14, 324 },
+#endif
+#ifdef AUDIT_ARCH_S390
+ { AUDIT_ARCH_S390, 14, 290 },
+#endif
+#ifdef AUDIT_ARCH_S390X
+ { AUDIT_ARCH_S390X, 14, 290 },
+#endif
+#ifdef AUDIT_ARCH_RISCV32
+ { AUDIT_ARCH_RISCV32, -1, 33 },
+#endif
+#ifdef AUDIT_ARCH_RISCV64
+ { AUDIT_ARCH_RISCV64, -1, 33 },
+#endif
+#ifdef AUDIT_ARCH_PPC
+ { AUDIT_ARCH_PPC, 14, 288 },
+#endif
+#ifdef AUDIT_ARCH_PPC64
+ { AUDIT_ARCH_PPC64, 14, 288 },
+#endif
+#ifdef AUDIT_ARCH_PPC64LE
+ { AUDIT_ARCH_PPC64LE, 14, 288 },
+#endif
+#ifdef AUDIT_ARCH_IA64
+ { AUDIT_ARCH_IA64, 13, 259 },
+#endif
+#ifdef AUDIT_ARCH_SPARC
+ { AUDIT_ARCH_SPARC, 14, 286 },
+#endif
+#ifdef AUDIT_ARCH_SPARC64
+ { AUDIT_ARCH_SPARC64, 14, 286 },
+#endif
+#ifdef AUDIT_ARCH_ALPHA
+ { AUDIT_ARCH_ALPHA, 14, 452 },
+#endif
+#ifdef AUDIT_ARCH_OPENRISC
+ { AUDIT_ARCH_OPENRISC, -1, 33 },
+#endif
+#ifdef AUDIT_ARCH_PARISC
+ { AUDIT_ARCH_PARISC, 14, 277 },
+#endif
+#ifdef AUDIT_ARCH_PARISC64
+ { AUDIT_ARCH_PARISC64, 14, 277 },
+#endif
+#ifdef AUDIT_ARCH_CRIS
+ { AUDIT_ARCH_CRIS, -1, -1 },
+#endif
+#ifdef AUDIT_ARCH_CSKY
+ { AUDIT_ARCH_CSKY, -1, 33 },
+#endif
+#ifdef AUDIT_ARCH_FRV
+ { AUDIT_ARCH_FRV, -1, -1 },
+#endif
+#ifdef AUDIT_ARCH_M32R
+ { AUDIT_ARCH_M32R, -1, -1 },
+#endif
+#ifdef AUDIT_ARCH_M68K
+ { AUDIT_ARCH_M68K, 14, 290 },
+#endif
+#ifdef AUDIT_ARCH_MICROBLAZE
+ { AUDIT_ARCH_MICROBLAZE, 14, 297 },
+#endif
+#ifdef AUDIT_ARCH_MIPS
+ { AUDIT_ARCH_MIPS, 14, 290 },
+#endif
+#ifdef AUDIT_ARCH_MIPSEL
+ { AUDIT_ARCH_MIPSEL, 14, 290 },
+#endif
+#ifdef AUDIT_ARCH_MIPS64
+ { AUDIT_ARCH_MIPS64, 131, 249 },
+#endif
+#ifdef AUDIT_ARCH_MIPS64N32
+ { AUDIT_ARCH_MIPS64N32, 131, 253 },
+#endif
+#ifdef AUDIT_ARCH_MIPSEL64
+ { AUDIT_ARCH_MIPSEL64, 131, 249 },
+#endif
+#ifdef AUDIT_ARCH_MIPSEL64N32
+ { AUDIT_ARCH_MIPSEL64N32, 131, 253 },
+#endif
+#ifdef AUDIT_ARCH_SH
+ { AUDIT_ARCH_SH, 14, 297 },
+#endif
+#ifdef AUDIT_ARCH_SHEL
+ { AUDIT_ARCH_SHEL, 14, 297 },
+#endif
+#ifdef AUDIT_ARCH_SH64
+ { AUDIT_ARCH_SH64, 14, 297 },
+#endif
+#ifdef AUDIT_ARCH_SHEL64
+ { AUDIT_ARCH_SHEL64, 14, 297 },
+#endif
+#ifdef AUDIT_ARCH_TILEGX
+ { AUDIT_ARCH_TILEGX, -1, -1 },
+#endif
+#ifdef AUDIT_ARCH_TILEGX32
+ { AUDIT_ARCH_TILEGX32, -1, -1 },
+#endif
+#ifdef AUDIT_ARCH_TILEPRO
+ { AUDIT_ARCH_TILEPRO, -1, -1 },
+#endif
+#ifdef AUDIT_ARCH_XTENSA
+ { AUDIT_ARCH_XTENSA, 36, 290 },
+#endif
+};
+
+// #if defined(__alpha__)
+// static int mknod[] = {14}
+// static int mknodat[] = {452}
+// #elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
+// static int mknod[] = {
+// 14, // i386
+// 133 // x86_64
+// }
+// static int mknodat[] = {
+// 297, // i386
+// 259 //x86_64
+// }
+// #elif defined (__arc__)
+// static int mknod[] = {
+// -1 // mknod is not defined
+// }
+// static int mknodat[] = {
+// 33 // uses asm-generic
+// }
+// #elif defined(__arm__)
+// static int mknod[] = {
+// 14, // i386
+// 133 // x86_64
+// }
+// static int mknodat[] = {
+// 297, // i386
+// 259 //x86_64
+// }
+// #elif defined(__aarch64__)
+// #elif defined(__i386__) || defined(i386) || defined(__i386)
+// #elif defined(__ia64__) || defined(_IA64) || defined(__IA64__)
+// #elif defined(__m68k__)
+// #elif defined(__mips__) || defined(_MIPS_SIM)
+// #elif defined(__powerpc) || defined(__powerpc__) || defined(__powerpc64__) || defined(__POWERPC__) || defined(__ppc__) || defined(__ppc64__) || defined(__PPC__) || defined(__PPC64__) || defined(_ARCH_PPC) || defined(_ARCH_PPC64)
+// #elif defined(__sparc__)
+// #elif defined(__sh__)
+// #elif defined(__s390__) || defined(__s390x__) || defined(__zarch__) || defined(__SYSC_ZARCH__)
+// #endif
+
#ifndef __NR_mknodat
#error missing kernel headers
#else
@@ -161,51 +329,58 @@ static int seccomp_notify_mknod_set_response(int fd_mem,
resp->val = 0;
resp->error = 0;
- switch (req->data.nr) {
-#ifdef LXD_MUST_CHECK_MKNOD
- case __NR_mknod:
- resp->error = device_allowed(req->data.args[2], req->data.args[1]);
- if (resp->error) {
- errno = EPERM;
- return -1;
- }
+ for (size_t i = 0; i < (sizeof(seccomp_notify_syscall_table) / sizeof(seccomp_notify_syscall_table[0])); i++) {
+ const struct lxd_seccomp_data_arch *entry = &seccomp_notify_syscall_table[i];
- bytes = pread(fd_mem, buf, size, req->data.args[0]);
- if (bytes < 0)
- return -1;
+ if (entry->arch != req->data.arch)
+ continue;
- *mode = req->data.args[1];
- *dev = req->data.args[2];
- *pid = req->pid;
+ if (entry->nr_mknod == req->data.nr) {
+ resp->error = device_allowed(req->data.args[2], req->data.args[1]);
+ if (resp->error) {
+ errno = EPERM;
+ return -EPERM;
+ }
- break;
-#endif
- case __NR_mknodat:
- if (req->data.args[0] != AT_FDCWD) {
- errno = EINVAL;
- return -1;
- }
+ bytes = pread(fd_mem, buf, size, req->data.args[0]);
+ if (bytes < 0)
+ return -errno;
+
+ *mode = req->data.args[1];
+ *dev = req->data.args[2];
+ *pid = req->pid;
- resp->error = device_allowed(req->data.args[3], req->data.args[2]);
- if (resp->error) {
- errno = EPERM;
- return -EPERM;
+ return 0;
}
- bytes = pread(fd_mem, buf, size, req->data.args[1]);
- if (bytes < 0)
- return -1;
+ if (entry->nr_mknodat == req->data.nr) {
+ if ((int)req->data.args[0] != AT_FDCWD) {
+ errno = EINVAL;
+ return -EINVAL;
+ }
- *mode = req->data.args[2];
- *dev = req->data.args[3];
- *pid = req->pid;
+ resp->error = device_allowed(req->data.args[3], req->data.args[2]);
+ if (resp->error) {
+ errno = EPERM;
+ return -EPERM;
+ }
+
+ bytes = pread(fd_mem, buf, size, req->data.args[1]);
+ if (bytes < 0)
+ return -errno;
+
+ *mode = req->data.args[2];
+ *dev = req->data.args[3];
+ *pid = req->pid;
+
+ return 0;
+ }
break;
- default:
- return -1;
}
- return 0;
+ errno = EPERM;
+ return -EPERM;
}
static void seccomp_notify_mknod_update_response(struct seccomp_notif_resp *resp,
@@ -701,11 +876,11 @@ func (s *SeccompServer) Handler(c net.Conn, clientFd int, ucred *ucred,
var err error
goErrno := 0
cPathBuf := [unix.PathMax]C.char{}
- ret := C.seccomp_notify_mknod_set_response(C.int(fdMem), req, resp,
+ goErrno = int(C.seccomp_notify_mknod_set_response(C.int(fdMem), req, resp,
&cPathBuf[0],
unix.PathMax, &cMode,
- &cDev, &cPid)
- if ret == 0 {
+ &cDev, &cPid))
+ if goErrno == 0 {
dev := types.Device{}
dev["type"] = "unix-char"
dev["mode"] = fmt.Sprintf("%#o", cMode)
More information about the lxc-devel
mailing list