diff mbox

[2/2] Creating qemu-seccomp.[ch] and adding call to vl.c

Message ID 5fa20a89801d7f1183490b87ffa9b6bde0dba22d.1340315275.git.otubo@linux.vnet.ibm.com
State New
Headers show

Commit Message

Eduardo Otubo June 21, 2012, 10:10 p.m. UTC
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

The whitelist is getting bigger and complete, maybe it's time to drop
the RFC tag.

Signed-off-by: Eduardo Otubo <otubo@linux.vnet.ibm.com>
---
 qemu-seccomp.c |   88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 qemu-seccomp.h |   23 +++++++++++++++
 vl.c           |   11 +++++++
 3 files changed, 122 insertions(+)
 create mode 100644 qemu-seccomp.c
 create mode 100644 qemu-seccomp.h

Comments

Stefan Hajnoczi June 22, 2012, 8:29 a.m. UTC | #1
On Thu, Jun 21, 2012 at 11:10 PM, Eduardo Otubo
<otubo@linux.vnet.ibm.com> wrote:
> 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
>
> The whitelist is getting bigger and complete, maybe it's time to drop
> the RFC tag.
>
> Signed-off-by: Eduardo Otubo <otubo@linux.vnet.ibm.com>
> ---
>  qemu-seccomp.c |   88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  qemu-seccomp.h |   23 +++++++++++++++
>  vl.c           |   11 +++++++
>  3 files changed, 122 insertions(+)
>  create mode 100644 qemu-seccomp.c
>  create mode 100644 qemu-seccomp.h
>
> diff --git a/qemu-seccomp.c b/qemu-seccomp.c
> new file mode 100644
> index 0000000..0442348
> --- /dev/null
> +++ b/qemu-seccomp.c
> @@ -0,0 +1,88 @@
> +/*
> + * 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;
> +};
> +
> +const static 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(bind), 245 },
> +    { SCMP_SYS(listen), 245 },
> +    { SCMP_SYS(ioctl), 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 }

preadv, pwritev, io_submit, io_cancel, io_getevents

Stefan
Blue Swirl June 24, 2012, 6:08 a.m. UTC | #2
On Thu, Jun 21, 2012 at 10:10 PM, Eduardo Otubo
<otubo@linux.vnet.ibm.com> wrote:
> 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
>
> The whitelist is getting bigger and complete, maybe it's time to drop
> the RFC tag.
>
> Signed-off-by: Eduardo Otubo <otubo@linux.vnet.ibm.com>
> ---
>  qemu-seccomp.c |   88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  qemu-seccomp.h |   23 +++++++++++++++
>  vl.c           |   11 +++++++
>  3 files changed, 122 insertions(+)
>  create mode 100644 qemu-seccomp.c
>  create mode 100644 qemu-seccomp.h
>
> diff --git a/qemu-seccomp.c b/qemu-seccomp.c
> new file mode 100644
> index 0000000..0442348
> --- /dev/null
> +++ b/qemu-seccomp.c
> @@ -0,0 +1,88 @@
> +/*
> + * 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.

Can't you just license the files under GPLv2+ directly?

> + */
> +#include <stdio.h>
> +#include <seccomp.h>
> +#include "qemu-seccomp.h"
> +
> +struct QemuSeccompSyscall {
> +    int32_t num;
> +    uint8_t priority;
> +};
> +
> +const static struct QemuSeccompSyscall seccomp_whitelist[] = {

Usually the order is 'static const'.

> +    { 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(bind), 245 },
> +    { SCMP_SYS(listen), 245 },
> +    { SCMP_SYS(ioctl), 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(void)
> +{
> +    int rc = 0;
> +    unsigned int i = 0;
> +
> +    rc = seccomp_init(SCMP_ACT_KILL);
> +    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..3253786
> --- /dev/null
> +++ b/qemu-seccomp.h
> @@ -0,0 +1,23 @@
> +/*
> + * 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 CONFIG_LIBSECCOMP
> +#define CONFIG_LIBSECCOMP
> +
> +#include <seccomp.h>
> +#include "osdep.h"
> +
> +int seccomp_start(void);
> +
> +#endif
> diff --git a/vl.c b/vl.c
> index 1329c30..83526f1 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -62,6 +62,9 @@
>  #include <linux/ppdev.h>
>  #include <linux/parport.h>
>  #endif
> +#ifdef CONFIG_LIBSECCOMP
> +#include "qemu-seccomp.h"
> +#endif
>  #ifdef __sun__
>  #include <sys/stat.h>
>  #include <sys/ethernet.h>
> @@ -2296,6 +2299,14 @@ int main(int argc, char **argv, char **envp)
>     const char *trace_events = NULL;
>     const char *trace_file = NULL;
>
> +#ifdef CONFIG_LIBSECCOMP
> +    if (seccomp_start() < 0) {
> +        fprintf(stderr,
> +                "failed to configure the seccomp syscall filter in the kernel\n");
> +        exit(1);
> +    }
> +#endif
> +
>     atexit(qemu_run_exit_notifiers);
>     error_set_progname(argv[0]);
>
> --
> 1.7.9.5
>
>
diff mbox

Patch

diff --git a/qemu-seccomp.c b/qemu-seccomp.c
new file mode 100644
index 0000000..0442348
--- /dev/null
+++ b/qemu-seccomp.c
@@ -0,0 +1,88 @@ 
+/*
+ * 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;
+};
+
+const static 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(bind), 245 },
+    { SCMP_SYS(listen), 245 },
+    { SCMP_SYS(ioctl), 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(void)
+{
+    int rc = 0;
+    unsigned int i = 0;
+
+    rc = seccomp_init(SCMP_ACT_KILL);
+    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..3253786
--- /dev/null
+++ b/qemu-seccomp.h
@@ -0,0 +1,23 @@ 
+/*
+ * 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 CONFIG_LIBSECCOMP
+#define CONFIG_LIBSECCOMP
+
+#include <seccomp.h>
+#include "osdep.h"
+
+int seccomp_start(void);
+
+#endif
diff --git a/vl.c b/vl.c
index 1329c30..83526f1 100644
--- a/vl.c
+++ b/vl.c
@@ -62,6 +62,9 @@ 
 #include <linux/ppdev.h>
 #include <linux/parport.h>
 #endif
+#ifdef CONFIG_LIBSECCOMP
+#include "qemu-seccomp.h"
+#endif
 #ifdef __sun__
 #include <sys/stat.h>
 #include <sys/ethernet.h>
@@ -2296,6 +2299,14 @@  int main(int argc, char **argv, char **envp)
     const char *trace_events = NULL;
     const char *trace_file = NULL;
 
+#ifdef CONFIG_LIBSECCOMP
+    if (seccomp_start() < 0) {
+        fprintf(stderr,
+                "failed to configure the seccomp syscall filter in the kernel\n");
+        exit(1);
+    }
+#endif
+
     atexit(qemu_run_exit_notifiers);
     error_set_progname(argv[0]);