aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sysemu/seccomp.h3
-rw-r--r--qemu-seccomp.c121
-rw-r--r--vl.c124
3 files changed, 130 insertions, 118 deletions
diff --git a/include/sysemu/seccomp.h b/include/sysemu/seccomp.h
index 9b092aa23f..fe859894f6 100644
--- a/include/sysemu/seccomp.h
+++ b/include/sysemu/seccomp.h
@@ -21,5 +21,6 @@
#define QEMU_SECCOMP_SET_SPAWN (1 << 3)
#define QEMU_SECCOMP_SET_RESOURCECTL (1 << 4)
-int seccomp_start(uint32_t seccomp_opts);
+int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp);
+
#endif
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
diff --git a/vl.c b/vl.c
index 038d7f8042..4a0e17833d 100644
--- a/vl.c
+++ b/vl.c
@@ -28,11 +28,7 @@
#include "qemu/cutils.h"
#include "qemu/help_option.h"
#include "qemu/uuid.h"
-
-#ifdef CONFIG_SECCOMP
-#include <sys/prctl.h>
#include "sysemu/seccomp.h"
-#endif
#ifdef CONFIG_SDL
#if defined(__APPLE__) || defined(main)
@@ -259,35 +255,6 @@ static QemuOptsList qemu_rtc_opts = {
},
};
-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 QemuOptsList qemu_option_rom_opts = {
.name = "option-rom",
.implied_opt_name = "romfile",
@@ -1043,88 +1010,6 @@ static int bt_parse(const char *opt)
return 1;
}
-static int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp)
-{
- if (qemu_opt_get_bool(opts, "enable", false)) {
-#ifdef CONFIG_SECCOMP
- 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;
- }
-#else
- error_report("seccomp support is disabled");
- return -1;
-#endif
- }
-
- return 0;
-}
-
static int parse_name(void *opaque, QemuOpts *opts, Error **errp)
{
const char *proc_name;
@@ -3059,7 +2944,6 @@ int main(int argc, char **argv, char **envp)
qemu_add_opts(&qemu_mem_opts);
qemu_add_opts(&qemu_smp_opts);
qemu_add_opts(&qemu_boot_opts);
- qemu_add_opts(&qemu_sandbox_opts);
qemu_add_opts(&qemu_add_fd_opts);
qemu_add_opts(&qemu_object_opts);
qemu_add_opts(&qemu_tpmdev_opts);
@@ -3957,11 +3841,17 @@ int main(int argc, char **argv, char **envp)
qtest_log = optarg;
break;
case QEMU_OPTION_sandbox:
+#ifdef CONFIG_SECCOMP
opts = qemu_opts_parse_noisily(qemu_find_opts("sandbox"),
optarg, true);
if (!opts) {
exit(1);
}
+#else
+ error_report("-sandbox support is not enabled "
+ "in this QEMU binary");
+ exit(1);
+#endif
break;
case QEMU_OPTION_add_fd:
#ifndef _WIN32
@@ -4048,10 +3938,12 @@ int main(int argc, char **argv, char **envp)
exit(1);
}
+#ifdef CONFIG_SECCOMP
if (qemu_opts_foreach(qemu_find_opts("sandbox"),
parse_sandbox, NULL, NULL)) {
exit(1);
}
+#endif
if (qemu_opts_foreach(qemu_find_opts("name"),
parse_name, NULL, NULL)) {