aboutsummaryrefslogtreecommitdiff
path: root/qemu-seccomp.c
diff options
context:
space:
mode:
authorYi Min Zhao <zyimin@linux.ibm.com>2018-05-31 11:29:37 +0800
committerEduardo Otubo <otubo@redhat.com>2018-06-01 13:44:15 +0200
commit9d0fdecbad130f01b602e35e87c6d3fad5821d6e (patch)
tree82f742cd079629bf6451341a3f377cd93be3d2f5 /qemu-seccomp.c
parent14fc618461c2756a3f0b16bf6af198c5d7731137 (diff)
sandbox: disable -sandbox if CONFIG_SECCOMP undefined
If CONFIG_SECCOMP is undefined, the option 'elevatedprivileges' remains compiled. This would make libvirt set the corresponding capability and then trigger failure during guest startup. This patch moves the code regarding seccomp command line options to qemu-seccomp.c file and wraps qemu_opts_foreach finding sandbox option with CONFIG_SECCOMP. Because parse_sandbox() is moved into qemu-seccomp.c file, change seccomp_start() to static function. Signed-off-by: Yi Min Zhao <zyimin@linux.ibm.com> Reviewed-by: Ján Tomko <jtomko@redhat.com> Tested-by: Ján Tomko <jtomko@redhat.com> Acked-by: Eduardo Otubo <otubo@redhat.com>
Diffstat (limited to 'qemu-seccomp.c')
-rw-r--r--qemu-seccomp.c121
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