diff mbox

[PATCHv4,2/4] Adding qemu-seccomp.[ch]

Message ID 60bb02396e4c2a8e9a50439b654511ccd4ecceb6.1342552002.git.otubo@linux.vnet.ibm.com
State New
Headers show

Commit Message

Eduardo Otubo July 17, 2012, 7:19 p.m. UTC
v1:
 * I added a syscall struct using priority levels as described in the
   libseccomp man page. The priority numbers are based to the frequency
   they appear in a sample strace from a regular qemu guest run under
   libvirt.

   Libseccomp generates linear BPF code to filter system calls, those rules
   are read one after another. The priority system places the most common
   rules first in order to reduce the overhead when processing them.

v2:
 * Fixed some style issues
 * Removed code from vl.c and created qemu-seccomp.[ch]
 * Now using ARRAY_SIZE macro
 * Added more syscalls without priority/frequency set yet

v3:
 * Adding copyright and license information
 * Replacing seccomp_whitelist_count just by ARRAY_SIZE
 * Adding header protection to qemu-seccomp.h
 * Moving QemuSeccompSyscall definition to qemu-seccomp.c
 * Negative return from seccomp_start is fatal now.
 * Adding open() and execve() to the whitelis

v4:
 * Tests revealed a bigger set of syscalls.
 * seccomp_start() now has an argument to set the mode according to the
   configure option trap or kill.

Signed-off-by: Eduardo Otubo <otubo@linux.vnet.ibm.com>
---
 qemu-seccomp.c |  126 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 qemu-seccomp.h |   22 ++++++++++
 2 files changed, 148 insertions(+)
 create mode 100644 qemu-seccomp.c
 create mode 100644 qemu-seccomp.h
diff mbox

Patch

