diff options
author | Peter Maydell | 2018-06-01 14:11:30 +0200 |
---|---|---|
committer | Peter Maydell | 2018-06-01 14:11:30 +0200 |
commit | c25e8bba1f546ea72744ccfab77f8a9e8a323be8 (patch) | |
tree | 82f742cd079629bf6451341a3f377cd93be3d2f5 /qemu-seccomp.c | |
parent | Merge remote-tracking branch 'remotes/sstabellini-http/tags/xen-20180531-tag'... (diff) | |
parent | sandbox: disable -sandbox if CONFIG_SECCOMP undefined (diff) | |
download | qemu-c25e8bba1f546ea72744ccfab77f8a9e8a323be8.tar.gz qemu-c25e8bba1f546ea72744ccfab77f8a9e8a323be8.tar.xz qemu-c25e8bba1f546ea72744ccfab77f8a9e8a323be8.zip |
Merge remote-tracking branch 'remotes/otubo/tags/pull-seccomp-20180601' into staging
pull-seccomp-20180601
# gpg: Signature made Fri 01 Jun 2018 13:01:18 BST
# gpg: using RSA key DF32E7C0F0FFF9A2
# gpg: Good signature from "Eduardo Otubo (Senior Software Engineer) <otubo@redhat.com>"
# Primary key fingerprint: D67E 1B50 9374 86B4 0723 DBAB DF32 E7C0 F0FF F9A2
* remotes/otubo/tags/pull-seccomp-20180601:
sandbox: disable -sandbox if CONFIG_SECCOMP undefined
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'qemu-seccomp.c')
-rw-r--r-- | qemu-seccomp.c | 121 |
1 files changed, 120 insertions, 1 deletions
diff --git a/qemu-seccomp.c b/qemu-seccomp.c index b770a77d33..148e4c6f24 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -13,6 +13,11 @@ * GNU GPL, version 2 or (at your option) any later version. */ #include "qemu/osdep.h" +#include "qemu/config-file.h" +#include "qemu/option.h" +#include "qemu/module.h" +#include "qemu/error-report.h" +#include <sys/prctl.h> #include <seccomp.h> #include "sysemu/seccomp.h" @@ -96,7 +101,7 @@ static const struct QemuSeccompSyscall blacklist[] = { }; -int seccomp_start(uint32_t seccomp_opts) +static int seccomp_start(uint32_t seccomp_opts) { int rc = 0; unsigned int i = 0; @@ -125,3 +130,117 @@ int seccomp_start(uint32_t seccomp_opts) seccomp_release(ctx); return rc; } + +#ifdef CONFIG_SECCOMP +int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp) +{ + if (qemu_opt_get_bool(opts, "enable", false)) { + uint32_t seccomp_opts = QEMU_SECCOMP_SET_DEFAULT + | QEMU_SECCOMP_SET_OBSOLETE; + const char *value = NULL; + + value = qemu_opt_get(opts, "obsolete"); + if (value) { + if (g_str_equal(value, "allow")) { + seccomp_opts &= ~QEMU_SECCOMP_SET_OBSOLETE; + } else if (g_str_equal(value, "deny")) { + /* this is the default option, this if is here + * to provide a little bit of consistency for + * the command line */ + } else { + error_report("invalid argument for obsolete"); + return -1; + } + } + + value = qemu_opt_get(opts, "elevateprivileges"); + if (value) { + if (g_str_equal(value, "deny")) { + seccomp_opts |= QEMU_SECCOMP_SET_PRIVILEGED; + } else if (g_str_equal(value, "children")) { + seccomp_opts |= QEMU_SECCOMP_SET_PRIVILEGED; + + /* calling prctl directly because we're + * not sure if host has CAP_SYS_ADMIN set*/ + if (prctl(PR_SET_NO_NEW_PRIVS, 1)) { + error_report("failed to set no_new_privs " + "aborting"); + return -1; + } + } else if (g_str_equal(value, "allow")) { + /* default value */ + } else { + error_report("invalid argument for elevateprivileges"); + return -1; + } + } + + value = qemu_opt_get(opts, "spawn"); + if (value) { + if (g_str_equal(value, "deny")) { + seccomp_opts |= QEMU_SECCOMP_SET_SPAWN; + } else if (g_str_equal(value, "allow")) { + /* default value */ + } else { + error_report("invalid argument for spawn"); + return -1; + } + } + + value = qemu_opt_get(opts, "resourcecontrol"); + if (value) { + if (g_str_equal(value, "deny")) { + seccomp_opts |= QEMU_SECCOMP_SET_RESOURCECTL; + } else if (g_str_equal(value, "allow")) { + /* default value */ + } else { + error_report("invalid argument for resourcecontrol"); + return -1; + } + } + + if (seccomp_start(seccomp_opts) < 0) { + error_report("failed to install seccomp syscall filter " + "in the kernel"); + return -1; + } + } + + return 0; +} + +static QemuOptsList qemu_sandbox_opts = { + .name = "sandbox", + .implied_opt_name = "enable", + .head = QTAILQ_HEAD_INITIALIZER(qemu_sandbox_opts.head), + .desc = { + { + .name = "enable", + .type = QEMU_OPT_BOOL, + }, + { + .name = "obsolete", + .type = QEMU_OPT_STRING, + }, + { + .name = "elevateprivileges", + .type = QEMU_OPT_STRING, + }, + { + .name = "spawn", + .type = QEMU_OPT_STRING, + }, + { + .name = "resourcecontrol", + .type = QEMU_OPT_STRING, + }, + { /* end of list */ } + }, +}; + +static void seccomp_register(void) +{ + qemu_add_opts(&qemu_sandbox_opts); +} +opts_init(seccomp_register); +#endif |