diff --git a/qemu-seccomp.c b/qemu-seccomp.c
new file mode 100644
index 0000000..6a349b6
--- /dev/null
+++ b/qemu-seccomp.c
@@ -0,0 +1,126 @@ 
+/*
+ * QEMU seccomp mode 2 support with libseccomp
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ *  Eduardo Otubo    <eotubo@br.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ * Contributions after 2012-01-13 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
+ */
+#include <stdio.h>
+#include <seccomp.h>
+#include "qemu-seccomp.h"
+
+struct QemuSeccompSyscall {
+    int32_t num;
+    uint8_t priority;
+};
+
+static const struct QemuSeccompSyscall seccomp_whitelist[] = {
+    { SCMP_SYS(timer_settime), 255 },
+    { SCMP_SYS(timer_gettime), 254 },
+    { SCMP_SYS(futex), 253 },
+    { SCMP_SYS(select), 252 },
+    { SCMP_SYS(recvfrom), 251 },
+    { SCMP_SYS(sendto), 250 },
+    { SCMP_SYS(read), 249 },
+    { SCMP_SYS(brk), 248 },
+    { SCMP_SYS(clone), 247 },
+    { SCMP_SYS(mmap), 247 },
+    { SCMP_SYS(mprotect), 246 },
+    { SCMP_SYS(execve), 245 },
+    { SCMP_SYS(open), 245 },
+    { SCMP_SYS(ioctl), 245 },
+    { SCMP_SYS(recvmsg), 245 },
+    { SCMP_SYS(sendmsg), 245 },
+    { SCMP_SYS(accept), 245 },
+    { SCMP_SYS(connect), 245 },
+    { SCMP_SYS(gettimeofday), 245 },
+    { SCMP_SYS(readlink), 245 },
+    { SCMP_SYS(access), 245 },
+    { SCMP_SYS(prctl), 245 },
+    { SCMP_SYS(signalfd), 245 },
+    { SCMP_SYS(fcntl64), 245 },
+    { SCMP_SYS(eventfd2), 245 },
+    { SCMP_SYS(dup), 245 },
+    { SCMP_SYS(gettid), 245 },
+    { SCMP_SYS(timer_create), 245 },
+    { SCMP_SYS(fstat64), 245 },
+    { SCMP_SYS(stat64), 245 },
+    { SCMP_SYS(exit), 245 },
+    { SCMP_SYS(clock_gettime), 245 },
+    { SCMP_SYS(time), 245 },
+    { SCMP_SYS(restart_syscall), 245 },
+    { SCMP_SYS(getgid32), 245 },
+    { SCMP_SYS(getegid32), 245 },
+    { SCMP_SYS(getuid32), 245 },
+    { SCMP_SYS(geteuid32), 245 },
+    { SCMP_SYS(pwrite64), 245 },
+    { SCMP_SYS(chown), 245 },
+    { SCMP_SYS(openat), 245 },
+    { SCMP_SYS(getdents), 245 },
+    { SCMP_SYS(timer_delete), 245 },
+    { SCMP_SYS(exit_group), 245 },
+    { SCMP_SYS(sigreturn), 245 },
+    { SCMP_SYS(rt_sigreturn), 245 },
+    { SCMP_SYS(_newselect), 245 },
+    { SCMP_SYS(_llseek), 245 },
+    { SCMP_SYS(mmap2), 245},
+    { SCMP_SYS(sync), 245 },
+    { SCMP_SYS(pread64), 245 },
+    { SCMP_SYS(madvise), 245 },
+    { SCMP_SYS(set_robust_list), 245 },
+    { SCMP_SYS(lseek), 245 },
+    { SCMP_SYS(sigprocmask), 245 },
+    { SCMP_SYS(pselect6), 245 },
+    { SCMP_SYS(fork), 245 },
+    { SCMP_SYS(bind), 245 },
+    { SCMP_SYS(listen), 245 },
+    { SCMP_SYS(eventfd), 245 },
+    { SCMP_SYS(rt_sigprocmask), 245 },
+    { SCMP_SYS(write), 244 },
+    { SCMP_SYS(fcntl), 243 },
+    { SCMP_SYS(tgkill), 242 },
+    { SCMP_SYS(rt_sigaction), 242 },
+    { SCMP_SYS(pipe2), 242 },
+    { SCMP_SYS(munmap), 242 },
+    { SCMP_SYS(mremap), 242 },
+    { SCMP_SYS(getsockname), 242 },
+    { SCMP_SYS(getpeername), 242 },
+    { SCMP_SYS(fdatasync), 242 },
+    { SCMP_SYS(close), 242 }
+};
+
+int seccomp_start(uint32_t mode)
+{
+    int rc = 0;
+    unsigned int i = 0;
+
+    rc = seccomp_init(mode);
+    if (rc < 0) {
+        goto seccomp_return;
+    }
+
+    for (i = 0; i < ARRAY_SIZE(seccomp_whitelist); i++) {
+        rc = seccomp_rule_add(SCMP_ACT_ALLOW, seccomp_whitelist[i].num, 0);
+        if (rc < 0) {
+            goto seccomp_return;
+        }
+        rc = seccomp_syscall_priority(seccomp_whitelist[i].num,
+                                      seccomp_whitelist[i].priority);
+        if (rc < 0) {
+            goto seccomp_return;
+        }
+    }
+
+    rc = seccomp_load();
+
+  seccomp_return:
+    seccomp_release();
+    return rc;
+}
diff --git a/qemu-seccomp.h b/qemu-seccomp.h
new file mode 100644
index 0000000..087333f
--- /dev/null
+++ b/qemu-seccomp.h
@@ -0,0 +1,22 @@ 
+/*
+ * QEMU seccomp mode 2 support with libseccomp
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ *  Eduardo Otubo    <eotubo@br.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ * Contributions after 2012-01-13 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
+ */
+#ifndef QEMU_SECCOMP_H
+#define QEMU_SECCOMP_H
+
+#include <seccomp.h>
+#include "osdep.h"
+
+int seccomp_start(uint32_t mode);
+#endif