[Qemu-devel] [PATCH v3 5/6] seccomp: add resourcecontrol argument to command line
This patch adds [,resourcecontrol=deny] to `-sandbox on' option. It blacklists all process affinity and scheduler priority system calls to avoid any bigger of the process. Signed-off-by: Eduardo Otubo --- include/sysemu/seccomp.h | 1 + qemu-options.hx | 9 ++--- qemu-seccomp.c | 28 vl.c | 11 +++ 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/include/sysemu/seccomp.h b/include/sysemu/seccomp.h index f1614d6514..c7003dd197 100644 --- a/include/sysemu/seccomp.h +++ b/include/sysemu/seccomp.h @@ -18,6 +18,7 @@ #define OBSOLETE0x0001 #define PRIVILEGED 0x0010 #define SPAWN 0x0100 +#define RESOURCECTL 0x1000 #include diff --git a/qemu-options.hx b/qemu-options.hx index 3d612f0fd1..7192236dee 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4004,13 +4004,14 @@ Old param mode (ARM only). ETEXI DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \ -"-sandbox on[,obsolete=allow][,elevateprivileges=allow|deny|children][,spawn=deny] Enable seccomp mode 2 system call filter (default 'off').\n" \ +"-sandbox on[,obsolete=allow][,elevateprivileges=allow|deny|children][,spawn=deny][,resourcecontrol=deny] Enable seccomp mode 2 system call filter (default 'off').\n" \ "obsolete: Allow obsolete system calls\n" "elevateprivileges: allows or denies Qemu process to elevate its privileges by blacklisting all set*uid|gid system calls. 'children' will deny set*uid|gid system calls for main Qemu process but will allow forks and execves to run unprivileged\n" -"spawn: avoids Qemu to spawn new threads or processes by blacklisting *fork and execve\n", +"spawn: avoids Qemu to spawn new threads or processes by blacklisting *fork and execve\n" +"resourcecontrol: disable process affinity and schedular priority\n", QEMU_ARCH_ALL) STEXI -@item -sandbox @var{arg}[,obsolete=@var{string}][,elevateprivileges=@var{string}][,spawn=@var{string}] +@item -sandbox @var{arg}[,obsolete=@var{string}][,elevateprivileges=@var{string}][,spawn=@var{string}][,resourcecontrol=@var{string}] @findex -sandbox Enable Seccomp mode 2 system call filter. 'on' will enable syscall filtering and 'off' will disable it. The default is 'off'. @@ -4021,6 +4022,8 @@ Enable Obsolete system calls Disable set*uid|gid systema calls @item spawn=@var{string} Disable *fork and execve +@item resourcecontrol=@var{string} +Disable process affinity and schedular priority @end table ETEXI diff --git a/qemu-seccomp.c b/qemu-seccomp.c index 22a093ca1b..95c8e31d1a 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -31,6 +31,19 @@ struct QemuSeccompSyscall { uint8_t priority; }; +static const struct QemuSeccompSyscall resourcecontrol_syscalls[] = { +{ SCMP_SYS(getpriority), 255 }, +{ SCMP_SYS(setpriority), 255 }, +{ SCMP_SYS(sched_setparam), 255 }, +{ SCMP_SYS(sched_getparam), 255 }, +{ SCMP_SYS(sched_setscheduler), 255 }, +{ SCMP_SYS(sched_getscheduler), 255 }, +{ SCMP_SYS(sched_setaffinity), 255 }, +{ SCMP_SYS(sched_getaffinity), 255 }, +{ SCMP_SYS(sched_get_priority_max), 255 }, +{ SCMP_SYS(sched_get_priority_min), 255 }, +}; + static const struct QemuSeccompSyscall spawn_syscalls[] = { { SCMP_SYS(fork), 255 }, { SCMP_SYS(vfork), 255 }, @@ -158,6 +171,21 @@ int seccomp_start(uint8_t seccomp_opts) } } +if (seccomp_opts & RESOURCECTL) { +for (i = 0; i < ARRAY_SIZE(resourcecontrol_syscalls); i++) { +rc = seccomp_rule_add(ctx, SCMP_ACT_KILL, + resourcecontrol_syscalls[i].num, 0); +if (rc < 0) { +goto seccomp_return; +} +rc = seccomp_syscall_priority(ctx, resourcecontrol_syscalls[i].num, + resourcecontrol_syscalls[i].priority); +if (rc < 0) { +goto seccomp_return; +} +} +} + rc = seccomp_load(ctx); seccomp_return: diff --git a/vl.c b/vl.c index e3a59ef1b5..c09d6dde49 100644 --- a/vl.c +++ b/vl.c @@ -284,6 +284,10 @@ static QemuOptsList qemu_sandbox_opts = { .name = "spawn", .type = QEMU_OPT_STRING, }, +{ +.name = "resourcecontrol", +.type = QEMU_OPT_STRING, +}, { /* end of list */ } }, }; @@ -1079,6 +1083,13 @@ static int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp) } } +value = qemu_opt_get(opts, "resourcecontrol"); +if (value) { +if (strcmp(value, "deny") == 0) { +seccom
[Qemu-devel] [PATCH v3 3/6] seccomp: add elevateprivileges argument to command line
This patch introduces the new argument [,elevateprivileges=allow|deny|children] to the `-sandbox on'. It allows or denies Qemu process to elevate its privileges by blacklisting all set*uid|gid system calls. The 'children' option will let forks and execves run unprivileged. Signed-off-by: Eduardo Otubo --- include/sysemu/seccomp.h | 1 + qemu-options.hx | 9 ++--- qemu-seccomp.c | 29 + vl.c | 22 ++ 4 files changed, 58 insertions(+), 3 deletions(-) diff --git a/include/sysemu/seccomp.h b/include/sysemu/seccomp.h index 7a7bde246b..e6e78d85ce 100644 --- a/include/sysemu/seccomp.h +++ b/include/sysemu/seccomp.h @@ -16,6 +16,7 @@ #define QEMU_SECCOMP_H #define OBSOLETE0x0001 +#define PRIVILEGED 0x0010 #include diff --git a/qemu-options.hx b/qemu-options.hx index 54e492f36a..34d33a812e 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4004,17 +4004,20 @@ Old param mode (ARM only). ETEXI DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \ -"-sandbox on[,obsolete=allow] Enable seccomp mode 2 system call filter (default 'off').\n" \ -"obsolete: Allow obsolete system calls\n", +"-sandbox on[,obsolete=allow][,elevateprivileges=allow|deny|children] Enable seccomp mode 2 system call filter (default 'off').\n" \ +"obsolete: Allow obsolete system calls\n" +"elevateprivileges: allows or denies Qemu process to elevate its privileges by blacklisting all set*uid|gid system calls. 'children' will deny set*uid|gid system calls for main Qemu process but will allow forks and execves to run unprivileged\n", QEMU_ARCH_ALL) STEXI -@item -sandbox @var{arg}[,obsolete=@var{string}] +@item -sandbox @var{arg}[,obsolete=@var{string}][,elevateprivileges=@var{string}] @findex -sandbox Enable Seccomp mode 2 system call filter. 'on' will enable syscall filtering and 'off' will disable it. The default is 'off'. @table @option @item obsolete=@var{string} Enable Obsolete system calls +@item elevateprivileges=@var{string} +Disable set*uid|gid systema calls @end table ETEXI diff --git a/qemu-seccomp.c b/qemu-seccomp.c index c6a8b28260..6caa513edd 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -31,6 +31,19 @@ struct QemuSeccompSyscall { uint8_t priority; }; +static const struct QemuSeccompSyscall privileged_syscalls[] = { +{ SCMP_SYS(setuid), 255 }, +{ SCMP_SYS(setgid), 255 }, +{ SCMP_SYS(setpgid), 255 }, +{ SCMP_SYS(setsid), 255 }, +{ SCMP_SYS(setreuid), 255 }, +{ SCMP_SYS(setregid), 255 }, +{ SCMP_SYS(setresuid), 255 }, +{ SCMP_SYS(setresgid), 255 }, +{ SCMP_SYS(setfsuid), 255 }, +{ SCMP_SYS(setfsgid), 255 }, +}; + static const struct QemuSeccompSyscall obsolete[] = { { SCMP_SYS(readdir), 255 }, { SCMP_SYS(_sysctl), 255 }, @@ -110,6 +123,22 @@ int seccomp_start(uint8_t seccomp_opts) } } +if (seccomp_opts & PRIVILEGED) { +for (i = 0; i < ARRAY_SIZE(privileged_syscalls); i++) { +rc = seccomp_rule_add(ctx, SCMP_ACT_KILL, + privileged_syscalls[i].num, 0); +if (rc < 0) { +goto seccomp_return; +} +rc = seccomp_syscall_priority(ctx, privileged_syscalls[i].num, +privileged_syscalls[i].priority); +if (rc < 0) { +goto seccomp_return; +} +} +} + + rc = seccomp_load(ctx); seccomp_return: diff --git a/vl.c b/vl.c index cbe09c94af..800e2b573d 100644 --- a/vl.c +++ b/vl.c @@ -29,6 +29,7 @@ #ifdef CONFIG_SECCOMP #include "sysemu/seccomp.h" +#include "sys/prctl.h" #endif #if defined(CONFIG_VDE) @@ -275,6 +276,10 @@ static QemuOptsList qemu_sandbox_opts = { .name = "obsolete", .type = QEMU_OPT_STRING, }, +{ +.name = "elevateprivileges", +.type = QEMU_OPT_STRING, +}, { /* end of list */ } }, }; @@ -1046,6 +1051,23 @@ static int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp) } } +value = qemu_opt_get(opts, "elevateprivileges"); +if (value) { +if (strcmp(value, "deny") == 0) { +seccomp_opts |= PRIVILEGED; +} +if (strcmp(value, "children") == 0) { +seccomp_opts |= 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"); +} +} +} + if (seccomp_start(seccomp_opts) < 0) { error_report("failed to install seccomp syscall filter " "in the kernel"); -- 2.13.3
[Qemu-devel] [PATCH v3 6/6] seccomp: adding documentation to new seccomp model
Adding new documention under docs/ to describe every one and each new option added by the seccomp refactoring patchset. Signed-off-by: Eduardo Otubo --- docs/seccomp.txt | 31 +++ 1 file changed, 31 insertions(+) create mode 100644 docs/seccomp.txt diff --git a/docs/seccomp.txt b/docs/seccomp.txt new file mode 100644 index 00..4b7edba312 --- /dev/null +++ b/docs/seccomp.txt @@ -0,0 +1,31 @@ +QEMU Seccomp system call filter +=== + +Starting from Qemu version 2.10, the seccomp filter does not work as a +whitelist but as a blacklist instead. This method allows safer deploys since +only the strictly forbidden system calls will be black-listed and the +possibility of breaking any workload is close to zero. + +The default option (-sandbox on) has a slightly looser security though and the +reason is that it shouldn't break any backwards compatibility with previous +deploys and command lines already running. But if the intent is to have a +better security from this version on, one should make use of the following +additional options properly: + +* [,obsolete=allow]: It allows Qemu to run safely on old system that still + relies on old system calls. + +* [,elevateprivileges=deny|allow|children]: It allows or denies Qemu process + to elevate its privileges by blacklisting all set*uid|gid system calls. The + 'children' option sets the PR_SET_NO_NEW_PRIVS to 1 which allows helpers + (forls and execs) to run unprivileged. + +* [,spawn=deny]: It blacklists fork and execve syste calls, avoiding Qemu to + spawn new threads or processes. + +* [,resourcecontrol=deny]: It blacklists all process affinity and scheduler + priority system calls to avoid any bigger of the process. + + +-- +Eduardo Otubo -- 2.13.3
Re: [Qemu-devel] [PATCH] MAINTAINERS: seccomp: change email contact for Eduardo Otubo
On 06/12/2017 06:03 PM, Thomas Huth wrote: On 12.06.2017 14:18, Eduardo Otubo wrote: Signed-off-by: Eduardo Otubo --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 120788d..0d065a0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1490,7 +1490,7 @@ F: tests/vmstate-static-checker-data/ F: docs/migration.txt Seccomp -M: Eduardo Otubo +M: Eduardo Otubo S: Supported F: qemu-seccomp.c F: include/sysemu/seccomp.h Reviewed-by: Thomas Huth ping?
[Qemu-devel] [PULL 01/01] MAINTAINERS: seccomp: change email contact for Eduardo Otubo
Signed-off-by: Eduardo Otubo --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 120788d..0d065a0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1490,7 +1490,7 @@ F: tests/vmstate-static-checker-data/ F: docs/migration.txt Seccomp -M: Eduardo Otubo +M: Eduardo Otubo S: Supported F: qemu-seccomp.c F: include/sysemu/seccomp.h -- 2.9.4
[Qemu-devel] [PULL 00/01] seccomp branch queue
The following changes since commit 8dfaf23ae1f2273a9730a9b309cc8471269bb524: tcg/tci: fix tcg-interpreter build (2017-06-20 18:39:15 +0100) are available in the git repository at: https://github.com/otubo/qemu.git tags/pull-seccomp-20170622 for you to fetch changes up to 064983cb0a18c5adc4ec791c00792f74ebf50ca4: MAINTAINERS: seccomp: change email contact for Eduardo Otubo (2017-06-22 09:58:00 +0200) seccomp branch queue Eduardo Otubo (1): MAINTAINERS: seccomp: change email contact for Eduardo Otubo MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -- 2.9.4
Re: [Qemu-devel] [RFC PATCH 2/3] qemu-seccomp: manually expand SCMP_A1
On 10/08/2018 - 18:11:00, Alex Bennée wrote: > The expansion of ((struct scmp_arg_cmp){1, SCMP_CMP_NE, 5}) doesn't > work with -std=gnu99. > > Signed-off-by: Alex Bennée > --- > qemu-seccomp.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/qemu-seccomp.c b/qemu-seccomp.c > index 9cd8eb9499..4dc1c22924 100644 > --- a/qemu-seccomp.c > +++ b/qemu-seccomp.c > @@ -39,7 +39,7 @@ struct QemuSeccompSyscall { > }; > > const struct scmp_arg_cmp sched_setscheduler_arg[] = { > -SCMP_A1(SCMP_CMP_NE, SCHED_IDLE) > +{1, SCMP_CMP_NE, SCHED_IDLE} > }; > > static const struct QemuSeccompSyscall blacklist[] = { > -- > 2.17.1 > Acked-by: Eduardo Otubo signature.asc Description: PGP signature
Re: [Qemu-devel] [PATCH v3 0/3] seccomp fixes
On 22/08/2018 - 16:29:53, Marc-André Lureau wrote: > Hi, > > This series fixes 2 issues with -sandbox: > > - The seccomp action SCMP_ACT_KILL results in immediate termination of > the thread that made the bad system call. However, qemu being > multi-threaded, it keeps running. There is no easy way for parent > process / management layer (libvirt) to know about that situation. > > Instead, the default SIGSYS handler when invoked with SCMP_ACT_TRAP > will terminate the program and core dump. > > This may not be the most secure solution, but probably better than > just killing the offending thread. SCMP_ACT_KILL_PROCESS has been > added in Linux 4.14 to improve the situation, which I propose to use > by default if available. > > Related to: > https://bugzilla.redhat.com/show_bug.cgi?id=1594456 > > - The seccomp filter isn't applied to all threads. We can solve the > issue by using SECCOMP_FILTER_FLAG_TSYNC since libseccomp 2.2.0 and > kernel >= 3.17. The issue remains on older kernels or older > libseccomp. I chose to report an error by default, but we may want > it to fail instead. > > v3: > - modify qemu_seccomp() to set errno=ENOSYS > - add patch "seccomp: set the seccomp filter to all threads" > > v2: > - fix clang unused inline warning > - add acked-by/r-b tags > > Marc-André Lureau (3): > seccomp: use SIGSYS signal instead of killing the thread > seccomp: prefer SCMP_ACT_KILL_PROCESS if available > seccomp: set the seccomp filter to all threads > > qemu-seccomp.c | 96 +++++++-- > qemu-options.hx | 2 ++ > 2 files changed, 95 insertions(+), 3 deletions(-) > > -- > 2.18.0.547.g1d89318c48 > Acked-by: Eduardo Otubo signature.asc Description: PGP signature
[Qemu-devel] [PULL 3/3] seccomp: set the seccomp filter to all threads
From: Marc-André Lureau When using "-seccomp on", the seccomp policy is only applied to the main thread, the vcpu worker thread and other worker threads created after seccomp policy is applied; the seccomp policy is not applied to e.g. the RCU thread because it is created before the seccomp policy is applied and SECCOMP_FILTER_FLAG_TSYNC isn't used. This can be verified with for task in /proc/`pidof qemu`/task/*; do cat $task/status | grep Secc ; done Seccomp:2 Seccomp:0 Seccomp:0 Seccomp:2 Seccomp:2 Seccomp:2 Starting with libseccomp 2.2.0 and kernel >= 3.17, we can use seccomp_attr_set(ctx, > SCMP_FLTATR_CTL_TSYNC, 1) to update the policy on all threads. Do it by default if possible, warn if not possible. Add an option to set the tsync behaviour explicitly. Note: we can't bump libseccomp to 2.2.0 since it's not available in Debian oldstable (2.1.0). Signed-off-by: Marc-André Lureau Acked-by: Eduardo Otubo --- qemu-options.hx | 2 ++ qemu-seccomp.c | 65 +++-- 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/qemu-options.hx b/qemu-options.hx index 5515dfaba5..dafacb60c6 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -3864,6 +3864,8 @@ Disable set*uid|gid system calls Disable *fork and execve @item resourcecontrol=@var{string} Disable process affinity and schedular priority +@item tsync=@var{bool} +Apply seccomp filter to all threads (default is auto, and will warn if fail) @end table ETEXI diff --git a/qemu-seccomp.c b/qemu-seccomp.c index f0c833f3ca..aa23eae970 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -119,6 +119,45 @@ qemu_seccomp(unsigned int operation, unsigned int flags, void *args) #endif } +static bool qemu_seccomp_syscall_check(void) +{ +int rc; + +/* + * this is an invalid call because the second argument is non-zero, but + * depending on the errno value of ENOSYS or EINVAL we can guess if the + * seccomp() syscal is supported or not + */ +rc = qemu_seccomp(SECCOMP_SET_MODE_STRICT, 1, NULL); +if (rc < 0 && errno == EINVAL) { +return true; +} + +return false; +} + +static bool qemu_seccomp_get_default_tsync(void) +{ +bool tsync = true; + +/* TSYNC support was added with the syscall */ +if (!qemu_seccomp_syscall_check()) { +error_report("The host kernel doesn't support seccomp TSYNC!"); +tsync = false; +} + +#if !(SCMP_VER_MAJOR >= 2 && SCMP_VER_MINOR >= 2) +error_report("libseccomp is too old to support TSYNC!"); +tsync = false; +#endif + +if (!tsync) { +error_report("Only the main thread will be filtered by seccomp!"); +} + +return tsync; +} + static uint32_t qemu_seccomp_get_kill_action(void) { #if defined(SECCOMP_GET_ACTION_AVAIL) && defined(SCMP_ACT_KILL_PROCESS) && \ @@ -136,7 +175,7 @@ static uint32_t qemu_seccomp_get_kill_action(void) } -static int seccomp_start(uint32_t seccomp_opts) +static int seccomp_start(uint32_t seccomp_opts, bool tsync) { int rc = 0; unsigned int i = 0; @@ -149,6 +188,17 @@ static int seccomp_start(uint32_t seccomp_opts) goto seccomp_return; } +if (tsync) { +#if SCMP_VER_MAJOR >= 2 && SCMP_VER_MINOR >= 2 +rc = seccomp_attr_set(ctx, SCMP_FLTATR_CTL_TSYNC, 1); +#else +rc = -1; +#endif +if (rc != 0) { +goto seccomp_return; +} +} + for (i = 0; i < ARRAY_SIZE(blacklist); i++) { if (!(seccomp_opts & blacklist[i].set)) { continue; @@ -175,6 +225,13 @@ int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp) uint32_t seccomp_opts = QEMU_SECCOMP_SET_DEFAULT | QEMU_SECCOMP_SET_OBSOLETE; const char *value = NULL; +bool tsync; + +if (qemu_opt_get(opts, "tsync")) { +tsync = qemu_opt_get_bool(opts, "tsync", true); +} else { +tsync = qemu_seccomp_get_default_tsync(); +} value = qemu_opt_get(opts, "obsolete"); if (value) { @@ -236,7 +293,7 @@ int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp) } } -if (seccomp_start(seccomp_opts) < 0) { +if (seccomp_start(seccomp_opts, tsync) < 0) { error_report("failed to install seccomp syscall filter " "in the kernel"); return -1; @@ -271,6 +328,10 @@ static QemuOptsList qemu_sandbox_opts = { .name = "resourcecontrol", .type = QEMU_OPT_STRING, }, +{ +.name = "tsync", +.type = QEMU_OPT_BOOL, +}, { /* end of list */ } }, }; -- 2.17.1
[Qemu-devel] [PULL 1/3] seccomp: use SIGSYS signal instead of killing the thread
From: Marc-André Lureau The seccomp action SCMP_ACT_KILL results in immediate termination of the thread that made the bad system call. However, qemu being multi-threaded, it keeps running. There is no easy way for parent process / management layer (libvirt) to know about that situation. Instead, the default SIGSYS handler when invoked with SCMP_ACT_TRAP will terminate the program and core dump. This may not be the most secure solution, but probably better than just killing the offending thread. SCMP_ACT_KILL_PROCESS has been added in Linux 4.14 to improve the situation, which I propose to use by default if available in the next patch. Related to: https://bugzilla.redhat.com/show_bug.cgi?id=1594456 Signed-off-by: Marc-André Lureau Reviewed-by: Daniel P. Berrangé Acked-by: Eduardo Otubo --- qemu-seccomp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qemu-seccomp.c b/qemu-seccomp.c index 9cd8eb9499..b117a92559 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -125,7 +125,7 @@ static int seccomp_start(uint32_t seccomp_opts) continue; } -rc = seccomp_rule_add_array(ctx, SCMP_ACT_KILL, blacklist[i].num, +rc = seccomp_rule_add_array(ctx, SCMP_ACT_TRAP, blacklist[i].num, blacklist[i].narg, blacklist[i].arg_cmp); if (rc < 0) { goto seccomp_return; -- 2.17.1
[Qemu-devel] [PULL 0/3] seccomp branch queue
The following changes since commit 13b7b188501d419a7d63c016e00065bcc693b7d4: Merge remote-tracking branch 'remotes/kraxel/tags/vga-20180821-pull-request' into staging (2018-08-21 15:57:56 +0100) are available in the Git repository at: https://github.com/otubo/qemu.git tags/pull-seccomp-20180822 for you to fetch changes up to 2131f3e6e98195b4ce43a87c78cd9d8cb9f4da2c: seccomp: set the seccomp filter to all threads (2018-08-22 17:35:34 +0200) pull-seccomp-20180822 Marc-André Lureau (3): seccomp: use SIGSYS signal instead of killing the thread seccomp: prefer SCMP_ACT_KILL_PROCESS if available seccomp: set the seccomp filter to all threads qemu-options.hx | 2 ++ qemu-seccomp.c | 96 +++-- 2 files changed, 95 insertions(+), 3 deletions(-) -- 2.17.1
[Qemu-devel] [PULL 2/3] seccomp: prefer SCMP_ACT_KILL_PROCESS if available
From: Marc-André Lureau The upcoming libseccomp release should have SCMP_ACT_KILL_PROCESS action (https://github.com/seccomp/libseccomp/issues/96). SCMP_ACT_KILL_PROCESS is preferable to immediately terminate the offending process, rather than having the SIGSYS handler running. Use SECCOMP_GET_ACTION_AVAIL to check availability of kernel support, as libseccomp will fallback on SCMP_ACT_KILL otherwise, and we still prefer SCMP_ACT_TRAP. Signed-off-by: Marc-André Lureau Reviewed-by: Daniel P. Berrangé Acked-by: Eduardo Otubo --- qemu-seccomp.c | 31 ++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/qemu-seccomp.c b/qemu-seccomp.c index b117a92559..f0c833f3ca 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -20,6 +20,7 @@ #include #include #include "sysemu/seccomp.h" +#include /* For some architectures (notably ARM) cacheflush is not supported until * libseccomp 2.2.3, but configure enforces that we are using a more recent @@ -107,12 +108,40 @@ static const struct QemuSeccompSyscall blacklist[] = { { SCMP_SYS(sched_get_priority_min), QEMU_SECCOMP_SET_RESOURCECTL }, }; +static inline __attribute__((unused)) int +qemu_seccomp(unsigned int operation, unsigned int flags, void *args) +{ +#ifdef __NR_seccomp +return syscall(__NR_seccomp, operation, flags, args); +#else +errno = ENOSYS; +return -1; +#endif +} + +static uint32_t qemu_seccomp_get_kill_action(void) +{ +#if defined(SECCOMP_GET_ACTION_AVAIL) && defined(SCMP_ACT_KILL_PROCESS) && \ +defined(SECCOMP_RET_KILL_PROCESS) +{ +uint32_t action = SECCOMP_RET_KILL_PROCESS; + +if (qemu_seccomp(SECCOMP_GET_ACTION_AVAIL, 0, &action) == 0) { +return SCMP_ACT_KILL_PROCESS; +} +} +#endif + +return SCMP_ACT_TRAP; +} + static int seccomp_start(uint32_t seccomp_opts) { int rc = 0; unsigned int i = 0; scmp_filter_ctx ctx; +uint32_t action = qemu_seccomp_get_kill_action(); ctx = seccomp_init(SCMP_ACT_ALLOW); if (ctx == NULL) { @@ -125,7 +154,7 @@ static int seccomp_start(uint32_t seccomp_opts) continue; } -rc = seccomp_rule_add_array(ctx, SCMP_ACT_TRAP, blacklist[i].num, +rc = seccomp_rule_add_array(ctx, action, blacklist[i].num, blacklist[i].narg, blacklist[i].arg_cmp); if (rc < 0) { goto seccomp_return; -- 2.17.1
[Qemu-devel] [PULL 1/4] seccomp: use SIGSYS signal instead of killing the thread
From: Marc-André Lureau The seccomp action SCMP_ACT_KILL results in immediate termination of the thread that made the bad system call. However, qemu being multi-threaded, it keeps running. There is no easy way for parent process / management layer (libvirt) to know about that situation. Instead, the default SIGSYS handler when invoked with SCMP_ACT_TRAP will terminate the program and core dump. This may not be the most secure solution, but probably better than just killing the offending thread. SCMP_ACT_KILL_PROCESS has been added in Linux 4.14 to improve the situation, which I propose to use by default if available in the next patch. Related to: https://bugzilla.redhat.com/show_bug.cgi?id=1594456 Signed-off-by: Marc-André Lureau Reviewed-by: Daniel P. Berrangé Acked-by: Eduardo Otubo --- qemu-seccomp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qemu-seccomp.c b/qemu-seccomp.c index 9cd8eb9499..b117a92559 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -125,7 +125,7 @@ static int seccomp_start(uint32_t seccomp_opts) continue; } -rc = seccomp_rule_add_array(ctx, SCMP_ACT_KILL, blacklist[i].num, +rc = seccomp_rule_add_array(ctx, SCMP_ACT_TRAP, blacklist[i].num, blacklist[i].narg, blacklist[i].arg_cmp); if (rc < 0) { goto seccomp_return; -- 2.17.1
Re: [Qemu-devel] [PATCH v4 0/4] seccomp fixes
On 22/08/2018 - 19:02:46, Marc-André Lureau wrote: > Hi, > > This series fixes 2 issues with -sandbox: > > - The seccomp action SCMP_ACT_KILL results in immediate termination of > the thread that made the bad system call. However, qemu being > multi-threaded, it keeps running. There is no easy way for parent > process / management layer (libvirt) to know about that situation. > > Instead, the default SIGSYS handler when invoked with SCMP_ACT_TRAP > will terminate the program and core dump. > > This may not be the most secure solution, but probably better than > just killing the offending thread. SCMP_ACT_KILL_PROCESS has been > added in Linux 4.14 to improve the situation, which I propose to use > by default if available. > > Related to: > https://bugzilla.redhat.com/show_bug.cgi?id=1594456 > > - The seccomp filter isn't applied to all threads. We can solve the > issue by using SECCOMP_FILTER_FLAG_TSYNC since libseccomp 2.2.0 and > kernel >= 3.17. > > v3: > - modify qemu_seccomp() to set errno=ENOSYS > - add patch "seccomp: set the seccomp filter to all threads" > > v2: > - fix clang unused inline warning > - add acked-by/r-b tags > > Marc-André Lureau (4): > seccomp: use SIGSYS signal instead of killing the thread > seccomp: prefer SCMP_ACT_KILL_PROCESS if available > configure: require libseccomp 2.2.0 > seccomp: set the seccomp filter to all threads > > qemu-seccomp.c | 36 +++- > configure | 7 ++- > 2 files changed, 37 insertions(+), 6 deletions(-) > > -- > 2.18.0.547.g1d89318c48 > Acked-by: Eduardo Otubo signature.asc Description: PGP signature
[Qemu-devel] [PULL 2/4] seccomp: prefer SCMP_ACT_KILL_PROCESS if available
From: Marc-André Lureau The upcoming libseccomp release should have SCMP_ACT_KILL_PROCESS action (https://github.com/seccomp/libseccomp/issues/96). SCMP_ACT_KILL_PROCESS is preferable to immediately terminate the offending process, rather than having the SIGSYS handler running. Use SECCOMP_GET_ACTION_AVAIL to check availability of kernel support, as libseccomp will fallback on SCMP_ACT_KILL otherwise, and we still prefer SCMP_ACT_TRAP. Signed-off-by: Marc-André Lureau Reviewed-by: Daniel P. Berrangé Acked-by: Eduardo Otubo --- qemu-seccomp.c | 31 ++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/qemu-seccomp.c b/qemu-seccomp.c index b117a92559..f0c833f3ca 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -20,6 +20,7 @@ #include #include #include "sysemu/seccomp.h" +#include /* For some architectures (notably ARM) cacheflush is not supported until * libseccomp 2.2.3, but configure enforces that we are using a more recent @@ -107,12 +108,40 @@ static const struct QemuSeccompSyscall blacklist[] = { { SCMP_SYS(sched_get_priority_min), QEMU_SECCOMP_SET_RESOURCECTL }, }; +static inline __attribute__((unused)) int +qemu_seccomp(unsigned int operation, unsigned int flags, void *args) +{ +#ifdef __NR_seccomp +return syscall(__NR_seccomp, operation, flags, args); +#else +errno = ENOSYS; +return -1; +#endif +} + +static uint32_t qemu_seccomp_get_kill_action(void) +{ +#if defined(SECCOMP_GET_ACTION_AVAIL) && defined(SCMP_ACT_KILL_PROCESS) && \ +defined(SECCOMP_RET_KILL_PROCESS) +{ +uint32_t action = SECCOMP_RET_KILL_PROCESS; + +if (qemu_seccomp(SECCOMP_GET_ACTION_AVAIL, 0, &action) == 0) { +return SCMP_ACT_KILL_PROCESS; +} +} +#endif + +return SCMP_ACT_TRAP; +} + static int seccomp_start(uint32_t seccomp_opts) { int rc = 0; unsigned int i = 0; scmp_filter_ctx ctx; +uint32_t action = qemu_seccomp_get_kill_action(); ctx = seccomp_init(SCMP_ACT_ALLOW); if (ctx == NULL) { @@ -125,7 +154,7 @@ static int seccomp_start(uint32_t seccomp_opts) continue; } -rc = seccomp_rule_add_array(ctx, SCMP_ACT_TRAP, blacklist[i].num, +rc = seccomp_rule_add_array(ctx, action, blacklist[i].num, blacklist[i].narg, blacklist[i].arg_cmp); if (rc < 0) { goto seccomp_return; -- 2.17.1
[Qemu-devel] [PULL 4/4] seccomp: set the seccomp filter to all threads
From: Marc-André Lureau When using "-seccomp on", the seccomp policy is only applied to the main thread, the vcpu worker thread and other worker threads created after seccomp policy is applied; the seccomp policy is not applied to e.g. the RCU thread because it is created before the seccomp policy is applied and SECCOMP_FILTER_FLAG_TSYNC isn't used. This can be verified with for task in /proc/`pidof qemu`/task/*; do cat $task/status | grep Secc ; done Seccomp:2 Seccomp:0 Seccomp:0 Seccomp:2 Seccomp:2 Seccomp:2 Starting with libseccomp 2.2.0 and kernel >= 3.17, we can use seccomp_attr_set(ctx, > SCMP_FLTATR_CTL_TSYNC, 1) to update the policy on all threads. libseccomp requirement was bumped to 2.2.0 in previous patch. libseccomp should fail to set the filter if it can't honour SCMP_FLTATR_CTL_TSYNC (untested), and thus -sandbox will now fail on kernel < 3.17. Signed-off-by: Marc-André Lureau Acked-by: Eduardo Otubo --- qemu-seccomp.c | 5 + 1 file changed, 5 insertions(+) diff --git a/qemu-seccomp.c b/qemu-seccomp.c index f0c833f3ca..4729eb107f 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -149,6 +149,11 @@ static int seccomp_start(uint32_t seccomp_opts) goto seccomp_return; } +rc = seccomp_attr_set(ctx, SCMP_FLTATR_CTL_TSYNC, 1); +if (rc != 0) { +goto seccomp_return; +} + for (i = 0; i < ARRAY_SIZE(blacklist); i++) { if (!(seccomp_opts & blacklist[i].set)) { continue; -- 2.17.1
[Qemu-devel] [PULL 0/4] seccomp branch queue
The following changes since commit 3392fbee4e435658733bbe9aab23392660558b59: Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-3.1-pull-request' into staging (2018-08-23 12:28:17 +0100) are available in the Git repository at: https://github.com/otubo/qemu.git tags/pull-seccomp-20180823 for you to fetch changes up to 70dfabeaa79ba4d7a3b699abe1a047c8012db114: seccomp: set the seccomp filter to all threads (2018-08-23 16:45:44 +0200) pull-seccomp-20180823 Marc-André Lureau (4): seccomp: use SIGSYS signal instead of killing the thread seccomp: prefer SCMP_ACT_KILL_PROCESS if available configure: require libseccomp 2.2.0 seccomp: set the seccomp filter to all threads configure | 7 ++- qemu-seccomp.c | 36 +++- 2 files changed, 37 insertions(+), 6 deletions(-) -- 2.17.1
[Qemu-devel] [PULL 3/4] configure: require libseccomp 2.2.0
From: Marc-André Lureau The following patch is going to require TSYNC, which is only available since libseccomp 2.2.0. libseccomp 2.2.0 was released February 12, 2015. According to repology, libseccomp version in different distros: RHEL-7: 2.3.1 Debian (Stretch): 2.3.1 OpenSUSE Leap 15: 2.3.2 Ubuntu (Xenial): 2.3.1 This will drop support for -sandbox on: Debian (Jessie): 2.1.1 (but 2.2.3 in backports) Signed-off-by: Marc-André Lureau Acked-by: Eduardo Otubo --- configure | 7 ++- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/configure b/configure index e7bddc04b0..5fc2915096 100755 --- a/configure +++ b/configure @@ -2228,13 +2228,10 @@ fi ## # libseccomp check +libseccomp_minver="2.2.0" if test "$seccomp" != "no" ; then case "$cpu" in -i386|x86_64) -libseccomp_minver="2.1.0" -;; -mips) -libseccomp_minver="2.2.0" +i386|x86_64|mips) ;; arm|aarch64) libseccomp_minver="2.2.3" -- 2.17.1
Re: [Qemu-devel] [PATCH] seccomp: allow sched_setscheduler() with SCHED_IDLE policy
On 10/07/2018 - 16:55:57, Marc-André Lureau wrote: > Current and upcoming mesa releases rely on a shader disk cash. It uses > a thread job queue with low priority, set with > sched_setscheduler(SCHED_IDLE). However, that syscall is rejected by > the "resourcecontrol" seccomp qemu filter. > > Since it should be safe to allow lowering thread priority, let's allow > scheduling thread to idle policy. > > Related to: > https://bugzilla.redhat.com/show_bug.cgi?id=1594456 > > Signed-off-by: Marc-André Lureau > --- > qemu-seccomp.c | 12 ++-- > 1 file changed, 10 insertions(+), 2 deletions(-) > > diff --git a/qemu-seccomp.c b/qemu-seccomp.c > index 148e4c6f24..9cd8eb9499 100644 > --- a/qemu-seccomp.c > +++ b/qemu-seccomp.c > @@ -34,6 +34,12 @@ > struct QemuSeccompSyscall { > int32_t num; > uint8_t set; > +uint8_t narg; > +const struct scmp_arg_cmp *arg_cmp; > +}; > + > +const struct scmp_arg_cmp sched_setscheduler_arg[] = { > +SCMP_A1(SCMP_CMP_NE, SCHED_IDLE) > }; > > static const struct QemuSeccompSyscall blacklist[] = { > @@ -92,7 +98,8 @@ static const struct QemuSeccompSyscall blacklist[] = { > { SCMP_SYS(setpriority),QEMU_SECCOMP_SET_RESOURCECTL }, > { SCMP_SYS(sched_setparam), QEMU_SECCOMP_SET_RESOURCECTL }, > { SCMP_SYS(sched_getparam), QEMU_SECCOMP_SET_RESOURCECTL }, > -{ SCMP_SYS(sched_setscheduler), QEMU_SECCOMP_SET_RESOURCECTL }, > +{ SCMP_SYS(sched_setscheduler), QEMU_SECCOMP_SET_RESOURCECTL, > + ARRAY_SIZE(sched_setscheduler_arg), sched_setscheduler_arg }, > { SCMP_SYS(sched_getscheduler), QEMU_SECCOMP_SET_RESOURCECTL }, > { SCMP_SYS(sched_setaffinity), QEMU_SECCOMP_SET_RESOURCECTL }, > { SCMP_SYS(sched_getaffinity), QEMU_SECCOMP_SET_RESOURCECTL }, > @@ -118,7 +125,8 @@ static int seccomp_start(uint32_t seccomp_opts) > continue; > } > > -rc = seccomp_rule_add(ctx, SCMP_ACT_KILL, blacklist[i].num, 0); > +rc = seccomp_rule_add_array(ctx, SCMP_ACT_KILL, blacklist[i].num, > +blacklist[i].narg, blacklist[i].arg_cmp); > if (rc < 0) { > goto seccomp_return; > } > -- > 2.18.0.129.ge3331758f1 > Acked-by: Eduardo Otubo Patch looks safe enough for me. If everyone else is OK with this I'll send a pull-request tomorrow morning. signature.asc Description: PGP signature
[Qemu-devel] [PULL 0/1] seccomp branch queue
The following changes since commit c447afd5783b9237fa51b7a85777007d8d568bfc: Update version for v3.0.0-rc0 release (2018-07-10 18:19:50 +0100) are available in the Git repository at: https://github.com/otubo/qemu.git tags/pull-seccomp-20180712 for you to fetch changes up to 056de1e894155fbb99e7b43c1c4382d4920cf437: seccomp: allow sched_setscheduler() with SCHED_IDLE policy (2018-07-12 14:52:39 +0200) pull-seccomp-20180712 Marc-André Lureau (1): seccomp: allow sched_setscheduler() with SCHED_IDLE policy qemu-seccomp.c | 12 ++-- 1 file changed, 10 insertions(+), 2 deletions(-) -- 2.17.1
[Qemu-devel] [PULL 1/1] seccomp: allow sched_setscheduler() with SCHED_IDLE policy
From: Marc-André Lureau Current and upcoming mesa releases rely on a shader disk cash. It uses a thread job queue with low priority, set with sched_setscheduler(SCHED_IDLE). However, that syscall is rejected by the "resourcecontrol" seccomp qemu filter. Since it should be safe to allow lowering thread priority, let's allow scheduling thread to idle policy. Related to: https://bugzilla.redhat.com/show_bug.cgi?id=1594456 Signed-off-by: Marc-André Lureau Acked-by: Eduardo Otubo --- qemu-seccomp.c | 12 ++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/qemu-seccomp.c b/qemu-seccomp.c index 148e4c6f24..9cd8eb9499 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -34,6 +34,12 @@ struct QemuSeccompSyscall { int32_t num; uint8_t set; +uint8_t narg; +const struct scmp_arg_cmp *arg_cmp; +}; + +const struct scmp_arg_cmp sched_setscheduler_arg[] = { +SCMP_A1(SCMP_CMP_NE, SCHED_IDLE) }; static const struct QemuSeccompSyscall blacklist[] = { @@ -92,7 +98,8 @@ static const struct QemuSeccompSyscall blacklist[] = { { SCMP_SYS(setpriority),QEMU_SECCOMP_SET_RESOURCECTL }, { SCMP_SYS(sched_setparam), QEMU_SECCOMP_SET_RESOURCECTL }, { SCMP_SYS(sched_getparam), QEMU_SECCOMP_SET_RESOURCECTL }, -{ SCMP_SYS(sched_setscheduler), QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(sched_setscheduler), QEMU_SECCOMP_SET_RESOURCECTL, + ARRAY_SIZE(sched_setscheduler_arg), sched_setscheduler_arg }, { SCMP_SYS(sched_getscheduler), QEMU_SECCOMP_SET_RESOURCECTL }, { SCMP_SYS(sched_setaffinity), QEMU_SECCOMP_SET_RESOURCECTL }, { SCMP_SYS(sched_getaffinity), QEMU_SECCOMP_SET_RESOURCECTL }, @@ -118,7 +125,8 @@ static int seccomp_start(uint32_t seccomp_opts) continue; } -rc = seccomp_rule_add(ctx, SCMP_ACT_KILL, blacklist[i].num, 0); +rc = seccomp_rule_add_array(ctx, SCMP_ACT_KILL, blacklist[i].num, +blacklist[i].narg, blacklist[i].arg_cmp); if (rc < 0) { goto seccomp_return; } -- 2.17.1
Re: [Qemu-devel] [PATCH 1/2] seccomp: use SIGSYS signal instead of killing the thread
On 20/07/2018 - 17:00:39, Daniel P. Berrange wrote: > On Fri, Jul 20, 2018 at 05:44:24PM +0200, Marc-André Lureau wrote: > > The seccomp action SCMP_ACT_KILL results in immediate termination of > > the thread that made the bad system call. However, qemu being > > multi-threaded, it keeps running. There is no easy way for parent > > process / management layer (libvirt) to know about that situation. > > > > Instead, the default SIGSYS handler when invoked with SCMP_ACT_TRAP > > will terminate the program and core dump. > > > > This may not be the most secure solution, but probably better than > > just killing the offending thread. SCMP_ACT_KILL_PROCESS has been > > added in Linux 4.14 to improve the situation, which I propose to use > > by default if available in the next patch. > > Note that seccomp doesn't promise to protect against all types > of vulnerability in a program. It merely aims to stop the program > executing designated system calls. > > Using SCMP_ACT_TRAP still prevents syscal execution to exactly the > same extent that SCMP_ACT_KILL does, so its security level is the > same. > > What differs is that the userspace app has option to ignore the > syscall and carry on instead of being killed. A malicous attacker > would thus have option to try to influence other parts of QEMU > todo bad stuff, but if they already have control over the userspace > process to this extent, they can likely do such bad stuff even > before executing the syscalls > > So I don't think there's any significant difference in security > protection here. Mostly the difference is just about what the > crash will look like. A full process crash (from the default > signal handler) looks better than a thread crash for the reasons > you've explained. I guess that's the whole point of having the process killed instead of the thread. Seccomp is not a big security feature alone by itself, but rather combined with others techniques. Marc, from what we've already discussed I think these patches are good enough for now. Thanks a lot for the contribution. > > > > > Related to: > > https://bugzilla.redhat.com/show_bug.cgi?id=1594456 > > > > Signed-off-by: Marc-André Lureau > > --- > > qemu-seccomp.c | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > diff --git a/qemu-seccomp.c b/qemu-seccomp.c > > index 9cd8eb9499..b117a92559 100644 > > --- a/qemu-seccomp.c > > +++ b/qemu-seccomp.c > > @@ -125,7 +125,7 @@ static int seccomp_start(uint32_t seccomp_opts) > > continue; > > } > > > > -rc = seccomp_rule_add_array(ctx, SCMP_ACT_KILL, blacklist[i].num, > > + rc = seccomp_rule_add_array(ctx, SCMP_ACT_TRAP, blacklist[i].num, > > blacklist[i].narg, > > blacklist[i].arg_cmp); > > if (rc < 0) { > > goto seccomp_return; > > Reviewed-by: Daniel P. Berrangé > Acked-by: Eduardo Otubo signature.asc Description: PGP signature
Re: [Qemu-devel] [PATCH 2/2] RFC: seccomp: prefer SCMP_ACT_KILL_PROCESS if available
On 20/07/2018 - 17:44:25, Marc-André Lureau wrote: > The upcoming libseccomp release should have SCMP_ACT_KILL_PROCESS > action (https://github.com/seccomp/libseccomp/issues/96). > > SCMP_ACT_KILL_PROCESS is preferable to immediately terminate the > offending process, rather than having the SIGSYS handler running. > > Use SECCOMP_GET_ACTION_AVAIL to check availability of kernel support, > as libseccomp will fallback on SCMP_ACT_KILL otherwise, and we still > prefer SCMP_ACT_TRAP. > > Signed-off-by: Marc-André Lureau > --- > qemu-seccomp.c | 30 +- > 1 file changed, 29 insertions(+), 1 deletion(-) > > diff --git a/qemu-seccomp.c b/qemu-seccomp.c > index b117a92559..505887d5af 100644 > --- a/qemu-seccomp.c > +++ b/qemu-seccomp.c > @@ -20,6 +20,7 @@ > #include > #include > #include "sysemu/seccomp.h" > +#include > > /* For some architectures (notably ARM) cacheflush is not supported until > * libseccomp 2.2.3, but configure enforces that we are using a more recent > @@ -107,12 +108,39 @@ static const struct QemuSeccompSyscall blacklist[] = { > { SCMP_SYS(sched_get_priority_min), QEMU_SECCOMP_SET_RESOURCECTL }, > }; > > +static inline int > +qemu_seccomp(unsigned int operation, unsigned int flags, void *args) > +{ > +#ifdef __NR_seccomp > +return syscall(__NR_seccomp, operation, flags, args); > +#else > +return -1; > +#endif > +} > + > +static uint32_t qemu_seccomp_get_kill_action(void) > +{ > +#if defined(SECCOMP_GET_ACTION_AVAIL) && defined(SCMP_ACT_KILL_PROCESS) && \ > +defined(SECCOMP_RET_KILL_PROCESS) > +{ > +uint32_t action = SECCOMP_RET_KILL_PROCESS; > + > +if (qemu_seccomp(SECCOMP_GET_ACTION_AVAIL, 0, &action) == 0) { > +return SCMP_ACT_KILL_PROCESS; > +} > +} > +#endif > + > +return SCMP_ACT_TRAP; > +} > + > > static int seccomp_start(uint32_t seccomp_opts) > { > int rc = 0; > unsigned int i = 0; > scmp_filter_ctx ctx; > +uint32_t action = qemu_seccomp_get_kill_action(); > > ctx = seccomp_init(SCMP_ACT_ALLOW); > if (ctx == NULL) { > @@ -125,7 +153,7 @@ static int seccomp_start(uint32_t seccomp_opts) > continue; > } > > -rc = seccomp_rule_add_array(ctx, SCMP_ACT_TRAP, blacklist[i].num, > + rc = seccomp_rule_add_array(ctx, action, blacklist[i].num, > blacklist[i].narg, blacklist[i].arg_cmp); > if (rc < 0) { > goto seccomp_return; > -- > 2.18.0.232.gb7bd9486b0 > Acked-by: Eduardo Otubo -- Eduardo Otubo signature.asc Description: PGP signature
[Qemu-devel] [PULL 1/2] seccomp: use SIGSYS signal instead of killing the thread
From: Marc-André Lureau The seccomp action SCMP_ACT_KILL results in immediate termination of the thread that made the bad system call. However, qemu being multi-threaded, it keeps running. There is no easy way for parent process / management layer (libvirt) to know about that situation. Instead, the default SIGSYS handler when invoked with SCMP_ACT_TRAP will terminate the program and core dump. This may not be the most secure solution, but probably better than just killing the offending thread. SCMP_ACT_KILL_PROCESS has been added in Linux 4.14 to improve the situation, which I propose to use by default if available in the next patch. Related to: https://bugzilla.redhat.com/show_bug.cgi?id=1594456 Signed-off-by: Marc-André Lureau Acked-by: Eduardo Otubo --- qemu-seccomp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qemu-seccomp.c b/qemu-seccomp.c index 9cd8eb9499..b117a92559 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -125,7 +125,7 @@ static int seccomp_start(uint32_t seccomp_opts) continue; } -rc = seccomp_rule_add_array(ctx, SCMP_ACT_KILL, blacklist[i].num, +rc = seccomp_rule_add_array(ctx, SCMP_ACT_TRAP, blacklist[i].num, blacklist[i].narg, blacklist[i].arg_cmp); if (rc < 0) { goto seccomp_return; -- 2.17.1
[Qemu-devel] [PULL 0/2] seccomp branch queue
The following changes since commit 18a398f6a39df4b08ff86ac0d38384193ca5f4cc: Update version for v3.0.0-rc2 release (2018-07-24 22:06:31 +0100) are available in the Git repository at: https://github.com/otubo/qemu.git tags/pull-seccomp-20180725 for you to fetch changes up to 5b2f59307372bae13a2ff95706646674eccb65e0: RFC: seccomp: prefer SCMP_ACT_KILL_PROCESS if available (2018-07-25 16:07:31 +0200) pull-seccomp-20180725 Marc-André Lureau (2): seccomp: use SIGSYS signal instead of killing the thread RFC: seccomp: prefer SCMP_ACT_KILL_PROCESS if available qemu-seccomp.c | 30 +- 1 file changed, 29 insertions(+), 1 deletion(-) -- 2.17.1
[Qemu-devel] [PULL 2/2] RFC: seccomp: prefer SCMP_ACT_KILL_PROCESS if available
From: Marc-André Lureau The upcoming libseccomp release should have SCMP_ACT_KILL_PROCESS action (https://github.com/seccomp/libseccomp/issues/96). SCMP_ACT_KILL_PROCESS is preferable to immediately terminate the offending process, rather than having the SIGSYS handler running. Use SECCOMP_GET_ACTION_AVAIL to check availability of kernel support, as libseccomp will fallback on SCMP_ACT_KILL otherwise, and we still prefer SCMP_ACT_TRAP. Signed-off-by: Marc-André Lureau Acked-by: Eduardo Otubo --- qemu-seccomp.c | 30 +- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/qemu-seccomp.c b/qemu-seccomp.c index b117a92559..505887d5af 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -20,6 +20,7 @@ #include #include #include "sysemu/seccomp.h" +#include /* For some architectures (notably ARM) cacheflush is not supported until * libseccomp 2.2.3, but configure enforces that we are using a more recent @@ -107,12 +108,39 @@ static const struct QemuSeccompSyscall blacklist[] = { { SCMP_SYS(sched_get_priority_min), QEMU_SECCOMP_SET_RESOURCECTL }, }; +static inline int +qemu_seccomp(unsigned int operation, unsigned int flags, void *args) +{ +#ifdef __NR_seccomp +return syscall(__NR_seccomp, operation, flags, args); +#else +return -1; +#endif +} + +static uint32_t qemu_seccomp_get_kill_action(void) +{ +#if defined(SECCOMP_GET_ACTION_AVAIL) && defined(SCMP_ACT_KILL_PROCESS) && \ +defined(SECCOMP_RET_KILL_PROCESS) +{ +uint32_t action = SECCOMP_RET_KILL_PROCESS; + +if (qemu_seccomp(SECCOMP_GET_ACTION_AVAIL, 0, &action) == 0) { +return SCMP_ACT_KILL_PROCESS; +} +} +#endif + +return SCMP_ACT_TRAP; +} + static int seccomp_start(uint32_t seccomp_opts) { int rc = 0; unsigned int i = 0; scmp_filter_ctx ctx; +uint32_t action = qemu_seccomp_get_kill_action(); ctx = seccomp_init(SCMP_ACT_ALLOW); if (ctx == NULL) { @@ -125,7 +153,7 @@ static int seccomp_start(uint32_t seccomp_opts) continue; } -rc = seccomp_rule_add_array(ctx, SCMP_ACT_TRAP, blacklist[i].num, +rc = seccomp_rule_add_array(ctx, action, blacklist[i].num, blacklist[i].narg, blacklist[i].arg_cmp); if (rc < 0) { goto seccomp_return; -- 2.17.1
Re: [Qemu-devel] [PULL 0/2] seccomp branch queue
On 26/07/2018 - 11:47:46, Peter Maydell wrote: > On 25 July 2018 at 15:16, Eduardo Otubo wrote: > > The following changes since commit 18a398f6a39df4b08ff86ac0d38384193ca5f4cc: > > > > Update version for v3.0.0-rc2 release (2018-07-24 22:06:31 +0100) > > > > are available in the Git repository at: > > > > https://github.com/otubo/qemu.git tags/pull-seccomp-20180725 > > > > for you to fetch changes up to 5b2f59307372bae13a2ff95706646674eccb65e0: > > > > RFC: seccomp: prefer SCMP_ACT_KILL_PROCESS if available (2018-07-25 > > 16:07:31 +0200) > > > > > > pull-seccomp-20180725 > > > > > > Marc-André Lureau (2): > > seccomp: use SIGSYS signal instead of killing the thread > > RFC: seccomp: prefer SCMP_ACT_KILL_PROCESS if available > > Hi. This fails to compile with clang: > > CC qemu-seccomp.o > qemu-seccomp.c:112:1: error: unused function 'qemu_seccomp' > [-Werror,-Wunused-function] > qemu_seccomp(unsigned int operation, unsigned int flags, void *args) > ^ > > This is because clang is stricter about warning about static inline > functions defined in .c files but never used and your ifdef > guard on the callsite is not matched by one around the function > definition. > Peter, sorry for not catching that before. Marc, can you fix and resend? -- Eduardo Otubo signature.asc Description: PGP signature
Re: [Qemu-devel] [PATCH 16/31] seccomp: Clean up error reporting in parse_sandbox()
On 08/10/2018 - 19:31:10, Markus Armbruster wrote: > Calling error_report() in a function that takes an Error ** argument > is suspicious. parse_sandbox() does that, and then fails without > setting an error. Its caller main(), via qemu_opts_foreach(), is fine > with it, but clean it up anyway. > > Cc: Eduardo Otubo > Signed-off-by: Markus Armbruster > --- > qemu-seccomp.c | 18 +- > vl.c | 4 ++-- > 2 files changed, 11 insertions(+), 11 deletions(-) > > diff --git a/qemu-seccomp.c b/qemu-seccomp.c > index 1baa5c69ed..6d27699409 100644 > --- a/qemu-seccomp.c > +++ b/qemu-seccomp.c > @@ -12,11 +12,12 @@ > * Contributions after 2012-01-13 are licensed under the terms of the > * GNU GPL, version 2 or (at your option) any later version. > */ > + > #include "qemu/osdep.h" > +#include "qapi/error.h" > #include "qemu/config-file.h" > #include "qemu/option.h" > #include "qemu/module.h" > -#include "qemu/error-report.h" > #include > #include > #include "sysemu/seccomp.h" > @@ -190,7 +191,7 @@ int parse_sandbox(void *opaque, QemuOpts *opts, Error > **errp) > * to provide a little bit of consistency for > * the command line */ > } else { > -error_report("invalid argument for obsolete"); > +error_setg(errp, "invalid argument for obsolete"); > return -1; > } > } > @@ -205,14 +206,13 @@ int parse_sandbox(void *opaque, QemuOpts *opts, Error > **errp) > /* 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"); > +error_setg(errp, "failed to set no_new_privs " > "aborting"); > return -1; Except for this " " all else is good. Acked-by: Eduardo Otubo > } > } else if (g_str_equal(value, "allow")) { > /* default value */ > } else { > -error_report("invalid argument for elevateprivileges"); > +error_setg(errp, "invalid argument for elevateprivileges"); > return -1; > } > } > @@ -224,7 +224,7 @@ int parse_sandbox(void *opaque, QemuOpts *opts, Error > **errp) > } else if (g_str_equal(value, "allow")) { > /* default value */ > } else { > -error_report("invalid argument for spawn"); > +error_setg(errp, "invalid argument for spawn"); > return -1; > } > } > @@ -236,14 +236,14 @@ int parse_sandbox(void *opaque, QemuOpts *opts, Error > **errp) > } else if (g_str_equal(value, "allow")) { > /* default value */ > } else { > -error_report("invalid argument for resourcecontrol"); > +error_setg(errp, "invalid argument for resourcecontrol"); > return -1; > } > } > > if (seccomp_start(seccomp_opts) < 0) { > -error_report("failed to install seccomp syscall filter " > - "in the kernel"); > +error_setg(errp, "failed to install seccomp syscall filter " > + "in the kernel"); > return -1; > } > } > diff --git a/vl.c b/vl.c > index 9d2b38a31f..485c3fc008 100644 > --- a/vl.c > +++ b/vl.c > @@ -3925,8 +3925,8 @@ int main(int argc, char **argv, char **envp) > > #ifdef CONFIG_SECCOMP > olist = qemu_find_opts_err("sandbox", NULL); > -if (olist && qemu_opts_foreach(olist, parse_sandbox, NULL, NULL)) { > -exit(1); > +if (olist) { > +qemu_opts_foreach(olist, parse_sandbox, NULL, &error_fatal); > } > #endif > > -- > 2.17.1 > -- Eduardo Otubo signature.asc Description: PGP signature
Re: [Qemu-devel] [PATCH v4 00/16] pc: add CPU hot-add/hot-remove with device_add/device_del
On Tue, Jul 19, 2016 at 12=59=36AM +0300, Michael S. Tsirkin wrote: > On Thu, Jul 14, 2016 at 06:54:29PM +0200, Igor Mammedov wrote: > > Changelog: > > So for pc and apic bits: > > Reviewed-by: Michael S. Tsirkin > > Since Eduardo picked up first part of this, feel free > to merge the rest too. Hi Igor, I was a little curios about the state of this feature. Is this going to make it to 2.7? Best regards, > > > > > since v3: > > * rebase on top of x86-next tree as it's already applied 1-6/19 from v3 > > (so they are could be omitted from v4) > > * set apic-state to NULL after destroying it in unrealize() > > * fix places where I forgot to print X86CPUTopoInfo fields as %u > > * move "pc: implement query-hotpluggable-cpus callback" after > > patch that enables device_add cpu > > * extract counting of present cpus in possible_cpus into a separate > > helper > > * newly added patches: > > * pc: forbid BSP removal > > * pc: enforce adding CPUs contiguously and removing them in opposit > > order > > * apic: kvm-apic: fix crash due to access to freed memory region > > * update Reviewed-bys > > since v2: > > * use 0x for UNASSIGNED_APIC_ID instead of UINT32_MAX > > * add comment why 0x could be used for UNASSIGNED_APIC_ID > > * print topo ids is unsigned > > * print APIC ID as hex > > * print topo ids calculated from APIC ID beside it > > * add extra patch to fix migration failure due to APIC's instance_id > > mismatch > > since v1: > > * s/pc_find_cpu/pc_find_cpu_slot/ + add comment to it > > * add more sanity checks for socket-id/core-id/thread-id and 'apic' > > properties > > * include device_del cpu patches and related fixes to x86 CPU/apic > > > > Series enabling usage of -device/device_add for adding CPUs as devices > > and device_del for removing them. Using -device/device_add in combination > > with query-hotpluggable-cpus QMP command allows to hotplug CPUs at any > > not used possition and then safely migrate QEMU instance by specifying > > hotadded CPUs on target with help of -device CLI option like with any > > other device. > > Having been able to replicate exact topology on taggert with -device CPUs > > also opens poosibility to hot-remove CPUs, which this series does by > > enabling to use device_del with x86 CPUs. > > > > > > git tree for testing: > > https://github.com/imammedo/qemu.git dev_del_cpu_v4 > > for viewing: > > https://github.com/imammedo/qemu/commits/dev_del_cpu_v4 > > > > Tested with RHEL7.2 guest including ping/pong migration with adding/removing > > CPUs in between. > > > > CC: pkre...@redhat.com > > CC: ehabk...@redhat.com > > CC: m...@redhat.com > > CC: eduardo.ot...@profitbricks.com > > CC: Bandan Das > > > > Igor Mammedov (16): > > pc: set APIC ID based on socket/core/thread ids if it's not been set > > yet > > pc: delay setting number of boot CPUs to machine_done time > > pc: register created initial and hotpluged CPUs in one place > > pc_cpu_plug() > > pc: forbid BSP removal > > pc: enforce adding CPUs contiguously and removing them in opposit > > order > > pc: cpu: allow device_add to be used with x86 cpu > > pc: implement query-hotpluggable-cpus callback > > apic: move MAX_APICS check to 'apic' class > > apic: drop APICCommonState.idx and use APIC ID as index in > > local_apics[] > > apic: kvm-apic: fix crash due to access to freed memory region > > (kvm)apic: add unrealize callbacks > > apic: use apic_id as apic's migration instance_id > > target-i386: cpu: do not ignore error and fix apic parent > > target-i386: fix apic object leak when CPU is deleted > > target-i386: add x86_cpu_unrealizefn() > > pc: make device_del CPU work for x86 CPUs > > > > include/hw/i386/apic_internal.h | 5 +- > > include/hw/i386/pc.h| 5 ++ > > hw/i386/kvm/apic.c | 9 +- > > hw/i386/pc.c| 183 > > ++-- > > hw/intc/apic.c | 26 +- > > hw/intc/apic_common.c | 33 ++-- > > qmp-commands.hx | 15 > > target-i386/cpu.c | 23 - > > 8 files changed, 251 insertions(+), 48 deletions(-) > > > > -- > > 2.7.4 -- Eduardo Otubo ProfitBricks GmbH signature.asc Description: PGP signature
Re: [Qemu-devel] [PATCH] seccomp: Add support for ppc/ppc64
On Wed, Jun 01, 2016 at 06=30=18PM -0500, Michael Strosaker wrote: > Support for ppc/ppc64 is official in libseccomp 2.3.0, so modify the > configuration script to allow qemuu to enable seccomp for those platforms. > > Signed-off-by: Michael Strosaker > --- > configure | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/configure b/configure > index b5aab72..79b571d 100755 > --- a/configure > +++ b/configure > @@ -1879,6 +1879,9 @@ if test "$seccomp" != "no" ; then > arm|aarch64) > libseccomp_minver="2.2.3" > ;; > +ppc|ppc64) > +libseccomp_minver="2.3.0" > + ;; > *) > libseccomp_minver="" > ;; > -- > 1.8.3.1 > Acked-by: Eduardo Otubo Patch looks good. I'll send a pull request shortly. Thanks for the contribution. -- Eduardo Otubo ProfitBricks GmbH signature.asc Description: Digital signature
[Qemu-devel] [PULL 00/01] seccomp branch queue
The following changes since commit 482b61844ae7c6df39df0b48ac90ffbc87bed7d2: Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20160617' into staging (2016-06-17 16:16:37 +0100) are available in the git repository at: git://github.com/otubo/qemu.git tags/pull-seccomp-20160620 for you to fetch changes up to 3e684455032a748be261e5a2524147940af9b6d9: seccomp: Add support for ppc/ppc64 (2016-06-20 11:04:09 +0200) seccomp branch queue Michael Strosaker (1): seccomp: Add support for ppc/ppc64 configure | 3 +++ 1 file changed, 3 insertions(+) -- 2.1.4
[Qemu-devel] [PULL 01/01] seccomp: Add support for ppc/ppc64
From: Michael Strosaker Support for ppc/ppc64 is official in libseccomp 2.3.0, so modify the configuration script to allow qemuu to enable seccomp for those platforms. Signed-off-by: Michael Strosaker Acked-by: Eduardo Otubo --- configure | 3 +++ 1 file changed, 3 insertions(+) diff --git a/configure b/configure index 10cb212..5929aba 100755 --- a/configure +++ b/configure @@ -1884,6 +1884,9 @@ if test "$seccomp" != "no" ; then arm|aarch64) libseccomp_minver="2.2.3" ;; +ppc|ppc64) +libseccomp_minver="2.3.0" +;; *) libseccomp_minver="" ;; -- 2.1.4
Re: [Qemu-devel] [PATCH v3 0/7] cpu: add i386 cpu hot remove support
On Mon, Jul 13, 2015 at 09=45=57AM +0800, Zhu Guihua wrote: > > On 07/09/2015 10:25 PM, Eduardo Otubo wrote: > >On Fri, Jun 26, 2015 at 11=37=43AM +0800, Zhu Guihua wrote: > >>Hi, > >>On 06/24/2015 09:28 PM, Eduardo Otubo wrote: > >>>Hello Zhu, > >>> > >>>Are you still working on this feature? Could you provide a rebased > >>>version of this series? > >>Sorry for late reply. > >> > >>Yes, we are still working on this feature. > >> > >>I have updated my github, you can get the rebased version from it. > >> > >>https://github.com/zhuguihua/qemu.git cpu-hotplug > >Hi, thanks a lot for rebasing it. I didn't have time to test it, though. > >I appologise. > > > >Regarding your branch, your plan is to stick with device_del and > >object_del interface? > > Yeah, we will only stick with device_del interface. > There is no need to use object_del interface for cpu hot remove. > > Thanks, > Zhu > This is almost a year old email, but I decided to git it a try anyway. Are you still working on this? I'm trying your patches and it seems I had a simple issue: EJ0 is sent, guest ack's and removes the CPU, but it get's stuck somewhere between the BIOS and Qemu. CPU is successfully removed from the guest, but it still appears on QOM: (qemu) info cpus * CPU #0: pc=0x8104f596 (halted) thread_id=22208 CPU #1: pc=0x8104f596 (halted) thread_id=22209 CPU #2: pc=0x810429c8 (halted) thread_id=22281 (qemu) info qom-tree /machine (pc-i440fx-2.1-machine) /fw_cfg (fw_cfg_io) /fwcfg[0] (qemu:memory-region) [...] /cpu3 (SandyBridge-x86_64-cpu) [...] Do you have any clues? -- Eduardo Otubo ProfitBricks GmbH signature.asc Description: Digital signature
Re: [Qemu-devel] [PATCH v3 0/7] cpu: add i386 cpu hot remove support
On Wed, Jun 22, 2016 at 03=24=14PM +0200, Igor Mammedov wrote: > On Wed, 22 Jun 2016 14:12:49 +0200 > Eduardo Otubo wrote: > > > On Mon, Jul 13, 2015 at 09=45=57AM +0800, Zhu Guihua wrote: > > > > > > On 07/09/2015 10:25 PM, Eduardo Otubo wrote: > > > >On Fri, Jun 26, 2015 at 11=37=43AM +0800, Zhu Guihua wrote: > > > >>Hi, > > > >>On 06/24/2015 09:28 PM, Eduardo Otubo wrote: > > > >>>Hello Zhu, > > > >>> > > > >>>Are you still working on this feature? Could you provide a > > > >>>rebased version of this series? > > > >>Sorry for late reply. > > > >> > > > >>Yes, we are still working on this feature. > > > >> > > > >>I have updated my github, you can get the rebased version from it. > > > >> > > > >>https://github.com/zhuguihua/qemu.git cpu-hotplug > > > >Hi, thanks a lot for rebasing it. I didn't have time to test it, > > > >though. I appologise. > > > > > > > >Regarding your branch, your plan is to stick with device_del and > > > >object_del interface? > > > > > > Yeah, we will only stick with device_del interface. > > > There is no need to use object_del interface for cpu hot remove. > > > > > > Thanks, > > > Zhu > > > > > > > This is almost a year old email, but I decided to git it a try anyway. > > Are you still working on this? I'm trying your patches and it seems I > > had a simple issue: EJ0 is sent, guest ack's and removes the CPU, but > > it get's stuck somewhere between the BIOS and Qemu. CPU is > > successfully removed from the guest, but it still appears on QOM: > I'm working on new version and I plan to post patches this week. > I saw your RFCs. Will your new patches include QMP/HMP interface? Looking forward to test. regards, -- Eduardo Otubo ProfitBricks GmbH signature.asc Description: Digital signature
Re: [Qemu-devel] [PATCHv6 0/6] seccomp: feature refactoring
On Fri, Sep 08, 2017 at 01:44:02PM +0200, Eduardo Otubo wrote: > v6: > * remove switch-case > * invert obsolete option logic at vl.c > * remove debug info > v5: > * replaced strcmp by g_str_equal > * removed useless goto > * fixed style problems > > v4: > * include another field on the struct for the modes > * remove priority > * fixed typos > * error handling for prctl > * add allow|deny values for all options > * error hanlding for wrong values for all options > * change how binary values are treated > * reformat help text > > v3: > * Style problems fixed > > v2: > * The semantics of the options "allow/deny" instead of booleans "on/off" > remains. > * Added option 'children' to elevateprivileges > * Added documentation to docs/ > > v1: > * First version based on the discussion > https://lists.gnu.org/archive/html/qemu-devel/2017-02/msg03348.html > > Eduardo Otubo (6): > seccomp: changing from whitelist to blacklist > seccomp: add obsolete argument to command line > seccomp: add elevateprivileges argument to command line > seccomp: add spawn argument to command line > seccomp: add resourcecontrol argument to command line > seccomp: adding documentation to new seccomp model > > docs/seccomp.txt | 31 + > include/sysemu/seccomp.h | 8 +- > qemu-options.hx | 26 +++- > qemu-seccomp.c | 325 > ++- > vl.c | 82 +++- > 5 files changed, 235 insertions(+), 237 deletions(-) > create mode 100644 docs/seccomp.txt > > -- > 2.13.5 > > Daniel or anyone else interested in reviewing, any comment left for this patchset? If not I'll send the pull request tomorrow. Best regards, -- Eduardo Otubo Senior Software Engineer @ RedHat
[Qemu-devel] [PULL 00/06] seccomp branch queue
The following changes since commit 3dabde1128b671f36ac6cb36b97b273139964420: Merge remote-tracking branch 'remotes/dgilbert/tags/pull-hmp-20170914' into staging (2017-09-14 16:33:02 +0100) are available in the git repository at: https://github.com/otubo/qemu.git tags/pull-seccomp-20170915 for you to fetch changes up to c3883e1f935bf11ef0d2b8157b0022ace3d0e77d: buildsys: Move seccomp cflags/libs to per object (2017-09-15 10:16:05 +0200) pull-seccomp-20170915 -------- Eduardo Otubo (5): seccomp: changing from whitelist to blacklist seccomp: add obsolete argument to command line seccomp: add elevateprivileges argument to command line seccomp: add spawn argument to command line seccomp: add resourcecontrol argument to command line Fam Zheng (1): buildsys: Move seccomp cflags/libs to per object Makefile.objs| 2 + configure| 6 +- include/sysemu/seccomp.h | 8 +- qemu-options.hx | 26 +++- qemu-seccomp.c | 303 +++ vl.c | 84 - 6 files changed, 190 insertions(+), 239 deletions(-) -- 2.13.5
[Qemu-devel] [PULL 06/06] buildsys: Move seccomp cflags/libs to per object
From: Fam Zheng Like many other libraries, libseccomp cflags and libs should only apply to the building of necessary objects. Do so in the usual way with the help of per object variables. Signed-off-by: Fam Zheng Acked-by: Eduardo Otubo --- Makefile.objs | 2 ++ configure | 6 -- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Makefile.objs b/Makefile.objs index 24a4ea08b8..d9cf7ad791 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -70,6 +70,8 @@ common-obj-y += backends/ common-obj-y += chardev/ common-obj-$(CONFIG_SECCOMP) += qemu-seccomp.o +qemu-seccomp.o-cflags := $(SECCOMP_CFLAGS) +qemu-seccomp.o-libs := $(SECCOMP_LIBS) common-obj-$(CONFIG_FDT) += device_tree.o diff --git a/configure b/configure index 9ee4559b54..94db2d103e 100755 --- a/configure +++ b/configure @@ -2035,8 +2035,8 @@ if test "$seccomp" != "no" ; then if test "$libseccomp_minver" != "" && $pkg_config --atleast-version=$libseccomp_minver libseccomp ; then -libs_softmmu="$libs_softmmu $($pkg_config --libs libseccomp)" -QEMU_CFLAGS="$QEMU_CFLAGS $($pkg_config --cflags libseccomp)" +seccomp_cflags="$($pkg_config --cflags libseccomp)" +seccomp_libs="$($pkg_config --libs libseccomp)" seccomp="yes" else if test "$seccomp" = "yes" ; then @@ -5829,6 +5829,8 @@ fi if test "$seccomp" = "yes"; then echo "CONFIG_SECCOMP=y" >> $config_host_mak + echo "SECCOMP_CFLAGS=$seccomp_cflags" >> $config_host_mak + echo "SECCOMP_LIBS=$seccomp_libs" >> $config_host_mak fi # XXX: suppress that -- 2.13.5
[Qemu-devel] [PULL 04/06] seccomp: add spawn argument to command line
This patch adds [,spawn=deny] argument to `-sandbox on' option. It blacklists fork and execve system calls, avoiding Qemu to spawn new threads or processes. Signed-off-by: Eduardo Otubo Reviewed-by: Thomas Huth Reviewed-by: Daniel P. Berrange --- include/sysemu/seccomp.h | 1 + qemu-options.hx | 9 +++-- qemu-seccomp.c | 4 vl.c | 16 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/include/sysemu/seccomp.h b/include/sysemu/seccomp.h index 4a9e63c7cd..3ab5fc4f61 100644 --- a/include/sysemu/seccomp.h +++ b/include/sysemu/seccomp.h @@ -18,6 +18,7 @@ #define QEMU_SECCOMP_SET_DEFAULT (1 << 0) #define QEMU_SECCOMP_SET_OBSOLETE(1 << 1) #define QEMU_SECCOMP_SET_PRIVILEGED (1 << 2) +#define QEMU_SECCOMP_SET_SPAWN (1 << 3) #include diff --git a/qemu-options.hx b/qemu-options.hx index 5c1b163fb5..2b04b9f170 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4018,6 +4018,7 @@ ETEXI DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \ "-sandbox on[,obsolete=allow|deny][,elevateprivileges=allow|deny|children]\n" \ +" [,spawn=allow|deny]\n" \ "Enable seccomp mode 2 system call filter (default 'off').\n" \ "use 'obsolete' to allow obsolete system calls that are provided\n" \ "by the kernel, but typically no longer used by modern\n" \ @@ -4025,10 +4026,12 @@ DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \ "use 'elevateprivileges' to allow or deny QEMU process to elevate\n" \ "its privileges by blacklisting all set*uid|gid system calls.\n" \ "The value 'children' will deny set*uid|gid system calls for\n" \ -"main QEMU process but will allow forks and execves to run unprivileged\n", +"main QEMU process but will allow forks and execves to run unprivileged\n" \ +"use 'spawn' to avoid QEMU to spawn new threads or processes by\n" \ +" blacklisting *fork and execve\n", QEMU_ARCH_ALL) STEXI -@item -sandbox @var{arg}[,obsolete=@var{string}][,elevateprivileges=@var{string}] +@item -sandbox @var{arg}[,obsolete=@var{string}][,elevateprivileges=@var{string}][,spawn=@var{string}] @findex -sandbox Enable Seccomp mode 2 system call filter. 'on' will enable syscall filtering and 'off' will disable it. The default is 'off'. @@ -4037,6 +4040,8 @@ disable it. The default is 'off'. Enable Obsolete system calls @item elevateprivileges=@var{string} Disable set*uid|gid system calls +@item spawn=@var{string} +Disable *fork and execve @end table ETEXI diff --git a/qemu-seccomp.c b/qemu-seccomp.c index 978d66bd28..f3878a5e29 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -78,6 +78,10 @@ static const struct QemuSeccompSyscall blacklist[] = { { SCMP_SYS(setresgid), QEMU_SECCOMP_SET_PRIVILEGED }, { SCMP_SYS(setfsuid), QEMU_SECCOMP_SET_PRIVILEGED }, { SCMP_SYS(setfsgid), QEMU_SECCOMP_SET_PRIVILEGED }, +/* spawn */ +{ SCMP_SYS(fork), QEMU_SECCOMP_SET_SPAWN }, +{ SCMP_SYS(vfork), QEMU_SECCOMP_SET_SPAWN }, +{ SCMP_SYS(execve), QEMU_SECCOMP_SET_SPAWN }, }; diff --git a/vl.c b/vl.c index d59b560276..984db0c399 100644 --- a/vl.c +++ b/vl.c @@ -280,6 +280,10 @@ static QemuOptsList qemu_sandbox_opts = { .name = "elevateprivileges", .type = QEMU_OPT_STRING, }, +{ +.name = "spawn", +.type = QEMU_OPT_STRING, +}, { /* end of list */ } }, }; @@ -1083,6 +1087,18 @@ static int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp) } } +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; +} +} + if (seccomp_start(seccomp_opts) < 0) { error_report("failed to install seccomp syscall filter " "in the kernel"); -- 2.13.5
[Qemu-devel] [PULL 05/06] seccomp: add resourcecontrol argument to command line
This patch adds [,resourcecontrol=deny] to `-sandbox on' option. It blacklists all process affinity and scheduler priority system calls to avoid any bigger of the process. Signed-off-by: Eduardo Otubo Reviewed-by: Thomas Huth Reviewed-by: Daniel P. Berrange --- include/sysemu/seccomp.h | 1 + qemu-options.hx | 9 ++--- qemu-seccomp.c | 11 +++ vl.c | 16 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/include/sysemu/seccomp.h b/include/sysemu/seccomp.h index 3ab5fc4f61..e67c2dc840 100644 --- a/include/sysemu/seccomp.h +++ b/include/sysemu/seccomp.h @@ -19,6 +19,7 @@ #define QEMU_SECCOMP_SET_OBSOLETE(1 << 1) #define QEMU_SECCOMP_SET_PRIVILEGED (1 << 2) #define QEMU_SECCOMP_SET_SPAWN (1 << 3) +#define QEMU_SECCOMP_SET_RESOURCECTL (1 << 4) #include diff --git a/qemu-options.hx b/qemu-options.hx index 2b04b9f170..600614f6e5 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4018,7 +4018,7 @@ ETEXI DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \ "-sandbox on[,obsolete=allow|deny][,elevateprivileges=allow|deny|children]\n" \ -" [,spawn=allow|deny]\n" \ +" [,spawn=allow|deny][,resourcecontrol=allow|deny]\n" \ "Enable seccomp mode 2 system call filter (default 'off').\n" \ "use 'obsolete' to allow obsolete system calls that are provided\n" \ "by the kernel, but typically no longer used by modern\n" \ @@ -4028,10 +4028,11 @@ DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \ "The value 'children' will deny set*uid|gid system calls for\n" \ "main QEMU process but will allow forks and execves to run unprivileged\n" \ "use 'spawn' to avoid QEMU to spawn new threads or processes by\n" \ -" blacklisting *fork and execve\n", +" blacklisting *fork and execve\n" \ +"use 'resourcecontrol' to disable process affinity and schedular priority\n", QEMU_ARCH_ALL) STEXI -@item -sandbox @var{arg}[,obsolete=@var{string}][,elevateprivileges=@var{string}][,spawn=@var{string}] +@item -sandbox @var{arg}[,obsolete=@var{string}][,elevateprivileges=@var{string}][,spawn=@var{string}][,resourcecontrol=@var{string}] @findex -sandbox Enable Seccomp mode 2 system call filter. 'on' will enable syscall filtering and 'off' will disable it. The default is 'off'. @@ -4042,6 +4043,8 @@ Enable Obsolete system calls Disable set*uid|gid system calls @item spawn=@var{string} Disable *fork and execve +@item resourcecontrol=@var{string} +Disable process affinity and schedular priority @end table ETEXI diff --git a/qemu-seccomp.c b/qemu-seccomp.c index f3878a5e29..b770a77d33 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -82,6 +82,17 @@ static const struct QemuSeccompSyscall blacklist[] = { { SCMP_SYS(fork), QEMU_SECCOMP_SET_SPAWN }, { SCMP_SYS(vfork), QEMU_SECCOMP_SET_SPAWN }, { SCMP_SYS(execve), QEMU_SECCOMP_SET_SPAWN }, +/* resource control */ +{ SCMP_SYS(getpriority),QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(setpriority),QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(sched_setparam), QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(sched_getparam), QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(sched_setscheduler), QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(sched_getscheduler), QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(sched_setaffinity), QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(sched_getaffinity), QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(sched_get_priority_max), QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(sched_get_priority_min), QEMU_SECCOMP_SET_RESOURCECTL }, }; diff --git a/vl.c b/vl.c index 984db0c399..9e62e92aea 100644 --- a/vl.c +++ b/vl.c @@ -284,6 +284,10 @@ static QemuOptsList qemu_sandbox_opts = { .name = "spawn", .type = QEMU_OPT_STRING, }, +{ +.name = "resourcecontrol", +.type = QEMU_OPT_STRING, +}, { /* end of list */ } }, }; @@ -1099,6 +1103,18 @@ static int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp) } } +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")) { +
[Qemu-devel] [PULL 01/06] seccomp: changing from whitelist to blacklist
This patch changes the default behavior of the seccomp filter from whitelist to blacklist. By default now all system calls are allowed and a small black list of definitely forbidden ones was created. Signed-off-by: Eduardo Otubo Reviewed-by: Thomas Huth Reviewed-by: Daniel P. Berrange --- include/sysemu/seccomp.h | 2 + qemu-seccomp.c | 260 +-- vl.c | 1 - 3 files changed, 30 insertions(+), 233 deletions(-) diff --git a/include/sysemu/seccomp.h b/include/sysemu/seccomp.h index cfc06008cb..23b9c3c789 100644 --- a/include/sysemu/seccomp.h +++ b/include/sysemu/seccomp.h @@ -15,6 +15,8 @@ #ifndef QEMU_SECCOMP_H #define QEMU_SECCOMP_H +#define QEMU_SECCOMP_SET_DEFAULT (1 << 0) + #include int seccomp_start(void); diff --git a/qemu-seccomp.c b/qemu-seccomp.c index df75d9c471..f66613fc71 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -28,232 +28,33 @@ struct QemuSeccompSyscall { int32_t num; -uint8_t priority; +uint8_t set; }; -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(socketcall), 250 }, -{ SCMP_SYS(read), 249 }, -{ SCMP_SYS(io_submit), 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(socket), 245 }, -{ SCMP_SYS(setsockopt), 245 }, -{ SCMP_SYS(recvmsg), 245 }, -{ SCMP_SYS(sendmsg), 245 }, -{ SCMP_SYS(accept), 245 }, -{ SCMP_SYS(connect), 245 }, -{ SCMP_SYS(socketpair), 245 }, -{ SCMP_SYS(bind), 245 }, -{ SCMP_SYS(listen), 245 }, -{ SCMP_SYS(semget), 245 }, -{ SCMP_SYS(ipc), 245 }, -{ SCMP_SYS(gettimeofday), 245 }, -{ SCMP_SYS(readlink), 245 }, -{ SCMP_SYS(access), 245 }, -{ SCMP_SYS(prctl), 245 }, -{ SCMP_SYS(signalfd), 245 }, -{ SCMP_SYS(getrlimit), 245 }, -{ SCMP_SYS(getrusage), 245 }, -{ SCMP_SYS(set_tid_address), 245 }, -{ SCMP_SYS(statfs), 245 }, -{ SCMP_SYS(unlink), 245 }, -{ SCMP_SYS(wait4), 245 }, -{ SCMP_SYS(fcntl64), 245 }, -{ SCMP_SYS(fstat64), 245 }, -{ SCMP_SYS(stat64), 245 }, -{ SCMP_SYS(getgid32), 245 }, -{ SCMP_SYS(getegid32), 245 }, -{ SCMP_SYS(getuid32), 245 }, -{ SCMP_SYS(geteuid32), 245 }, -{ SCMP_SYS(sigreturn), 245 }, -{ SCMP_SYS(_newselect), 245 }, -{ SCMP_SYS(_llseek), 245 }, -{ SCMP_SYS(mmap2), 245 }, -{ SCMP_SYS(sigprocmask), 245 }, -{ SCMP_SYS(sched_getparam), 245 }, -{ SCMP_SYS(sched_getscheduler), 245 }, -{ SCMP_SYS(fstat), 245 }, -{ SCMP_SYS(clock_getres), 245 }, -{ SCMP_SYS(sched_get_priority_min), 245 }, -{ SCMP_SYS(sched_get_priority_max), 245 }, -{ SCMP_SYS(stat), 245 }, -{ SCMP_SYS(uname), 245 }, -{ SCMP_SYS(eventfd2), 245 }, -{ SCMP_SYS(io_getevents), 245 }, -{ SCMP_SYS(dup), 245 }, -{ SCMP_SYS(dup2), 245 }, -{ SCMP_SYS(dup3), 245 }, -{ SCMP_SYS(gettid), 245 }, -{ SCMP_SYS(getgid), 245 }, -{ SCMP_SYS(getegid), 245 }, -{ SCMP_SYS(getuid), 245 }, -{ SCMP_SYS(geteuid), 245 }, -{ SCMP_SYS(timer_create), 245 }, -{ SCMP_SYS(times), 245 }, -{ SCMP_SYS(exit), 245 }, -{ SCMP_SYS(clock_gettime), 245 }, -{ SCMP_SYS(time), 245 }, -{ SCMP_SYS(restart_syscall), 245 }, -{ SCMP_SYS(pwrite64), 245 }, -{ SCMP_SYS(nanosleep), 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(rt_sigreturn), 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(pselect6), 245 }, -{ SCMP_SYS(fork), 245 }, -{ SCMP_SYS(rt_sigprocmask), 245 }, -{ SCMP_SYS(write), 244 }, -{ SCMP_SYS(fcntl), 243 }, -{ SCMP_SYS(tgkill), 242 }, -{ SCMP_SYS(kill), 242 }, -{ SCMP_SYS(rt_sigaction), 242 }, -{ SCMP_SYS(pipe2), 242 }, -{ SCMP_SYS(munmap), 242 }, -{ SCMP_SYS(mremap), 242 }, -{ SCMP_SYS(fdatasync), 242 }, -{ SCMP_SYS(close), 242 }, -{ SCMP_SYS(rt_sigpending), 242 }, -{ SCMP_SYS(rt_sigtimedwait), 242 }, -{ SCMP_SYS(readv), 242 }, -{ SCMP_SYS(writev), 242 }, -{ SCMP_SYS(preadv), 242 }, -{ SCMP_SYS(pwritev), 242 }, -{ SCMP_SYS(setrlimit), 242 }, -{ SCMP_SYS(ftruncate), 242 }, -{ SCMP_SYS(lstat), 242 }, -{ SCMP_SYS(pipe), 242 }, -{ SCMP_SYS(umask), 242 }, -{ SCMP_SYS(chdir), 242 }, -{ SCMP_SYS(setitimer), 242 }, -{ SCMP_SYS(setsid), 242 }, -{ SCMP_SYS(poll
[Qemu-devel] [PULL 02/06] seccomp: add obsolete argument to command line
This patch introduces the argument [,obsolete=allow] to the `-sandbox on' option. It allows Qemu to run safely on old system that still relies on old system calls. Signed-off-by: Eduardo Otubo Reviewed-by: Thomas Huth Reviewed-by: Daniel P. Berrange --- include/sysemu/seccomp.h | 3 ++- qemu-options.hx | 12 ++-- qemu-seccomp.c | 19 ++- vl.c | 24 +++- 4 files changed, 53 insertions(+), 5 deletions(-) diff --git a/include/sysemu/seccomp.h b/include/sysemu/seccomp.h index 23b9c3c789..215138a372 100644 --- a/include/sysemu/seccomp.h +++ b/include/sysemu/seccomp.h @@ -16,8 +16,9 @@ #define QEMU_SECCOMP_H #define QEMU_SECCOMP_SET_DEFAULT (1 << 0) +#define QEMU_SECCOMP_SET_OBSOLETE(1 << 1) #include -int seccomp_start(void); +int seccomp_start(uint32_t seccomp_opts); #endif diff --git a/qemu-options.hx b/qemu-options.hx index 9f6e2adfff..72150c6b84 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4017,13 +4017,21 @@ Old param mode (ARM only). ETEXI DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \ -"-sandbox Enable seccomp mode 2 system call filter (default 'off').\n", +"-sandbox on[,obsolete=allow|deny]\n" \ +"Enable seccomp mode 2 system call filter (default 'off').\n" \ +"use 'obsolete' to allow obsolete system calls that are provided\n" \ +"by the kernel, but typically no longer used by modern\n" \ +"C library implementations.\n", QEMU_ARCH_ALL) STEXI -@item -sandbox @var{arg} +@item -sandbox @var{arg}[,obsolete=@var{string}] @findex -sandbox Enable Seccomp mode 2 system call filter. 'on' will enable syscall filtering and 'off' will disable it. The default is 'off'. +@table @option +@item obsolete=@var{string} +Enable Obsolete system calls +@end table ETEXI DEF("readconfig", HAS_ARG, QEMU_OPTION_readconfig, diff --git a/qemu-seccomp.c b/qemu-seccomp.c index f66613fc71..8a5fbd2ff1 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -55,9 +55,22 @@ static const struct QemuSeccompSyscall blacklist[] = { { SCMP_SYS(tuxcall),QEMU_SECCOMP_SET_DEFAULT }, { SCMP_SYS(ulimit), QEMU_SECCOMP_SET_DEFAULT }, { SCMP_SYS(vserver),QEMU_SECCOMP_SET_DEFAULT }, +/* obsolete */ +{ SCMP_SYS(readdir),QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(_sysctl),QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(bdflush),QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(create_module), QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(get_kernel_syms),QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(query_module), QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(sgetmask), QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(ssetmask), QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(sysfs), QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(uselib), QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(ustat), QEMU_SECCOMP_SET_OBSOLETE }, }; -int seccomp_start(void) + +int seccomp_start(uint32_t seccomp_opts) { int rc = 0; unsigned int i = 0; @@ -70,6 +83,10 @@ int seccomp_start(void) } for (i = 0; i < ARRAY_SIZE(blacklist); i++) { +if (!(seccomp_opts & blacklist[i].set)) { +continue; +} + rc = seccomp_rule_add(ctx, SCMP_ACT_KILL, blacklist[i].num, 0); if (rc < 0) { goto seccomp_return; diff --git a/vl.c b/vl.c index 76e0b3a946..57c5e93c1a 100644 --- a/vl.c +++ b/vl.c @@ -271,6 +271,10 @@ static QemuOptsList qemu_sandbox_opts = { .name = "enable", .type = QEMU_OPT_BOOL, }, +{ +.name = "obsolete", +.type = QEMU_OPT_STRING, +}, { /* end of list */ } }, }; @@ -1034,7 +1038,25 @@ static int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp) { if (qemu_opt_get_bool(opts, "enable", false)) { #ifdef CONFIG_SECCOMP -if (seccomp_start() < 0) { +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 { +
[Qemu-devel] [PULL 03/06] seccomp: add elevateprivileges argument to command line
This patch introduces the new argument [,elevateprivileges=allow|deny|children] to the `-sandbox on'. It allows or denies Qemu process to elevate its privileges by blacklisting all set*uid|gid system calls. The 'children' option will let forks and execves run unprivileged. Signed-off-by: Eduardo Otubo Reviewed-by: Thomas Huth Reviewed-by: Daniel P. Berrange --- include/sysemu/seccomp.h | 1 + qemu-options.hx | 12 +--- qemu-seccomp.c | 11 +++ vl.c | 27 +++ 4 files changed, 48 insertions(+), 3 deletions(-) diff --git a/include/sysemu/seccomp.h b/include/sysemu/seccomp.h index 215138a372..4a9e63c7cd 100644 --- a/include/sysemu/seccomp.h +++ b/include/sysemu/seccomp.h @@ -17,6 +17,7 @@ #define QEMU_SECCOMP_SET_DEFAULT (1 << 0) #define QEMU_SECCOMP_SET_OBSOLETE(1 << 1) +#define QEMU_SECCOMP_SET_PRIVILEGED (1 << 2) #include diff --git a/qemu-options.hx b/qemu-options.hx index 72150c6b84..5c1b163fb5 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4017,20 +4017,26 @@ Old param mode (ARM only). ETEXI DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \ -"-sandbox on[,obsolete=allow|deny]\n" \ +"-sandbox on[,obsolete=allow|deny][,elevateprivileges=allow|deny|children]\n" \ "Enable seccomp mode 2 system call filter (default 'off').\n" \ "use 'obsolete' to allow obsolete system calls that are provided\n" \ "by the kernel, but typically no longer used by modern\n" \ -"C library implementations.\n", +"C library implementations.\n" \ +"use 'elevateprivileges' to allow or deny QEMU process to elevate\n" \ +"its privileges by blacklisting all set*uid|gid system calls.\n" \ +"The value 'children' will deny set*uid|gid system calls for\n" \ +"main QEMU process but will allow forks and execves to run unprivileged\n", QEMU_ARCH_ALL) STEXI -@item -sandbox @var{arg}[,obsolete=@var{string}] +@item -sandbox @var{arg}[,obsolete=@var{string}][,elevateprivileges=@var{string}] @findex -sandbox Enable Seccomp mode 2 system call filter. 'on' will enable syscall filtering and 'off' will disable it. The default is 'off'. @table @option @item obsolete=@var{string} Enable Obsolete system calls +@item elevateprivileges=@var{string} +Disable set*uid|gid system calls @end table ETEXI diff --git a/qemu-seccomp.c b/qemu-seccomp.c index 8a5fbd2ff1..978d66bd28 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -67,6 +67,17 @@ static const struct QemuSeccompSyscall blacklist[] = { { SCMP_SYS(sysfs), QEMU_SECCOMP_SET_OBSOLETE }, { SCMP_SYS(uselib), QEMU_SECCOMP_SET_OBSOLETE }, { SCMP_SYS(ustat), QEMU_SECCOMP_SET_OBSOLETE }, +/* privileged */ +{ SCMP_SYS(setuid), QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setgid), QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setpgid),QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setsid), QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setreuid), QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setregid), QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setresuid), QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setresgid), QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setfsuid), QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setfsgid), QEMU_SECCOMP_SET_PRIVILEGED }, }; diff --git a/vl.c b/vl.c index 57c5e93c1a..d59b560276 100644 --- a/vl.c +++ b/vl.c @@ -29,6 +29,7 @@ #ifdef CONFIG_SECCOMP #include "sysemu/seccomp.h" +#include "sys/prctl.h" #endif #if defined(CONFIG_VDE) @@ -275,6 +276,10 @@ static QemuOptsList qemu_sandbox_opts = { .name = "obsolete", .type = QEMU_OPT_STRING, }, +{ +.name = "elevateprivileges", +.type = QEMU_OPT_STRING, +}, { /* end of list */ } }, }; @@ -1056,6 +1061,28 @@ static int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp) } } +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 +
[Qemu-devel] [PATCH] dma/i82374: avoid double creation of i82374 device
QEMU fails when used with the following command line: ./ppc64-softmmu/qemu-system-ppc64 -S -machine 40p,accel=tcg -device i82374 qemu-system-ppc64: hw/isa/isa-bus.c:110: isa_bus_dma: Assertion `!bus->dma[0] && !bus->dma[1]' failed. Aborted (core dumped) The 40p machine type already creates the device i82374. If specified in the command line, it will try to create it again, hence generating the error. The function isa_bus_dma() isn't supposed to be called twice for the same bus. One way to avoid this problem is to set user_creatable=false. A possible fix in a near future would be making isa_bus_dma()/DMA_init()/i82374_realize() return an error instead of asserting as well. Signed-off-by: Eduardo Otubo --- hw/dma/i82374.c | 5 + 1 file changed, 5 insertions(+) diff --git a/hw/dma/i82374.c b/hw/dma/i82374.c index 6c0f975df0..e76dea8dc7 100644 --- a/hw/dma/i82374.c +++ b/hw/dma/i82374.c @@ -139,6 +139,11 @@ static void i82374_class_init(ObjectClass *klass, void *data) dc->realize = i82374_realize; dc->vmsd = &vmstate_i82374; dc->props = i82374_properties; +dc->user_creatable = false; +/* + * Reason: i82374_realize() crashes (assertion failure inside isa_bus_dma() + * if the device is instantiated twice. + */ } static const TypeInfo i82374_info = { -- 2.13.5
Re: [Qemu-devel] [Qemu-trivial] [PATCH] dma/i82374: avoid double creation of i82374 device
(oups, forgot the v2 on Subject) On Fri, Sep 15, 2017 at 11:06:43AM +0200, Eduardo Otubo wrote: > QEMU fails when used with the following command line: > > ./ppc64-softmmu/qemu-system-ppc64 -S -machine 40p,accel=tcg -device i82374 > qemu-system-ppc64: hw/isa/isa-bus.c:110: isa_bus_dma: Assertion > `!bus->dma[0] && !bus->dma[1]' failed. > Aborted (core dumped) > > The 40p machine type already creates the device i82374. If specified in the > command line, it will try to create it again, hence generating the error. The > function isa_bus_dma() isn't supposed to be called twice for the same bus. One > way to avoid this problem is to set user_creatable=false. > > A possible fix in a near future would be making > isa_bus_dma()/DMA_init()/i82374_realize() return an error instead of asserting > as well. > > Signed-off-by: Eduardo Otubo > --- > hw/dma/i82374.c | 5 + > 1 file changed, 5 insertions(+) > > diff --git a/hw/dma/i82374.c b/hw/dma/i82374.c > index 6c0f975df0..e76dea8dc7 100644 > --- a/hw/dma/i82374.c > +++ b/hw/dma/i82374.c > @@ -139,6 +139,11 @@ static void i82374_class_init(ObjectClass *klass, void > *data) > dc->realize = i82374_realize; > dc->vmsd = &vmstate_i82374; > dc->props = i82374_properties; > +dc->user_creatable = false; > +/* > + * Reason: i82374_realize() crashes (assertion failure inside > isa_bus_dma() > + * if the device is instantiated twice. > + */ > } > > static const TypeInfo i82374_info = { > -- > 2.13.5 > > -- Eduardo Otubo Senior Software Engineer @ RedHat
Re: [Qemu-devel] [PATCH] dma/i82374: avoid double creation of i82374 device
On Fri, Sep 15, 2017 at 12:18:11PM +0200, Paolo Bonzini wrote: > On 15/09/2017 11:06, Eduardo Otubo wrote: > > QEMU fails when used with the following command line: > > > > ./ppc64-softmmu/qemu-system-ppc64 -S -machine 40p,accel=tcg -device i82374 > > qemu-system-ppc64: hw/isa/isa-bus.c:110: isa_bus_dma: Assertion > > `!bus->dma[0] && !bus->dma[1]' failed. > > Aborted (core dumped) > > > > The 40p machine type already creates the device i82374. If specified in the > > command line, it will try to create it again, hence generating the error. > > The > > function isa_bus_dma() isn't supposed to be called twice for the same bus. > > One > > way to avoid this problem is to set user_creatable=false. > > > > A possible fix in a near future would be making > > isa_bus_dma()/DMA_init()/i82374_realize() return an error instead of > > asserting > > as well. > > > > Signed-off-by: Eduardo Otubo > > --- > > hw/dma/i82374.c | 5 + > > 1 file changed, 5 insertions(+) > > > > diff --git a/hw/dma/i82374.c b/hw/dma/i82374.c > > index 6c0f975df0..e76dea8dc7 100644 > > --- a/hw/dma/i82374.c > > +++ b/hw/dma/i82374.c > > @@ -139,6 +139,11 @@ static void i82374_class_init(ObjectClass *klass, void > > *data) > > dc->realize = i82374_realize; > > dc->vmsd = &vmstate_i82374; > > dc->props = i82374_properties; > > +dc->user_creatable = false; > > +/* > > + * Reason: i82374_realize() crashes (assertion failure inside > > isa_bus_dma() > > + * if the device is instantiated twice. > > + */ > > } > > > > static const TypeInfo i82374_info = { > > > > This breaks "make check", doesn't it? > > v2 should be the one that returns an error instead of asserting. I guess I have misunderstood, then. I'll work on a patch to propagate the error then. Thanks, -- Eduardo Otubo Senior Software Engineer @ RedHat
Re: [Qemu-devel] [PATCH] seccomp: Don't include libseccomp from QEMU header
On Fri, Sep 22, 2017 at 09:09:27AM +0200, Jan Kiszka wrote: > On 2017-09-20 10:36, Fam Zheng wrote: > > The only prototype doesn't need anything from the lib header, and not > > including it here allows files that include this header, for example > > vl.c, to compile without the libseccomp cflags. > > > > The breakage is since c3883e1f93 for environments where `pkg-config > > --cflags libseccomp" is non-empty. > > > > Reported-by: Jan Kiszka > > Signed-off-by: Fam Zheng Acked-by: Eduardo Otubo > > > > --- > > > > This is an alternative for > > > > https://lists.gnu.org/archive/html/qemu-devel/2017-09/msg04470.html > > ([Qemu-devel] [PATCH] seccomp: Fix build) > > --- > > include/sysemu/seccomp.h | 2 -- > > 1 file changed, 2 deletions(-) > > > > diff --git a/include/sysemu/seccomp.h b/include/sysemu/seccomp.h > > index e67c2dc840..9b092aa23f 100644 > > --- a/include/sysemu/seccomp.h > > +++ b/include/sysemu/seccomp.h > > @@ -21,7 +21,5 @@ > > #define QEMU_SECCOMP_SET_SPAWN (1 << 3) > > #define QEMU_SECCOMP_SET_RESOURCECTL (1 << 4) > > > > -#include > > - > > int seccomp_start(uint32_t seccomp_opts); > > #endif > > > > Works fine for me as well and is indeed cleaner. > > Jan > > -- > Siemens AG, Corporate Technology, CT RDA ITP SES-DE > Corporate Competence Center Embedded Linux -- Eduardo Otubo Senior Software Engineer @ RedHat
Re: [Qemu-devel] [[PATCH] dma/i82374: avoid double creation of i82374 device
On Mon, Sep 25, 2017 at 11:11:37AM +0200, Paolo Bonzini wrote: > On 24/09/2017 23:02, Michael Tokarev wrote: > > 15.09.2017 12:06, Eduardo Otubo wrote: > >> QEMU fails when used with the following command line: > >> > >> ./ppc64-softmmu/qemu-system-ppc64 -S -machine 40p,accel=tcg -device > >> i82374 > >> qemu-system-ppc64: hw/isa/isa-bus.c:110: isa_bus_dma: Assertion > >> `!bus->dma[0] && !bus->dma[1]' failed. > >> Aborted (core dumped) > >> > >> The 40p machine type already creates the device i82374. If specified in the > >> command line, it will try to create it again, hence generating the error. > >> The > >> function isa_bus_dma() isn't supposed to be called twice for the same bus. > >> One > >> way to avoid this problem is to set user_creatable=false. > > > > Applied to -trivial, thanks! > > Eduardo, weren't you going to send a version that propagates Error* > correctly instead? Yes, that's correct. I can revert this patch with the error propagation patch as well, if you guys don't mind.
Re: [Qemu-devel] [PULL 00/31] Trivial patches for 2017-09-25
On Tue, Sep 26, 2017 at 08:57:00AM +0300, Michael Tokarev wrote: > 26.09.2017 02:22, Peter Maydell wrote: > [] > >> trivial patches for 2017-09-25 > > > > This fails 'make check' on most of my configs: > > > > GTESTER check-qtest-ppc64 > > qemu-system-ppc64: -object > > filter-mirror,id=qtest-f0,netdev=qtest-bn0,queue=tx,outdev=mirror0: > > Device 'qtest-bn0' not found > > Broken pipe > > GTester: last random seed: R02Sb816ff80b7d08ef6a5328ff373d8cd65 > > > > GLib-CRITICAL **: void g_hook_destroy_link(GHookList *, GHook *): > > assertion `hook != NULL' failed > > aborting... > That's really weird, I'm pretty sure I did run make check before sending it. Anyways, thanks for catching this. I'll fix and resend. > For what it's worth, this time I just _forgot_ to run tests. What a shame.. > > It fails due to: > > Author: Eduardo Otubo > Date: Mon Aug 21 17:50:05 2017 +0200 > > filter-mirror: segfault when specifying non existent device > > When using filter-mirror like the example below where the interface > 'ndev0' does not exist on the host, QEMU crashes into segmentation > fault. > > $ qemu-system-x86_64 -S -machine pc -netdev user,id=ndev0 -object > filter-mirror,id=test-object,netdev=ndev0 > > This happens because the function filter_mirror_setup() does not checks > if the device actually exists and still keep on processing calling > qemu_chr_find(). This patch fixes this issue. > > Signed-off-by: Eduardo Otubo > Reviewed-by: Zhang Chen > > Reverting this patch makes it run again. Cc'ing Eduardo. > > I'll remove this patch, patch "hw/isa/pc87312: Mark the device with > user_creatable = false" (will be replaced with a better variant), > and update another patch stripping one more trailing whitespace, > and resend. > > Thanks, > > /mjt -- Eduardo Otubo Senior Software Engineer @ RedHat
Re: [Qemu-devel] [Qemu-trivial] [PATCH] unicore32: abort when entering "x 0" on the monitor
On Mon, Jul 31, 2017 at 01:17:03PM +0300, Michael Tokarev wrote: > 28.07.2017 14:51, Eduardo Otubo wrote: > > Starting Qemu with "qemu-system-unicore32 -M puv3,accel=qtest -S -nographic" > > and entering "x 0 " at the monitor prompt leads to abort(): > > Applied to -trivial, thanks! > Hi Michael, you missed this patch in the latest pull request. Care to take it on the next one? I'm planning to send some other small fixes until this Friday. Regards, -- Eduardo Otubo Senior Software Engineer @ RedHat
[Qemu-devel] (no subject)
zhangchen.f...@cn.fujitsu.com, wang.guan...@zte.com.cn, wang.yong...@zte.com.cn Bcc: Subject: colo-compare: segfault and assert on colo_compare_finalize Reply-To: Hi all, I have found a problem on colo-compare that leads to segmentation fault when calling qemu like this: $ qemu-system-x86_64 -S -machine pc -object colo-compare,id=test-object First I got an assert failed: (qemu-system-x86_64:7887): GLib-CRITICAL **: g_main_loop_quit: assertion 'loop != NULL' failed >From this looks like s->compare_loop is NULL on the function colo_compare_finalize(), then I just added a check there and the assert went away. But then there's the segfault: Thread 1 "qemu-system-x86" received signal SIGSEGV, Segmentation fault. 0x7333f79e in pthread_join () from /lib64/libpthread.so.0 (gdb) bt #0 0x7333f79e in pthread_join () at /lib64/libpthread.so.0 #1 0x55c379d2 in qemu_thread_join (thread=0x77ff5160) at util/qemu-thread-posix.c:547 #2 0x55adfc1a in colo_compare_finalize (obj=0x77fd3010) at net/colo-compare.c:867 #3 0x55b2cd87 in object_deinit (obj=0x77fd3010, type=0x567432e0) at qom/object.c:453 #4 0x55b2cdf9 in object_finalize (data=0x77fd3010) at qom/object.c:467 #5 0x55b2dd80 in object_unref (obj=0x77fd3010) at qom/object.c:902 #6 0x55b319a5 in user_creatable_add_type (type=0x567499a0 "colo-compare", id=0x56749960 "test-object", qdict=0x56835750, v=0x5681a3f0, errp=0x7fffde58) at qom/object_interfaces.c:105 #7 0x55b31b02 in user_creatable_add_opts (opts=0x56749910, errp=0x7fffde58) at qom/object_interfaces.c:135 #8 0x55b31bfd in user_creatable_add_opts_foreach (opaque=0x558e9c39 , opts=0x56749910, errp=0x0) at qom/object_interfaces.c:159 #9 0x55c4aecf in qemu_opts_foreach (list=0x56157ac0 , func=0x55b31b6f , opaque=0x558e9c39 , errp=0x0) at util/qemu-option.c:1104 #10 0x558edb75 in main (argc=6, argv=0x7fffe2d8, envp=0x7fffe310) at vl.c:4520 At this point '&s->thread' is '0'. Is this segfault and the above mentioned assert trigged because I'm creating a colo-compare object without any other parameter? In a positive case, a simple workaround and error check should do it. Otherwise I'll debug a little more. Best regards, -- Eduardo Otubo Senior Software Engineer @ RedHat
[Qemu-devel] colo-compare: segfault and assert on colo_compare_finalize
(please ignore my last email, looks like mutt wants play games lately) Hi all, I have found a problem on colo-compare that leads to segmentation fault when calling qemu like this: $ qemu-system-x86_64 -S -machine pc -object colo-compare,id=test-object First I got an assert failed: (qemu-system-x86_64:7887): GLib-CRITICAL **: g_main_loop_quit: assertion 'loop != NULL' failed From this looks like s->compare_loop is NULL on the function colo_compare_finalize(), then I just added a check there and the assert went away. But then there's the segfault: Thread 1 "qemu-system-x86" received signal SIGSEGV, Segmentation fault. 0x7333f79e in pthread_join () from /lib64/libpthread.so.0 (gdb) bt #0 0x7333f79e in pthread_join () at /lib64/libpthread.so.0 #1 0x55c379d2 in qemu_thread_join (thread=0x77ff5160) at util/qemu-thread-posix.c:547 #2 0x55adfc1a in colo_compare_finalize (obj=0x77fd3010) at net/colo-compare.c:867 #3 0x55b2cd87 in object_deinit (obj=0x77fd3010, type=0x567432e0) at qom/object.c:453 #4 0x55b2cdf9 in object_finalize (data=0x77fd3010) at qom/object.c:467 #5 0x55b2dd80 in object_unref (obj=0x77fd3010) at qom/object.c:902 #6 0x55b319a5 in user_creatable_add_type (type=0x567499a0 "colo-compare", id=0x56749960 "test-object", qdict=0x56835750, v=0x5681a3f0, errp=0x7fffde58) at qom/object_interfaces.c:105 #7 0x55b31b02 in user_creatable_add_opts (opts=0x56749910, errp=0x7fffde58) at qom/object_interfaces.c:135 #8 0x55b31bfd in user_creatable_add_opts_foreach (opaque=0x558e9c39 , opts=0x56749910, errp=0x0) at qom/object_interfaces.c:159 #9 0x55c4aecf in qemu_opts_foreach (list=0x56157ac0 , func=0x55b31b6f , opaque=0x558e9c39 , errp=0x0) at util/qemu-option.c:1104 #10 0x558edb75 in main (argc=6, argv=0x7fffe2d8, envp=0x7fffe310) at vl.c:4520 At this point '&s->thread' is '0'. Is this segfault and the above mentioned assert trigged because I'm creating a colo-compare object without any other parameter? In a positive case, a simple workaround and error check should do it. Otherwise I'll debug a little more. Best regards, -- Eduardo Otubo Senior Software Engineer // Red Hat Hyper-V Virtualization, Berlin, DE IRC: otubo@{RedHat, OFTC, Freenode}
Re: [Qemu-devel] colo-compare: segfault and assert on colo_compare_finalize
On 08/08/2017 01:30 PM, Hailiang Zhang wrote: Hi, Did you test this branch https://github.com/coloft/qemu/tree/colo-for-qemu-2.10-2017-4-22 ? This seems to be an already known problem, I'm not quite sure, it may be fixed by this patch It's not :( Using your branch I don't see the assert() error anymore, but the segfault remains and apparently in the same place: Thread 1 "qemu-system-x86" received signal SIGSEGV, Segmentation fault. 0x730ec79e in pthread_join () from /lib64/libpthread.so.0 (gdb) bt #0 0x730ec79e in pthread_join () at /lib64/libpthread.so.0 #1 0x55c0b807 in qemu_thread_join (thread=0x77ff5130) at util/qemu-thread-posix.c:504 #2 0x55ac96c2 in colo_compare_finalize (obj=0x77fd3010) at net/colo-compare.c:873 #3 0x55b12f90 in object_deinit (obj=0x77fd3010, type=0x566e4c70) at qom/object.c:454 #4 0x55b13002 in object_finalize (data=0x77fd3010) at qom/object.c:468 #5 0x55b13f92 in object_unref (obj=0x77fd3010) at qom/object.c:903 #6 0x55b17a3e in user_creatable_add_type (type=0x566eb270 "colo-compare", id=0x566eb230 "test-object", qdict=0x56781bc0, v=0x567798f0, errp=0x7fffde58) at qom/object_interfaces.c:104 #7 0x55b17b9b in user_creatable_add_opts (opts=0x566eb1e0, errp=0x7fffde58) at qom/object_interfaces.c:134 #8 0x55b17c96 in user_creatable_add_opts_foreach (opaque=0x558e3562 , opts=0x566eb1e0, errp=0x0) at qom/object_interfaces.c:158 #9 0x55c1e634 in qemu_opts_foreach (list=0x561077a0 , func=0x55b17c08 , opaque=0x558e3562 , errp=0x0) at util/qemu-option.c:1114 #10 0x558e7441 in main (argc=6, argv=0x7fffe2d8, envp=0x7fffe310) at vl.c:4455 So, from what you're saying, this is *not* caused by the lack of parameter on the command line. Right? b19456dd0ea4eb418ad093f092adbb882be13054 char: Fix removing wrong GSource that be found by fd_in_tag We use fd_in_tag to find a GSource, fd_in_tag is return value of g_source_attach(GSource *source, GMainContext *context), the return value is unique only in the same context, so we may get the same values with different 'context' parameters. It is no problem to find the right fd_in_tag by using g_main_context_find_source_by_id(GMainContext *context, guint source_id) while there is only one default main context. But colo-compare tries to create/use its own context, and if we pass wrong 'context' parameter with right fd_in_tag, we will find a wrong GSource to handle. We tried to fix the related codes in commit b43decb015a6efeb9e3cdbdb80f6547ad7248a4c, but it didn't fix the bug completely, because we still have some codes didn't pass *right* context parameter for remove_fd_in_watch(). Let's fix it by record the GSource directly instead of fd_in_tag. Signed-off-by: zhanghailiang Reviewed-by: Marc-André Lureau Message-Id: <1492564532-91680-1-git-send-email-zhang.zhanghaili...@huawei.com> Signed-off-by: Paolo Bonzini Actually, we have already re-writed this part, and please follow the later series. Thanks, Hailiang On 2017/8/8 0:39, Eduardo Otubo wrote: (please ignore my last email, looks like mutt wants play games lately) Hi all, I have found a problem on colo-compare that leads to segmentation fault when calling qemu like this: $ qemu-system-x86_64 -S -machine pc -object colo-compare,id=test-object First I got an assert failed: (qemu-system-x86_64:7887): GLib-CRITICAL **: g_main_loop_quit: assertion 'loop != NULL' failed From this looks like s->compare_loop is NULL on the function colo_compare_finalize(), then I just added a check there and the assert went away. But then there's the segfault: Thread 1 "qemu-system-x86" received signal SIGSEGV, Segmentation fault. 0x7333f79e in pthread_join () from /lib64/libpthread.so.0 (gdb) bt #0 0x7333f79e in pthread_join () at /lib64/libpthread.so.0 #1 0x55c379d2 in qemu_thread_join (thread=0x77ff5160) at util/qemu-thread-posix.c:547 #2 0x55adfc1a in colo_compare_finalize (obj=0x77fd3010) at net/colo-compare.c:867 #3 0x55b2cd87 in object_deinit (obj=0x77fd3010, type=0x567432e0) at qom/object.c:453 #4 0x55b2cdf9 in object_finalize (data=0x77fd3010) at qom/object.c:467 #5 0x55b2dd80 in object_unref (obj=0x77fd3010) at qom/object.c:902 #6 0x55b319a5 in user_creatable_add_type (type=0x567499a0 "colo-compare", id=0x56749960 "test-object", qdict=0x56835750, v=0x5681a3f0, errp=0x7fffde58) at qom/object_interfaces.c:105 #7 0x55b31b02 in user_creatable_add_opts (opts=0x56749910, errp=0x7fffde58) at qom/object_interfaces.c:135 #8 0x55b31bfd in user_creatable_add_opts_fo
Re: [Qemu-devel] [PATCH v3 2/6] seccomp: add obsolete argument to command line
On Wed, Aug 02, 2017 at 01:33:56PM +0100, Daniel P. Berrange wrote: > On Fri, Jul 28, 2017 at 02:10:36PM +0200, Eduardo Otubo wrote: > > This patch introduces the argument [,obsolete=allow] to the `-sandbox on' > > option. It allows Qemu to run safely on old system that still relies on > > old system calls. > > > > Signed-off-by: Eduardo Otubo > > --- > > include/sysemu/seccomp.h | 4 +++- > > qemu-options.hx | 9 +++-- > > qemu-seccomp.c | 32 +++- > > vl.c | 16 +++- > > 4 files changed, 56 insertions(+), 5 deletions(-) > > > > diff --git a/include/sysemu/seccomp.h b/include/sysemu/seccomp.h > > index cfc06008cb..7a7bde246b 100644 > > --- a/include/sysemu/seccomp.h > > +++ b/include/sysemu/seccomp.h > > @@ -15,7 +15,9 @@ > > #ifndef QEMU_SECCOMP_H > > #define QEMU_SECCOMP_H > > > > +#define OBSOLETE0x0001 > > Please namespace this - its far too generic a term to expose to other > source files. I'd suggest > > QEMU_SECCOMP_SET_OBSOLETE > > > -int seccomp_start(void); > > +int seccomp_start(uint8_t seccomp_opts); > > This only allows for 8 sets. Perhaps its enough, but I'd suggest > just using a uint32_t straight away. > > > diff --git a/qemu-options.hx b/qemu-options.hx > > index 746b5fa75d..54e492f36a 100644 > > --- a/qemu-options.hx > > +++ b/qemu-options.hx > > @@ -4004,13 +4004,18 @@ Old param mode (ARM only). > > ETEXI > > > > DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \ > > -"-sandbox Enable seccomp mode 2 system call filter (default > > 'off').\n", > > +"-sandbox on[,obsolete=allow] Enable seccomp mode 2 system call > > filter (default 'off').\n" \ > > +"obsolete: Allow obsolete system calls\n", > > QEMU_ARCH_ALL) > > STEXI > > -@item -sandbox @var{arg} > > +@item -sandbox @var{arg}[,obsolete=@var{string}] > > @findex -sandbox > > Enable Seccomp mode 2 system call filter. 'on' will enable syscall > > filtering and 'off' will > > disable it. The default is 'off'. > > +@table @option > > +@item obsolete=@var{string} > > +Enable Obsolete system calls > > Lets explain this a bit more. > > E obsolete system calls that are provided by the kernel, but typically no > longer used by modern C library implementations. > > > +@end table > > ETEXI > > > > DEF("readconfig", HAS_ARG, QEMU_OPTION_readconfig, > > diff --git a/qemu-seccomp.c b/qemu-seccomp.c > > index f8877b07b5..c6a8b28260 100644 > > --- a/qemu-seccomp.c > > +++ b/qemu-seccomp.c > > @@ -31,6 +31,20 @@ struct QemuSeccompSyscall { > > uint8_t priority; > > }; > > > > +static const struct QemuSeccompSyscall obsolete[] = { > > +{ SCMP_SYS(readdir), 255 }, > > +{ SCMP_SYS(_sysctl), 255 }, > > +{ SCMP_SYS(bdflush), 255 }, > > +{ SCMP_SYS(create_module), 255 }, > > +{ SCMP_SYS(get_kernel_syms), 255 }, > > +{ SCMP_SYS(query_module), 255 }, > > +{ SCMP_SYS(sgetmask), 255 }, > > +{ SCMP_SYS(ssetmask), 255 }, > > +{ SCMP_SYS(sysfs), 255 }, > > +{ SCMP_SYS(uselib), 255 }, > > +{ SCMP_SYS(ustat), 255 }, > > +}; > > + > > static const struct QemuSeccompSyscall blacklist[] = { > > { SCMP_SYS(reboot), 255 }, > > { SCMP_SYS(swapon), 255 }, > > @@ -56,7 +70,20 @@ static const struct QemuSeccompSyscall blacklist[] = { > > { SCMP_SYS(vserver), 255 }, > > }; > > > > -int seccomp_start(void) > > +static int is_obsolete(int syscall) > > +{ > > +unsigned int i = 0; > > + > > +for (i = 0; i < ARRAY_SIZE(obsolete); i++) { > > +if (syscall == obsolete[i].num) { > > +return 1; > > +} > > +} > > + > > +return 0; > > +} > > + > > +int seccomp_start(uint8_t seccomp_opts) > > { > > int rc = 0; > > unsigned int i = 0; > > @@ -69,6 +96,9 @@ int seccomp_start(void) > > } > > > > for (i = 0; i < ARRAY_SIZE(blacklist); i++) { > > +if ((seccomp_opts & OBSOLETE) && is_obsolete(blacklist[i].num)) { > > +continue; > > +} > > IMHO this is leading to a rather inefficient approach. Why not extend > QemuSeccompSyscall struct so that it has another field to
Re: [Qemu-devel] [PATCH v3 2/6] seccomp: add obsolete argument to command line
On Fri, Aug 11, 2017 at 11:12:48AM +0200, Eduardo Otubo wrote: > On Wed, Aug 02, 2017 at 01:33:56PM +0100, Daniel P. Berrange wrote: > > On Fri, Jul 28, 2017 at 02:10:36PM +0200, Eduardo Otubo wrote: > > > This patch introduces the argument [,obsolete=allow] to the `-sandbox on' > > > option. It allows Qemu to run safely on old system that still relies on > > > old system calls. > > > > > > Signed-off-by: Eduardo Otubo > > > --- > > > include/sysemu/seccomp.h | 4 +++- > > > qemu-options.hx | 9 +++-- > > > qemu-seccomp.c | 32 +++- > > > vl.c | 16 +++- > > > 4 files changed, 56 insertions(+), 5 deletions(-) > > > > > > diff --git a/include/sysemu/seccomp.h b/include/sysemu/seccomp.h > > > index cfc06008cb..7a7bde246b 100644 > > > --- a/include/sysemu/seccomp.h > > > +++ b/include/sysemu/seccomp.h > > > @@ -15,7 +15,9 @@ > > > #ifndef QEMU_SECCOMP_H > > > #define QEMU_SECCOMP_H > > > > > > +#define OBSOLETE0x0001 > > > > Please namespace this - its far too generic a term to expose to other > > source files. I'd suggest > > > > QEMU_SECCOMP_SET_OBSOLETE > > > > > -int seccomp_start(void); > > > +int seccomp_start(uint8_t seccomp_opts); > > > > This only allows for 8 sets. Perhaps its enough, but I'd suggest > > just using a uint32_t straight away. > > > > > diff --git a/qemu-options.hx b/qemu-options.hx > > > index 746b5fa75d..54e492f36a 100644 > > > --- a/qemu-options.hx > > > +++ b/qemu-options.hx > > > @@ -4004,13 +4004,18 @@ Old param mode (ARM only). > > > ETEXI > > > > > > DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \ > > > -"-sandbox Enable seccomp mode 2 system call filter (default > > > 'off').\n", > > > +"-sandbox on[,obsolete=allow] Enable seccomp mode 2 system call > > > filter (default 'off').\n" \ > > > +"obsolete: Allow obsolete system calls\n", > > > QEMU_ARCH_ALL) > > > STEXI > > > -@item -sandbox @var{arg} > > > +@item -sandbox @var{arg}[,obsolete=@var{string}] > > > @findex -sandbox > > > Enable Seccomp mode 2 system call filter. 'on' will enable syscall > > > filtering and 'off' will > > > disable it. The default is 'off'. > > > +@table @option > > > +@item obsolete=@var{string} > > > +Enable Obsolete system calls > > > > Lets explain this a bit more. > > > > E obsolete system calls that are provided by the kernel, but typically no > > longer used by modern C library implementations. > > > > > +@end table > > > ETEXI > > > > > > DEF("readconfig", HAS_ARG, QEMU_OPTION_readconfig, > > > diff --git a/qemu-seccomp.c b/qemu-seccomp.c > > > index f8877b07b5..c6a8b28260 100644 > > > --- a/qemu-seccomp.c > > > +++ b/qemu-seccomp.c > > > @@ -31,6 +31,20 @@ struct QemuSeccompSyscall { > > > uint8_t priority; > > > }; > > > > > > +static const struct QemuSeccompSyscall obsolete[] = { > > > +{ SCMP_SYS(readdir), 255 }, > > > +{ SCMP_SYS(_sysctl), 255 }, > > > +{ SCMP_SYS(bdflush), 255 }, > > > +{ SCMP_SYS(create_module), 255 }, > > > +{ SCMP_SYS(get_kernel_syms), 255 }, > > > +{ SCMP_SYS(query_module), 255 }, > > > +{ SCMP_SYS(sgetmask), 255 }, > > > +{ SCMP_SYS(ssetmask), 255 }, > > > +{ SCMP_SYS(sysfs), 255 }, > > > +{ SCMP_SYS(uselib), 255 }, > > > +{ SCMP_SYS(ustat), 255 }, > > > +}; > > > + > > > static const struct QemuSeccompSyscall blacklist[] = { > > > { SCMP_SYS(reboot), 255 }, > > > { SCMP_SYS(swapon), 255 }, > > > @@ -56,7 +70,20 @@ static const struct QemuSeccompSyscall blacklist[] = { > > > { SCMP_SYS(vserver), 255 }, > > > }; > > > > > > -int seccomp_start(void) > > > +static int is_obsolete(int syscall) > > > +{ > > > +unsigned int i = 0; > > > + > > > +for (i = 0; i < ARRAY_SIZE(obsolete); i++) { > > > +if (syscall == obsolete[i].num) { > > > +return 1; > > > +} > > > +} > > &g
Re: [Qemu-devel] [PATCH v3 1/6] seccomp: changing from whitelist to blacklist
On Thu, Aug 03, 2017 at 06:54:15PM +0200, Thomas Huth wrote: > On 28.07.2017 14:10, Eduardo Otubo wrote: > > This patch changes the default behavior of the seccomp filter from > > whitelist to blacklist. By default now all system calls are allowed and > > a small black list of definitely forbidden ones was created. > > > > Signed-off-by: Eduardo Otubo > > --- > > qemu-seccomp.c | 256 > > +++-- > > vl.c | 5 +- > > 2 files changed, 32 insertions(+), 229 deletions(-) > > > > diff --git a/qemu-seccomp.c b/qemu-seccomp.c > > index df75d9c471..f8877b07b5 100644 > > --- a/qemu-seccomp.c > > +++ b/qemu-seccomp.c > > @@ -31,229 +31,29 @@ struct QemuSeccompSyscall { > > uint8_t priority; > > }; > [...] > > +static const struct QemuSeccompSyscall blacklist[] = { > > +{ SCMP_SYS(reboot), 255 }, > > +{ SCMP_SYS(swapon), 255 }, > > +{ SCMP_SYS(swapoff), 255 }, > > +{ SCMP_SYS(syslog), 255 }, > > +{ SCMP_SYS(mount), 255 }, > > +{ SCMP_SYS(umount), 255 }, > > +{ SCMP_SYS(kexec_load), 255 }, > > +{ SCMP_SYS(afs_syscall), 255 }, > > +{ SCMP_SYS(break), 255 }, > > +{ SCMP_SYS(ftime), 255 }, > > +{ SCMP_SYS(getpmsg), 255 }, > > +{ SCMP_SYS(gtty), 255 }, > > +{ SCMP_SYS(lock), 255 }, > > +{ SCMP_SYS(mpx), 255 }, > > +{ SCMP_SYS(prof), 255 }, > > +{ SCMP_SYS(profil), 255 }, > > +{ SCMP_SYS(putpmsg), 255 }, > > +{ SCMP_SYS(security), 255 }, > > +{ SCMP_SYS(stty), 255 }, > > +{ SCMP_SYS(tuxcall), 255 }, > > +{ SCMP_SYS(ulimit), 255 }, > > +{ SCMP_SYS(vserver), 255 }, > > }; > > Does it makes sense to still keep the priority field? Everything is now > marked with the value 255 and I currently fail to see the point of > priorities when using blacklisting ... so maybe just get rid of it? I think that's a fair point here. Don't see much of a point on such a small number of syscalls. I just need to double check the libseccomp docs if I can build the list without any priority information, but I'm pretty sure I've seen this before. -- Eduardo Otubo Senior Software Engineer @ RedHat
[Qemu-devel] [PATCH] filter-mirror: segfault when specifying non existent device
When using filter-mirror like the example below where the interface 'ndev0' does not exist on the host, QEMU crashes into segmentation fault. $ qemu-system-x86_64 -S -machine pc -netdev user,id=ndev0 -object filter-mirror,id=test-object,netdev=ndev0 This happens because the function filter_mirror_setup() does not checks if the device actually exists and still keep on processing calling qemu_chr_find(). This patch fixes this issue. Signed-off-by: Eduardo Otubo --- net/filter-mirror.c | 14 +++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/net/filter-mirror.c b/net/filter-mirror.c index 90e2c92337..e18a4b16a0 100644 --- a/net/filter-mirror.c +++ b/net/filter-mirror.c @@ -213,14 +213,22 @@ static void filter_mirror_setup(NetFilterState *nf, Error **errp) MirrorState *s = FILTER_MIRROR(nf); Chardev *chr; +if (s->outdev == NULL) { +goto err; +} + chr = qemu_chr_find(s->outdev); + if (chr == NULL) { -error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, - "Device '%s' not found", s->outdev); -return; +goto err; } qemu_chr_fe_init(&s->chr_out, chr, errp); + +err: +error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, "Device '%s' not found", + nf->netdev_id); +return; } static void redirector_rs_finalize(SocketReadState *rs) -- 2.13.5
[Qemu-devel] [PATCHv4 0/6] seccomp: feature refactoring
v4: * include another field on the struct for the modes * remove priority * fixed typos * error handling for prctl * add allow|deny values for all options * error hanlding for wrong values for all options * change how binary values are treated * reformat help text v3: * Style problems fixed v2: * The semantics of the options "allow/deny" instead of booleans "on/off" remains. * Added option 'children' to elevateprivileges * Added documentation to docs/ v1: * First version based on the discussion https://lists.gnu.org/archive/html/qemu-devel/2017-02/msg03348.html Eduardo Otubo (6): seccomp: changing from whitelist to blacklist seccomp: add obsolete argument to command line seccomp: add elevateprivileges argument to command line seccomp: add spawn argument to command line seccomp: add resourcecontrol argument to command line seccomp: adding documentation to new seccomp model docs/seccomp.txt | 31 + include/sysemu/seccomp.h | 8 +- qemu-options.hx | 26 +++- qemu-seccomp.c | 325 ++- vl.c | 82 +++- 5 files changed, 235 insertions(+), 237 deletions(-) create mode 100644 docs/seccomp.txt -- 2.13.5
[Qemu-devel] [PATCHv4 3/6] seccomp: add elevateprivileges argument to command line
This patch introduces the new argument [,elevateprivileges=allow|deny|children] to the `-sandbox on'. It allows or denies Qemu process to elevate its privileges by blacklisting all set*uid|gid system calls. The 'children' option will let forks and execves run unprivileged. Signed-off-by: Eduardo Otubo --- include/sysemu/seccomp.h | 1 + qemu-options.hx | 12 +--- qemu-seccomp.c | 29 ++--- vl.c | 27 +++ 4 files changed, 55 insertions(+), 14 deletions(-) diff --git a/include/sysemu/seccomp.h b/include/sysemu/seccomp.h index 215138a372..4a9e63c7cd 100644 --- a/include/sysemu/seccomp.h +++ b/include/sysemu/seccomp.h @@ -17,6 +17,7 @@ #define QEMU_SECCOMP_SET_DEFAULT (1 << 0) #define QEMU_SECCOMP_SET_OBSOLETE(1 << 1) +#define QEMU_SECCOMP_SET_PRIVILEGED (1 << 2) #include diff --git a/qemu-options.hx b/qemu-options.hx index 72150c6b84..5c1b163fb5 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4017,20 +4017,26 @@ Old param mode (ARM only). ETEXI DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \ -"-sandbox on[,obsolete=allow|deny]\n" \ +"-sandbox on[,obsolete=allow|deny][,elevateprivileges=allow|deny|children]\n" \ "Enable seccomp mode 2 system call filter (default 'off').\n" \ "use 'obsolete' to allow obsolete system calls that are provided\n" \ "by the kernel, but typically no longer used by modern\n" \ -"C library implementations.\n", +"C library implementations.\n" \ +"use 'elevateprivileges' to allow or deny QEMU process to elevate\n" \ +"its privileges by blacklisting all set*uid|gid system calls.\n" \ +"The value 'children' will deny set*uid|gid system calls for\n" \ +"main QEMU process but will allow forks and execves to run unprivileged\n", QEMU_ARCH_ALL) STEXI -@item -sandbox @var{arg}[,obsolete=@var{string}] +@item -sandbox @var{arg}[,obsolete=@var{string}][,elevateprivileges=@var{string}] @findex -sandbox Enable Seccomp mode 2 system call filter. 'on' will enable syscall filtering and 'off' will disable it. The default is 'off'. @table @option @item obsolete=@var{string} Enable Obsolete system calls +@item elevateprivileges=@var{string} +Disable set*uid|gid system calls @end table ETEXI diff --git a/qemu-seccomp.c b/qemu-seccomp.c index 3e3f15cc08..16c8c20132 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -57,17 +57,16 @@ static const struct QemuSeccompSyscall blacklist[] = { { SCMP_SYS(ulimit),1, QEMU_SECCOMP_SET_DEFAULT }, { SCMP_SYS(vserver), 1, QEMU_SECCOMP_SET_DEFAULT }, /* obsolete */ -{ SCMP_SYS(readdir), 2, QEMU_SECCOMP_SET_OBSOLETE }, -{ SCMP_SYS(_sysctl), 2, QEMU_SECCOMP_SET_OBSOLETE }, -{ SCMP_SYS(bdflush), 2, QEMU_SECCOMP_SET_OBSOLETE }, -{ SCMP_SYS(create_module), 2, QEMU_SECCOMP_SET_OBSOLETE }, -{ SCMP_SYS(get_kernel_syms), 2, QEMU_SECCOMP_SET_OBSOLETE }, -{ SCMP_SYS(query_module), 2, QEMU_SECCOMP_SET_OBSOLETE }, -{ SCMP_SYS(sgetmask), 2, QEMU_SECCOMP_SET_OBSOLETE }, -{ SCMP_SYS(ssetmask), 2, QEMU_SECCOMP_SET_OBSOLETE }, -{ SCMP_SYS(sysfs), 2, QEMU_SECCOMP_SET_OBSOLETE }, -{ SCMP_SYS(uselib),2, QEMU_SECCOMP_SET_OBSOLETE }, -{ SCMP_SYS(ustat), 2, QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(setuid),4, QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setgid),4, QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setpgid), 4, QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setsid),4, QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setreuid), 4, QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setregid), 4, QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setresuid), 4, QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setresgid), 4, QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setfsuid), 4, QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setfsgid), 4, QEMU_SECCOMP_SET_PRIVILEGED }, }; @@ -93,6 +92,14 @@ int seccomp_start(uint32_t seccomp_opts) } break; +case QEMU_SECCOMP_SET_PRIVILEGED: +if (seccomp_opts & QEMU_SECCOMP_SET_PRIVILEGED) { +goto add_syscall; +} else { +continue; +} + +break; default: goto add_sysca
[Qemu-devel] [PATCHv4 1/6] seccomp: changing from whitelist to blacklist
This patch changes the default behavior of the seccomp filter from whitelist to blacklist. By default now all system calls are allowed and a small black list of definitely forbidden ones was created. Signed-off-by: Eduardo Otubo --- include/sysemu/seccomp.h | 2 + qemu-seccomp.c | 264 ++- vl.c | 1 - 3 files changed, 35 insertions(+), 232 deletions(-) diff --git a/include/sysemu/seccomp.h b/include/sysemu/seccomp.h index cfc06008cb..23b9c3c789 100644 --- a/include/sysemu/seccomp.h +++ b/include/sysemu/seccomp.h @@ -15,6 +15,8 @@ #ifndef QEMU_SECCOMP_H #define QEMU_SECCOMP_H +#define QEMU_SECCOMP_SET_DEFAULT (1 << 0) + #include int seccomp_start(void); diff --git a/qemu-seccomp.c b/qemu-seccomp.c index df75d9c471..585de42a97 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -28,232 +28,34 @@ struct QemuSeccompSyscall { int32_t num; -uint8_t priority; +int type; +uint8_t set; }; -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(socketcall), 250 }, -{ SCMP_SYS(read), 249 }, -{ SCMP_SYS(io_submit), 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(socket), 245 }, -{ SCMP_SYS(setsockopt), 245 }, -{ SCMP_SYS(recvmsg), 245 }, -{ SCMP_SYS(sendmsg), 245 }, -{ SCMP_SYS(accept), 245 }, -{ SCMP_SYS(connect), 245 }, -{ SCMP_SYS(socketpair), 245 }, -{ SCMP_SYS(bind), 245 }, -{ SCMP_SYS(listen), 245 }, -{ SCMP_SYS(semget), 245 }, -{ SCMP_SYS(ipc), 245 }, -{ SCMP_SYS(gettimeofday), 245 }, -{ SCMP_SYS(readlink), 245 }, -{ SCMP_SYS(access), 245 }, -{ SCMP_SYS(prctl), 245 }, -{ SCMP_SYS(signalfd), 245 }, -{ SCMP_SYS(getrlimit), 245 }, -{ SCMP_SYS(getrusage), 245 }, -{ SCMP_SYS(set_tid_address), 245 }, -{ SCMP_SYS(statfs), 245 }, -{ SCMP_SYS(unlink), 245 }, -{ SCMP_SYS(wait4), 245 }, -{ SCMP_SYS(fcntl64), 245 }, -{ SCMP_SYS(fstat64), 245 }, -{ SCMP_SYS(stat64), 245 }, -{ SCMP_SYS(getgid32), 245 }, -{ SCMP_SYS(getegid32), 245 }, -{ SCMP_SYS(getuid32), 245 }, -{ SCMP_SYS(geteuid32), 245 }, -{ SCMP_SYS(sigreturn), 245 }, -{ SCMP_SYS(_newselect), 245 }, -{ SCMP_SYS(_llseek), 245 }, -{ SCMP_SYS(mmap2), 245 }, -{ SCMP_SYS(sigprocmask), 245 }, -{ SCMP_SYS(sched_getparam), 245 }, -{ SCMP_SYS(sched_getscheduler), 245 }, -{ SCMP_SYS(fstat), 245 }, -{ SCMP_SYS(clock_getres), 245 }, -{ SCMP_SYS(sched_get_priority_min), 245 }, -{ SCMP_SYS(sched_get_priority_max), 245 }, -{ SCMP_SYS(stat), 245 }, -{ SCMP_SYS(uname), 245 }, -{ SCMP_SYS(eventfd2), 245 }, -{ SCMP_SYS(io_getevents), 245 }, -{ SCMP_SYS(dup), 245 }, -{ SCMP_SYS(dup2), 245 }, -{ SCMP_SYS(dup3), 245 }, -{ SCMP_SYS(gettid), 245 }, -{ SCMP_SYS(getgid), 245 }, -{ SCMP_SYS(getegid), 245 }, -{ SCMP_SYS(getuid), 245 }, -{ SCMP_SYS(geteuid), 245 }, -{ SCMP_SYS(timer_create), 245 }, -{ SCMP_SYS(times), 245 }, -{ SCMP_SYS(exit), 245 }, -{ SCMP_SYS(clock_gettime), 245 }, -{ SCMP_SYS(time), 245 }, -{ SCMP_SYS(restart_syscall), 245 }, -{ SCMP_SYS(pwrite64), 245 }, -{ SCMP_SYS(nanosleep), 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(rt_sigreturn), 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(pselect6), 245 }, -{ SCMP_SYS(fork), 245 }, -{ SCMP_SYS(rt_sigprocmask), 245 }, -{ SCMP_SYS(write), 244 }, -{ SCMP_SYS(fcntl), 243 }, -{ SCMP_SYS(tgkill), 242 }, -{ SCMP_SYS(kill), 242 }, -{ SCMP_SYS(rt_sigaction), 242 }, -{ SCMP_SYS(pipe2), 242 }, -{ SCMP_SYS(munmap), 242 }, -{ SCMP_SYS(mremap), 242 }, -{ SCMP_SYS(fdatasync), 242 }, -{ SCMP_SYS(close), 242 }, -{ SCMP_SYS(rt_sigpending), 242 }, -{ SCMP_SYS(rt_sigtimedwait), 242 }, -{ SCMP_SYS(readv), 242 }, -{ SCMP_SYS(writev), 242 }, -{ SCMP_SYS(preadv), 242 }, -{ SCMP_SYS(pwritev), 242 }, -{ SCMP_SYS(setrlimit), 242 }, -{ SCMP_SYS(ftruncate), 242 }, -{ SCMP_SYS(lstat), 242 }, -{ SCMP_SYS(pipe), 242 }, -{ SCMP_SYS(umask), 242 }, -{ SCMP_SYS(chdir), 242 }, -{ SCMP_SYS(setitimer), 242 }, -{ SCMP_SYS(setsid), 242 }, -{ SCMP_SYS(poll), 242 }, -{ SCMP_SYS(epoll_create
[Qemu-devel] [PATCHv4 4/6] seccomp: add spawn argument to command line
This patch adds [,spawn=deny] argument to `-sandbox on' option. It blacklists fork and execve system calls, avoiding Qemu to spawn new threads or processes. Signed-off-by: Eduardo Otubo --- include/sysemu/seccomp.h | 1 + qemu-options.hx | 9 +++-- qemu-seccomp.c | 12 vl.c | 16 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/include/sysemu/seccomp.h b/include/sysemu/seccomp.h index 4a9e63c7cd..3ab5fc4f61 100644 --- a/include/sysemu/seccomp.h +++ b/include/sysemu/seccomp.h @@ -18,6 +18,7 @@ #define QEMU_SECCOMP_SET_DEFAULT (1 << 0) #define QEMU_SECCOMP_SET_OBSOLETE(1 << 1) #define QEMU_SECCOMP_SET_PRIVILEGED (1 << 2) +#define QEMU_SECCOMP_SET_SPAWN (1 << 3) #include diff --git a/qemu-options.hx b/qemu-options.hx index 5c1b163fb5..2b04b9f170 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4018,6 +4018,7 @@ ETEXI DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \ "-sandbox on[,obsolete=allow|deny][,elevateprivileges=allow|deny|children]\n" \ +" [,spawn=allow|deny]\n" \ "Enable seccomp mode 2 system call filter (default 'off').\n" \ "use 'obsolete' to allow obsolete system calls that are provided\n" \ "by the kernel, but typically no longer used by modern\n" \ @@ -4025,10 +4026,12 @@ DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \ "use 'elevateprivileges' to allow or deny QEMU process to elevate\n" \ "its privileges by blacklisting all set*uid|gid system calls.\n" \ "The value 'children' will deny set*uid|gid system calls for\n" \ -"main QEMU process but will allow forks and execves to run unprivileged\n", +"main QEMU process but will allow forks and execves to run unprivileged\n" \ +"use 'spawn' to avoid QEMU to spawn new threads or processes by\n" \ +" blacklisting *fork and execve\n", QEMU_ARCH_ALL) STEXI -@item -sandbox @var{arg}[,obsolete=@var{string}][,elevateprivileges=@var{string}] +@item -sandbox @var{arg}[,obsolete=@var{string}][,elevateprivileges=@var{string}][,spawn=@var{string}] @findex -sandbox Enable Seccomp mode 2 system call filter. 'on' will enable syscall filtering and 'off' will disable it. The default is 'off'. @@ -4037,6 +4040,8 @@ disable it. The default is 'off'. Enable Obsolete system calls @item elevateprivileges=@var{string} Disable set*uid|gid system calls +@item spawn=@var{string} +Disable *fork and execve @end table ETEXI diff --git a/qemu-seccomp.c b/qemu-seccomp.c index 16c8c20132..51754ace71 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -67,6 +67,10 @@ static const struct QemuSeccompSyscall blacklist[] = { { SCMP_SYS(setresgid), 4, QEMU_SECCOMP_SET_PRIVILEGED }, { SCMP_SYS(setfsuid), 4, QEMU_SECCOMP_SET_PRIVILEGED }, { SCMP_SYS(setfsgid), 4, QEMU_SECCOMP_SET_PRIVILEGED }, +/* spawn */ +{ SCMP_SYS(fork), 8, QEMU_SECCOMP_SET_SPAWN }, +{ SCMP_SYS(vfork), 8, QEMU_SECCOMP_SET_SPAWN }, +{ SCMP_SYS(execve),8, QEMU_SECCOMP_SET_SPAWN }, }; @@ -100,6 +104,14 @@ int seccomp_start(uint32_t seccomp_opts) } break; +case QEMU_SECCOMP_SET_SPAWN: +if (seccomp_opts & QEMU_SECCOMP_SET_SPAWN) { +goto add_syscall; +} else { +continue; +} + +break; default: goto add_syscall; } diff --git a/vl.c b/vl.c index 1d44b05772..8e6b252f8f 100644 --- a/vl.c +++ b/vl.c @@ -280,6 +280,10 @@ static QemuOptsList qemu_sandbox_opts = { .name = "elevateprivileges", .type = QEMU_OPT_STRING, }, +{ +.name = "spawn", +.type = QEMU_OPT_STRING, +}, { /* end of list */ } }, }; @@ -1079,6 +1083,18 @@ static int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp) } } +value = qemu_opt_get(opts, "spawn"); +if (value) { +if (strcmp(value, "deny") == 0) { +seccomp_opts |= QEMU_SECCOMP_SET_SPAWN; +} else if (strcmp(value, "allow") == 0) { +/* default value */ +} else { +error_report("invalid argument for spawn"); +return -1; +} +} + if (seccomp_start(seccomp_opts) < 0) { error_report("failed to install seccomp syscall filter " "in the kernel"); -- 2.13.5
[Qemu-devel] [PATCHv4 2/6] seccomp: add obsolete argument to command line
This patch introduces the argument [,obsolete=allow] to the `-sandbox on' option. It allows Qemu to run safely on old system that still relies on old system calls. Signed-off-by: Eduardo Otubo --- include/sysemu/seccomp.h | 3 ++- qemu-options.hx | 12 ++-- qemu-seccomp.c | 23 ++- vl.c | 22 +- 4 files changed, 55 insertions(+), 5 deletions(-) diff --git a/include/sysemu/seccomp.h b/include/sysemu/seccomp.h index 23b9c3c789..215138a372 100644 --- a/include/sysemu/seccomp.h +++ b/include/sysemu/seccomp.h @@ -16,8 +16,9 @@ #define QEMU_SECCOMP_H #define QEMU_SECCOMP_SET_DEFAULT (1 << 0) +#define QEMU_SECCOMP_SET_OBSOLETE(1 << 1) #include -int seccomp_start(void); +int seccomp_start(uint32_t seccomp_opts); #endif diff --git a/qemu-options.hx b/qemu-options.hx index 9f6e2adfff..72150c6b84 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4017,13 +4017,21 @@ Old param mode (ARM only). ETEXI DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \ -"-sandbox Enable seccomp mode 2 system call filter (default 'off').\n", +"-sandbox on[,obsolete=allow|deny]\n" \ +"Enable seccomp mode 2 system call filter (default 'off').\n" \ +"use 'obsolete' to allow obsolete system calls that are provided\n" \ +"by the kernel, but typically no longer used by modern\n" \ +"C library implementations.\n", QEMU_ARCH_ALL) STEXI -@item -sandbox @var{arg} +@item -sandbox @var{arg}[,obsolete=@var{string}] @findex -sandbox Enable Seccomp mode 2 system call filter. 'on' will enable syscall filtering and 'off' will disable it. The default is 'off'. +@table @option +@item obsolete=@var{string} +Enable Obsolete system calls +@end table ETEXI DEF("readconfig", HAS_ARG, QEMU_OPTION_readconfig, diff --git a/qemu-seccomp.c b/qemu-seccomp.c index 585de42a97..3e3f15cc08 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -56,9 +56,22 @@ static const struct QemuSeccompSyscall blacklist[] = { { SCMP_SYS(tuxcall), 1, QEMU_SECCOMP_SET_DEFAULT }, { SCMP_SYS(ulimit),1, QEMU_SECCOMP_SET_DEFAULT }, { SCMP_SYS(vserver), 1, QEMU_SECCOMP_SET_DEFAULT }, +/* obsolete */ +{ SCMP_SYS(readdir), 2, QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(_sysctl), 2, QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(bdflush), 2, QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(create_module), 2, QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(get_kernel_syms), 2, QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(query_module), 2, QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(sgetmask), 2, QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(ssetmask), 2, QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(sysfs), 2, QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(uselib),2, QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(ustat), 2, QEMU_SECCOMP_SET_OBSOLETE }, }; -int seccomp_start(void) + +int seccomp_start(uint32_t seccomp_opts) { int rc = 0; unsigned int i = 0; @@ -72,6 +85,14 @@ int seccomp_start(void) for (i = 0; i < ARRAY_SIZE(blacklist); i++) { switch (blacklist[i].set) { +case QEMU_SECCOMP_SET_OBSOLETE: +if (!(seccomp_opts & QEMU_SECCOMP_SET_OBSOLETE)) { +goto add_syscall; +} else { +continue; +} + +break; default: goto add_syscall; } diff --git a/vl.c b/vl.c index 305531aba8..ca267f9918 100644 --- a/vl.c +++ b/vl.c @@ -271,6 +271,10 @@ static QemuOptsList qemu_sandbox_opts = { .name = "enable", .type = QEMU_OPT_BOOL, }, +{ +.name = "obsolete", +.type = QEMU_OPT_STRING, +}, { /* end of list */ } }, }; @@ -1032,7 +1036,23 @@ static int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp) { if (qemu_opt_get_bool(opts, "enable", false)) { #ifdef CONFIG_SECCOMP -if (seccomp_start() < 0) { +uint32_t seccomp_opts = 0x0; +const char *value = NULL; + +value = qemu_opt_get(opts, "obsolete"); +if (value) { +if (strcmp(value, "allow") == 0) { +seccomp_opts |= QEMU_SECCOMP_SET_OBSOLETE; +} else if (strcmp(value, "deny")) { +/* this is the default option, this if is here +* to provide a little bit of consistency for +* the command line */ + } else { + error
[Qemu-devel] [PATCHv4 5/6] seccomp: add resourcecontrol argument to command line
This patch adds [,resourcecontrol=deny] to `-sandbox on' option. It blacklists all process affinity and scheduler priority system calls to avoid any bigger of the process. Signed-off-by: Eduardo Otubo --- include/sysemu/seccomp.h | 1 + qemu-options.hx | 9 ++--- qemu-seccomp.c | 19 +++ vl.c | 16 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/include/sysemu/seccomp.h b/include/sysemu/seccomp.h index 3ab5fc4f61..e67c2dc840 100644 --- a/include/sysemu/seccomp.h +++ b/include/sysemu/seccomp.h @@ -19,6 +19,7 @@ #define QEMU_SECCOMP_SET_OBSOLETE(1 << 1) #define QEMU_SECCOMP_SET_PRIVILEGED (1 << 2) #define QEMU_SECCOMP_SET_SPAWN (1 << 3) +#define QEMU_SECCOMP_SET_RESOURCECTL (1 << 4) #include diff --git a/qemu-options.hx b/qemu-options.hx index 2b04b9f170..600614f6e5 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4018,7 +4018,7 @@ ETEXI DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \ "-sandbox on[,obsolete=allow|deny][,elevateprivileges=allow|deny|children]\n" \ -" [,spawn=allow|deny]\n" \ +" [,spawn=allow|deny][,resourcecontrol=allow|deny]\n" \ "Enable seccomp mode 2 system call filter (default 'off').\n" \ "use 'obsolete' to allow obsolete system calls that are provided\n" \ "by the kernel, but typically no longer used by modern\n" \ @@ -4028,10 +4028,11 @@ DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \ "The value 'children' will deny set*uid|gid system calls for\n" \ "main QEMU process but will allow forks and execves to run unprivileged\n" \ "use 'spawn' to avoid QEMU to spawn new threads or processes by\n" \ -" blacklisting *fork and execve\n", +" blacklisting *fork and execve\n" \ +"use 'resourcecontrol' to disable process affinity and schedular priority\n", QEMU_ARCH_ALL) STEXI -@item -sandbox @var{arg}[,obsolete=@var{string}][,elevateprivileges=@var{string}][,spawn=@var{string}] +@item -sandbox @var{arg}[,obsolete=@var{string}][,elevateprivileges=@var{string}][,spawn=@var{string}][,resourcecontrol=@var{string}] @findex -sandbox Enable Seccomp mode 2 system call filter. 'on' will enable syscall filtering and 'off' will disable it. The default is 'off'. @@ -4042,6 +4043,8 @@ Enable Obsolete system calls Disable set*uid|gid system calls @item spawn=@var{string} Disable *fork and execve +@item resourcecontrol=@var{string} +Disable process affinity and schedular priority @end table ETEXI diff --git a/qemu-seccomp.c b/qemu-seccomp.c index 51754ace71..ae787a4312 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -71,6 +71,17 @@ static const struct QemuSeccompSyscall blacklist[] = { { SCMP_SYS(fork), 8, QEMU_SECCOMP_SET_SPAWN }, { SCMP_SYS(vfork), 8, QEMU_SECCOMP_SET_SPAWN }, { SCMP_SYS(execve),8, QEMU_SECCOMP_SET_SPAWN }, +/* resource control */ +{ SCMP_SYS(getpriority), 16, QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(setpriority), 16, QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(sched_setparam),16, QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(sched_getparam),16, QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(sched_setscheduler),16, QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(sched_getscheduler),16, QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(sched_setaffinity), 16, QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(sched_getaffinity), 16, QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(sched_get_priority_max),16, QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(sched_get_priority_min),16, QEMU_SECCOMP_SET_RESOURCECTL }, }; @@ -112,6 +123,14 @@ int seccomp_start(uint32_t seccomp_opts) } break; +case QEMU_SECCOMP_SET_RESOURCECTL: +if (seccomp_opts & QEMU_SECCOMP_SET_RESOURCECTL) { +goto add_syscall; +} else { +continue; +} + +break; default: goto add_syscall; } diff --git a/vl.c b/vl.c index 8e6b252f8f..563e7206ac 100644 --- a/vl.c +++ b/vl.c @@ -284,6 +284,10 @@ static QemuOptsList qemu_sandbox_opts = { .name = "spawn", .type = QEMU_OPT_STRING, }, +{ +.name = "resourcecontrol", +.type = QEMU_OPT_STRING, +}, { /* end of list */ } }, }; @@ -1095,6 +1099,18 @@ static int
[Qemu-devel] [PATCHv4 6/6] seccomp: adding documentation to new seccomp model
Adding new documentation under docs/ to describe every one and each new option added by the refactoring patchset. Signed-off-by: Eduardo Otubo --- docs/seccomp.txt | 31 +++ 1 file changed, 31 insertions(+) create mode 100644 docs/seccomp.txt diff --git a/docs/seccomp.txt b/docs/seccomp.txt new file mode 100644 index 00..a5eca85a9b --- /dev/null +++ b/docs/seccomp.txt @@ -0,0 +1,31 @@ +QEMU Seccomp system call filter +=== + +Starting from QEMU version 2.11, the seccomp filter does not work as a +whitelist but as a blacklist instead. This method allows safer deploys since +only the strictly forbidden system calls will be black-listed and the +possibility of breaking any workload is close to zero. + +The default option (-sandbox on) has a slightly looser security though and the +reason is that it shouldn't break any backwards compatibility with previous +deploys and command lines already running. But if the intent is to have a +better security from this version on, one should make use of the following +additional options properly: + +* obsolete=allow|deny: It allows Qemu to run safely on old system that still + relies on old system calls. + +* elevateprivileges=allow|deny|children: It allows or denies Qemu process + to elevate its privileges by blacklisting all set*uid|gid system calls. The + 'children' option sets the PR_SET_NO_NEW_PRIVS to 1 which allows helpers + (forks and execs) to run unprivileged. + +* spawn=allow|deny: It blacklists fork and execve system calls, avoiding QEMU to + spawn new threads or processes. + +* resourcecontrol=allow|deny: It blacklists all process affinity and scheduler + priority system calls to avoid that the process can increase its amount of + allowed resource consumption. + +-- +Eduardo Otubo -- 2.13.5
[Qemu-devel] [PATCH] dma/i82374: avoid double creation of i82374 device
When used with the following command line: ./ppc64-softmmu/qemu-system-ppc64 -S -machine 40p,accel=tcg -device i82374 QEMU with machine type 40p already creates the device i82374. If specified in the command line, it will try to create it again, hence generating the error. One way to avoid this problem is to set user_creatable=false. Signed-off-by: Eduardo Otubo --- hw/dma/i82374.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/dma/i82374.c b/hw/dma/i82374.c index 6c0f975df0..5275d822e0 100644 --- a/hw/dma/i82374.c +++ b/hw/dma/i82374.c @@ -139,6 +139,7 @@ static void i82374_class_init(ObjectClass *klass, void *data) dc->realize = i82374_realize; dc->vmsd = &vmstate_i82374; dc->props = i82374_properties; +dc->user_creatable = false; } static const TypeInfo i82374_info = { -- 2.13.5
[Qemu-devel] [PATCH] isa-fdc: assert replaced by proper error exit
When not available, isa-fdc falls into assert instead of proper error exit. This patch fixes this behavior. Signed-off-by: Eduardo Otubo --- hw/block/fdc.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/hw/block/fdc.c b/hw/block/fdc.c index 401129073b..0b6def4e1d 100644 --- a/hw/block/fdc.c +++ b/hw/block/fdc.c @@ -2699,11 +2699,15 @@ static void isabus_fdc_realize(DeviceState *dev, Error **errp) fdctrl->dma_chann = isa->dma; if (fdctrl->dma_chann != -1) { fdctrl->dma = isa_get_dma(isa_bus_from_device(isadev), isa->dma); -assert(fdctrl->dma); +if (!fdctrl->dma) { +error_setg(errp, "isa-fdc not supported"); +goto error; +} } qdev_set_legacy_instance_id(dev, isa->iobase, 2); fdctrl_realize_common(dev, fdctrl, &err); +error: if (err != NULL) { error_propagate(errp, err); return; -- 2.13.5
[Qemu-devel] [PATCH 2/6] seccomp: add obsolete argument to command line
This patch introduces the argument [,obsolete=allow] to the `-sandbox on' option. It allows Qemu to run safely on old system that still relies on old system calls. Signed-off-by: Eduardo Otubo --- include/sysemu/seccomp.h | 4 +++- qemu-options.hx | 9 +++-- qemu-seccomp.c | 32 +++- vl.c | 16 +++- 4 files changed, 56 insertions(+), 5 deletions(-) diff --git a/include/sysemu/seccomp.h b/include/sysemu/seccomp.h index cfc06008cb..7a7bde246b 100644 --- a/include/sysemu/seccomp.h +++ b/include/sysemu/seccomp.h @@ -15,7 +15,9 @@ #ifndef QEMU_SECCOMP_H #define QEMU_SECCOMP_H +#define OBSOLETE0x0001 + #include -int seccomp_start(void); +int seccomp_start(uint8_t seccomp_opts); #endif diff --git a/qemu-options.hx b/qemu-options.hx index 2cc70b9cfc..c3200f303b 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4004,13 +4004,18 @@ Old param mode (ARM only). ETEXI DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \ -"-sandbox Enable seccomp mode 2 system call filter (default 'off').\n", +"-sandbox on[,obsolete=allow] Enable seccomp mode 2 system call filter (default 'off').\n" \ +" obsolete: Allow obsolete system calls", QEMU_ARCH_ALL) STEXI -@item -sandbox @var{arg} +@item -sandbox @var{arg}[,obsolete=@var{string}] @findex -sandbox Enable Seccomp mode 2 system call filter. 'on' will enable syscall filtering and 'off' will disable it. The default is 'off'. +@table @option +@item obsolete=@var{string} +Enable Obsolete system calls +@end table ETEXI DEF("readconfig", HAS_ARG, QEMU_OPTION_readconfig, diff --git a/qemu-seccomp.c b/qemu-seccomp.c index f8877b07b5..c6a8b28260 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -31,6 +31,20 @@ struct QemuSeccompSyscall { uint8_t priority; }; +static const struct QemuSeccompSyscall obsolete[] = { +{ SCMP_SYS(readdir), 255 }, +{ SCMP_SYS(_sysctl), 255 }, +{ SCMP_SYS(bdflush), 255 }, +{ SCMP_SYS(create_module), 255 }, +{ SCMP_SYS(get_kernel_syms), 255 }, +{ SCMP_SYS(query_module), 255 }, +{ SCMP_SYS(sgetmask), 255 }, +{ SCMP_SYS(ssetmask), 255 }, +{ SCMP_SYS(sysfs), 255 }, +{ SCMP_SYS(uselib), 255 }, +{ SCMP_SYS(ustat), 255 }, +}; + static const struct QemuSeccompSyscall blacklist[] = { { SCMP_SYS(reboot), 255 }, { SCMP_SYS(swapon), 255 }, @@ -56,7 +70,20 @@ static const struct QemuSeccompSyscall blacklist[] = { { SCMP_SYS(vserver), 255 }, }; -int seccomp_start(void) +static int is_obsolete(int syscall) +{ +unsigned int i = 0; + +for (i = 0; i < ARRAY_SIZE(obsolete); i++) { +if (syscall == obsolete[i].num) { +return 1; +} +} + +return 0; +} + +int seccomp_start(uint8_t seccomp_opts) { int rc = 0; unsigned int i = 0; @@ -69,6 +96,9 @@ int seccomp_start(void) } for (i = 0; i < ARRAY_SIZE(blacklist); i++) { +if ((seccomp_opts & OBSOLETE) && is_obsolete(blacklist[i].num)) { +continue; +} rc = seccomp_rule_add(ctx, SCMP_ACT_KILL, blacklist[i].num, 0); if (rc < 0) { goto seccomp_return; diff --git a/vl.c b/vl.c index 838ad3b11a..6a297851aa 100644 --- a/vl.c +++ b/vl.c @@ -271,6 +271,10 @@ static QemuOptsList qemu_sandbox_opts = { .name = "enable", .type = QEMU_OPT_BOOL, }, +{ +.name = "obsolete", +.type = QEMU_OPT_STRING, +}, { /* end of list */ } }, }; @@ -1032,7 +1036,17 @@ static int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp) { if (qemu_opt_get_bool(opts, "enable", false)) { #ifdef CONFIG_SECCOMP -if (seccomp_start() < 0) { +uint8_t seccomp_opts = 0x; +const char * value = NULL; + +value = qemu_opt_get(opts,"obsolete"); +if (value) { +if (strcmp(value, "allow") == 0) { +seccomp_opts |= OBSOLETE; +} +} + +if (seccomp_start(seccomp_opts) < 0) { error_report("failed to install seccomp syscall filter " "in the kernel"); return -1; -- 2.13.0
[Qemu-devel] [PATCH 4/6] seccomp: add spawn argument to command line
This patch adds [,spawn=deny] argument to `-sandbox on' option. It blacklists fork and execve system calls, avoiding Qemu to spawn new threads or processes. Signed-off-by: Eduardo Otubo --- include/sysemu/seccomp.h | 1 + qemu-options.hx | 5 - qemu-seccomp.c | 19 +++ vl.c | 11 +++ 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/include/sysemu/seccomp.h b/include/sysemu/seccomp.h index e6e78d85ce..f1614d6514 100644 --- a/include/sysemu/seccomp.h +++ b/include/sysemu/seccomp.h @@ -17,6 +17,7 @@ #define OBSOLETE0x0001 #define PRIVILEGED 0x0010 +#define SPAWN 0x0100 #include diff --git a/qemu-options.hx b/qemu-options.hx index 6dc776aae3..611a501684 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4004,10 +4004,11 @@ Old param mode (ARM only). ETEXI DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \ -"-sandbox on[,obsolete=allow][,elevateprivileges=allow|deny|children]\n" \ +"-sandbox on[,obsolete=allow][,elevateprivileges=allow|deny|children][,spawn=deny]\n" \ " Enable seccomp mode 2 system call filter (default 'off').\n" \ " obsolete: Allow obsolete system calls\n" \ " elevateprivileges: allows or denies Qemu process to elevate its privileges by blacklisting all set*uid|gid system calls. 'children' will deny set*uid|gid system calls for main Qemu process but will allow forks and execves to run unprivileged", +" spawn: avoids Qemu to spawn new threads or processes by blacklisting *fork and execve\n" QEMU_ARCH_ALL) STEXI @item -sandbox @var{arg}[,obsolete=@var{string}] @@ -4019,6 +4020,8 @@ disable it. The default is 'off'. Enable Obsolete system calls @item elevateprivileges=@var{string} Disable set*uid|gid systema calls +@item spawn=@var{string} +Disable *fork and execve @end table ETEXI diff --git a/qemu-seccomp.c b/qemu-seccomp.c index c204cef9ee..075d87e27f 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -31,6 +31,12 @@ struct QemuSeccompSyscall { uint8_t priority; }; +static const struct QemuSeccompSyscall spawn_syscalls[] = { +{ SCMP_SYS(fork), 255 }, +{ SCMP_SYS(vfork), 255 }, +{ SCMP_SYS(execve), 255 }, +}; + static const struct QemuSeccompSyscall privileged_syscalls[] = { { SCMP_SYS(setuid), 255 }, { SCMP_SYS(setgid), 255 }, @@ -138,6 +144,19 @@ int seccomp_start(uint8_t seccomp_opts) } } +if (seccomp_opts & SPAWN) { +for (i = 0; i < ARRAY_SIZE(spawn_syscalls); i++) { +rc = seccomp_rule_add(ctx, SCMP_ACT_KILL, spawn_syscalls[i].num, 0); +if (rc < 0) { +goto seccomp_return; +} +rc = seccomp_syscall_priority(ctx, spawn_syscalls[i].num, + spawn_syscalls[i].priority); +if (rc < 0) { +goto seccomp_return; +} +} +} rc = seccomp_load(ctx); diff --git a/vl.c b/vl.c index 0b857083a3..456a518431 100644 --- a/vl.c +++ b/vl.c @@ -279,6 +279,10 @@ static QemuOptsList qemu_sandbox_opts = { .name = "elevateprivileges", .type = QEMU_OPT_STRING, }, +{ +.name = "spawn", +.type = QEMU_OPT_STRING, +}, { /* end of list */ } }, }; @@ -1064,6 +1068,13 @@ static int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp) } } +value = qemu_opt_get(opts,"spawn"); +if (value) { +if (strcmp(value, "deny") == 0) { +seccomp_opts |= SPAWN; +} +} + if (seccomp_start(seccomp_opts) < 0) { error_report("failed to install seccomp syscall filter " "in the kernel"); -- 2.13.0
[Qemu-devel] [PATCH 5/6] seccomp: add resourcecontrol argument to command line
This patch adds [,resourcecontrol=deny] to `-sandbox on' option. It blacklists all process affinity and scheduler priority system calls to avoid any bigger of the process. Signed-off-by: Eduardo Otubo --- include/sysemu/seccomp.h | 1 + qemu-options.hx | 5 - qemu-seccomp.c | 27 +++ vl.c | 11 +++ 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/include/sysemu/seccomp.h b/include/sysemu/seccomp.h index f1614d6514..c7003dd197 100644 --- a/include/sysemu/seccomp.h +++ b/include/sysemu/seccomp.h @@ -18,6 +18,7 @@ #define OBSOLETE0x0001 #define PRIVILEGED 0x0010 #define SPAWN 0x0100 +#define RESOURCECTL 0x1000 #include diff --git a/qemu-options.hx b/qemu-options.hx index 611a501684..77b437a052 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4004,11 +4004,12 @@ Old param mode (ARM only). ETEXI DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \ -"-sandbox on[,obsolete=allow][,elevateprivileges=allow|deny|children][,spawn=deny]\n" \ +"-sandbox on[,obsolete=allow][,elevateprivileges=allow|deny|children][,spawn=deny][,resourcecontrol=deny]\n" \ " Enable seccomp mode 2 system call filter (default 'off').\n" \ " obsolete: Allow obsolete system calls\n" \ " elevateprivileges: allows or denies Qemu process to elevate its privileges by blacklisting all set*uid|gid system calls. 'children' will deny set*uid|gid system calls for main Qemu process but will allow forks and execves to run unprivileged", " spawn: avoids Qemu to spawn new threads or processes by blacklisting *fork and execve\n" +" resourcecontrol: disable process affinity and schedular priority\n", QEMU_ARCH_ALL) STEXI @item -sandbox @var{arg}[,obsolete=@var{string}] @@ -4022,6 +4023,8 @@ Enable Obsolete system calls Disable set*uid|gid systema calls @item spawn=@var{string} Disable *fork and execve +@item resourcecontrol=@var{string} +Disable process affinity and schedular priority @end table ETEXI diff --git a/qemu-seccomp.c b/qemu-seccomp.c index 075d87e27f..a9a35456e9 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -31,6 +31,19 @@ struct QemuSeccompSyscall { uint8_t priority; }; +static const struct QemuSeccompSyscall resourcecontrol_syscalls[] = { +{ SCMP_SYS(getpriority), 255 }, +{ SCMP_SYS(setpriority), 255 }, +{ SCMP_SYS(sched_setparam), 255 }, +{ SCMP_SYS(sched_getparam), 255 }, +{ SCMP_SYS(sched_setscheduler), 255 }, +{ SCMP_SYS(sched_getscheduler), 255 }, +{ SCMP_SYS(sched_setaffinity), 255 }, +{ SCMP_SYS(sched_getaffinity), 255 }, +{ SCMP_SYS(sched_get_priority_max), 255 }, +{ SCMP_SYS(sched_get_priority_min), 255 }, +}; + static const struct QemuSeccompSyscall spawn_syscalls[] = { { SCMP_SYS(fork), 255 }, { SCMP_SYS(vfork), 255 }, @@ -158,6 +171,20 @@ int seccomp_start(uint8_t seccomp_opts) } } +if (seccomp_opts & RESOURCECTL) { +for (i = 0; i < ARRAY_SIZE(resourcecontrol_syscalls); i++) { +rc = seccomp_rule_add(ctx, SCMP_ACT_KILL, resourcecontrol_syscalls[i].num, 0); +if (rc < 0) { +goto seccomp_return; +} +rc = seccomp_syscall_priority(ctx, resourcecontrol_syscalls[i].num, + resourcecontrol_syscalls[i].priority); +if (rc < 0) { +goto seccomp_return; +} +} +} + rc = seccomp_load(ctx); seccomp_return: diff --git a/vl.c b/vl.c index 456a518431..8e92052603 100644 --- a/vl.c +++ b/vl.c @@ -283,6 +283,10 @@ static QemuOptsList qemu_sandbox_opts = { .name = "spawn", .type = QEMU_OPT_STRING, }, +{ +.name = "resourcecontrol", +.type = QEMU_OPT_STRING, +}, { /* end of list */ } }, }; @@ -1075,6 +1079,13 @@ static int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp) } } +value = qemu_opt_get(opts,"resourcecontrol"); +if (value) { +if (strcmp(value, "deny") == 0) { +seccomp_opts |= RESOURCECTL; +} +} + if (seccomp_start(seccomp_opts) < 0) { error_report("failed to install seccomp syscall filter " "in the kernel"); -- 2.13.0
[Qemu-devel] [PATCH 0/6] seccomp: feature refactoring
v2: * The semantics of the options "allow/deny" instead of booleans "on/off" remains. * Added option 'children' to elevateprivileges * Added documentation to docs/ v1: * First version based on the discussion https://lists.gnu.org/archive/html/qemu-devel/2017-02/msg03348.html Eduardo Otubo (6): seccomp: changing from whitelist to blacklist seccomp: add obsolete argument to command line seccomp: add elevateprivileges argument to command line seccomp: add spawn argument to command line seccomp: add resourcecontrol argument to command line seccomp: adding documentation to new seccomp model docs/seccomp.txt | 31 include/sysemu/seccomp.h | 7 +- qemu-options.hx | 19 ++- qemu-seccomp.c | 363 +-- vl.c | 63 +++- 5 files changed, 248 insertions(+), 235 deletions(-) create mode 100644 docs/seccomp.txt -- 2.13.0
[Qemu-devel] [PATCH 1/6] seccomp: changing from whitelist to blacklist
This patch changes the default behavior of the seccomp filter from whitelist to blacklist. By default now all system calls are allowed and a small black list of definitely forbidden ones was created. Signed-off-by: Eduardo Otubo --- qemu-seccomp.c | 256 +++-- vl.c | 7 +- 2 files changed, 33 insertions(+), 230 deletions(-) diff --git a/qemu-seccomp.c b/qemu-seccomp.c index df75d9c471..f8877b07b5 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -31,229 +31,29 @@ struct QemuSeccompSyscall { 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(socketcall), 250 }, -{ SCMP_SYS(read), 249 }, -{ SCMP_SYS(io_submit), 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(socket), 245 }, -{ SCMP_SYS(setsockopt), 245 }, -{ SCMP_SYS(recvmsg), 245 }, -{ SCMP_SYS(sendmsg), 245 }, -{ SCMP_SYS(accept), 245 }, -{ SCMP_SYS(connect), 245 }, -{ SCMP_SYS(socketpair), 245 }, -{ SCMP_SYS(bind), 245 }, -{ SCMP_SYS(listen), 245 }, -{ SCMP_SYS(semget), 245 }, -{ SCMP_SYS(ipc), 245 }, -{ SCMP_SYS(gettimeofday), 245 }, -{ SCMP_SYS(readlink), 245 }, -{ SCMP_SYS(access), 245 }, -{ SCMP_SYS(prctl), 245 }, -{ SCMP_SYS(signalfd), 245 }, -{ SCMP_SYS(getrlimit), 245 }, -{ SCMP_SYS(getrusage), 245 }, -{ SCMP_SYS(set_tid_address), 245 }, -{ SCMP_SYS(statfs), 245 }, -{ SCMP_SYS(unlink), 245 }, -{ SCMP_SYS(wait4), 245 }, -{ SCMP_SYS(fcntl64), 245 }, -{ SCMP_SYS(fstat64), 245 }, -{ SCMP_SYS(stat64), 245 }, -{ SCMP_SYS(getgid32), 245 }, -{ SCMP_SYS(getegid32), 245 }, -{ SCMP_SYS(getuid32), 245 }, -{ SCMP_SYS(geteuid32), 245 }, -{ SCMP_SYS(sigreturn), 245 }, -{ SCMP_SYS(_newselect), 245 }, -{ SCMP_SYS(_llseek), 245 }, -{ SCMP_SYS(mmap2), 245 }, -{ SCMP_SYS(sigprocmask), 245 }, -{ SCMP_SYS(sched_getparam), 245 }, -{ SCMP_SYS(sched_getscheduler), 245 }, -{ SCMP_SYS(fstat), 245 }, -{ SCMP_SYS(clock_getres), 245 }, -{ SCMP_SYS(sched_get_priority_min), 245 }, -{ SCMP_SYS(sched_get_priority_max), 245 }, -{ SCMP_SYS(stat), 245 }, -{ SCMP_SYS(uname), 245 }, -{ SCMP_SYS(eventfd2), 245 }, -{ SCMP_SYS(io_getevents), 245 }, -{ SCMP_SYS(dup), 245 }, -{ SCMP_SYS(dup2), 245 }, -{ SCMP_SYS(dup3), 245 }, -{ SCMP_SYS(gettid), 245 }, -{ SCMP_SYS(getgid), 245 }, -{ SCMP_SYS(getegid), 245 }, -{ SCMP_SYS(getuid), 245 }, -{ SCMP_SYS(geteuid), 245 }, -{ SCMP_SYS(timer_create), 245 }, -{ SCMP_SYS(times), 245 }, -{ SCMP_SYS(exit), 245 }, -{ SCMP_SYS(clock_gettime), 245 }, -{ SCMP_SYS(time), 245 }, -{ SCMP_SYS(restart_syscall), 245 }, -{ SCMP_SYS(pwrite64), 245 }, -{ SCMP_SYS(nanosleep), 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(rt_sigreturn), 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(pselect6), 245 }, -{ SCMP_SYS(fork), 245 }, -{ SCMP_SYS(rt_sigprocmask), 245 }, -{ SCMP_SYS(write), 244 }, -{ SCMP_SYS(fcntl), 243 }, -{ SCMP_SYS(tgkill), 242 }, -{ SCMP_SYS(kill), 242 }, -{ SCMP_SYS(rt_sigaction), 242 }, -{ SCMP_SYS(pipe2), 242 }, -{ SCMP_SYS(munmap), 242 }, -{ SCMP_SYS(mremap), 242 }, -{ SCMP_SYS(fdatasync), 242 }, -{ SCMP_SYS(close), 242 }, -{ SCMP_SYS(rt_sigpending), 242 }, -{ SCMP_SYS(rt_sigtimedwait), 242 }, -{ SCMP_SYS(readv), 242 }, -{ SCMP_SYS(writev), 242 }, -{ SCMP_SYS(preadv), 242 }, -{ SCMP_SYS(pwritev), 242 }, -{ SCMP_SYS(setrlimit), 242 }, -{ SCMP_SYS(ftruncate), 242 }, -{ SCMP_SYS(lstat), 242 }, -{ SCMP_SYS(pipe), 242 }, -{ SCMP_SYS(umask), 242 }, -{ SCMP_SYS(chdir), 242 }, -{ SCMP_SYS(setitimer), 242 }, -{ SCMP_SYS(setsid), 242 }, -{ SCMP_SYS(poll), 242 }, -{ SCMP_SYS(epoll_create), 242 }, -{ SCMP_SYS(epoll_ctl), 242 }, -{ SCMP_SYS(epoll_wait), 242 }, -{ SCMP_SYS(waitpid), 242 }, -{ SCMP_SYS(getsockname), 242 }, -{ SCMP_SYS(getpeername), 242 }, -{ SCMP_SYS(accept4), 242 }, -{ SCMP_SYS(timerfd_settime), 242 }, -{ SCMP_SYS(newfstatat), 241 }, -{ SCMP_SYS(shutdown), 241 }, -{ SCMP_SYS(getsockopt), 241 }, -{ SCMP_SYS(semop), 241 }, -{ SCMP_SYS(semtimedop), 241
[Qemu-devel] [PATCH 3/6] seccomp: add elevateprivileges argument to command line
This patch introduces the new argument [,elevateprivileges=allow|deny|children] to the `-sandbox on'. It allows or denies Qemu process to elevate its privileges by blacklisting all set*uid|gid system calls. The 'children' option will let forks and execves run unprivileged. Signed-off-by: Eduardo Otubo --- include/sysemu/seccomp.h | 1 + qemu-options.hx | 8 ++-- qemu-seccomp.c | 29 + vl.c | 18 ++ 4 files changed, 54 insertions(+), 2 deletions(-) diff --git a/include/sysemu/seccomp.h b/include/sysemu/seccomp.h index 7a7bde246b..e6e78d85ce 100644 --- a/include/sysemu/seccomp.h +++ b/include/sysemu/seccomp.h @@ -16,6 +16,7 @@ #define QEMU_SECCOMP_H #define OBSOLETE0x0001 +#define PRIVILEGED 0x0010 #include diff --git a/qemu-options.hx b/qemu-options.hx index c3200f303b..6dc776aae3 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4004,8 +4004,10 @@ Old param mode (ARM only). ETEXI DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \ -"-sandbox on[,obsolete=allow] Enable seccomp mode 2 system call filter (default 'off').\n" \ -" obsolete: Allow obsolete system calls", +"-sandbox on[,obsolete=allow][,elevateprivileges=allow|deny|children]\n" \ +" Enable seccomp mode 2 system call filter (default 'off').\n" \ +" obsolete: Allow obsolete system calls\n" \ +" elevateprivileges: allows or denies Qemu process to elevate its privileges by blacklisting all set*uid|gid system calls. 'children' will deny set*uid|gid system calls for main Qemu process but will allow forks and execves to run unprivileged", QEMU_ARCH_ALL) STEXI @item -sandbox @var{arg}[,obsolete=@var{string}] @@ -4015,6 +4017,8 @@ disable it. The default is 'off'. @table @option @item obsolete=@var{string} Enable Obsolete system calls +@item elevateprivileges=@var{string} +Disable set*uid|gid systema calls @end table ETEXI diff --git a/qemu-seccomp.c b/qemu-seccomp.c index c6a8b28260..c204cef9ee 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -31,6 +31,19 @@ struct QemuSeccompSyscall { uint8_t priority; }; +static const struct QemuSeccompSyscall privileged_syscalls[] = { +{ SCMP_SYS(setuid), 255 }, +{ SCMP_SYS(setgid), 255 }, +{ SCMP_SYS(setpgid), 255 }, +{ SCMP_SYS(setsid), 255 }, +{ SCMP_SYS(setreuid), 255 }, +{ SCMP_SYS(setregid), 255 }, +{ SCMP_SYS(setresuid), 255 }, +{ SCMP_SYS(setresgid), 255 }, +{ SCMP_SYS(setfsuid), 255 }, +{ SCMP_SYS(setfsgid), 255 }, +}; + static const struct QemuSeccompSyscall obsolete[] = { { SCMP_SYS(readdir), 255 }, { SCMP_SYS(_sysctl), 255 }, @@ -110,6 +123,22 @@ int seccomp_start(uint8_t seccomp_opts) } } +if (seccomp_opts & PRIVILEGED) { +for (i = 0; i < ARRAY_SIZE(privileged_syscalls); i++) { +rc = seccomp_rule_add(ctx, SCMP_ACT_KILL, + privileged_syscalls[i].num, 0); +if (rc < 0) { +goto seccomp_return; +} +rc = seccomp_syscall_priority(ctx, privileged_syscalls[i].num, +privileged_syscalls[i].priority); +if (rc < 0) { +goto seccomp_return; +} +} +} + + rc = seccomp_load(ctx); seccomp_return: diff --git a/vl.c b/vl.c index 6a297851aa..0b857083a3 100644 --- a/vl.c +++ b/vl.c @@ -275,6 +275,10 @@ static QemuOptsList qemu_sandbox_opts = { .name = "obsolete", .type = QEMU_OPT_STRING, }, +{ +.name = "elevateprivileges", +.type = QEMU_OPT_STRING, +}, { /* end of list */ } }, }; @@ -1046,6 +1050,20 @@ static int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp) } } +value = qemu_opt_get(opts,"elevateprivileges"); +if (value) { +if (strcmp(value, "deny") == 0) { +seccomp_opts |= PRIVILEGED; +} +if (strcmp(value, "children") == 0) { +seccomp_opts |= PRIVILEGED; + + /* calling prctl directly because we're +* not sure if host has CAP_SYS_ADMIN set*/ + prctl(PR_SET_NO_NEW_PRIVS, 1); + } +} + if (seccomp_start(seccomp_opts) < 0) { error_report("failed to install seccomp syscall filter " "in the kernel"); -- 2.13.0
[Qemu-devel] [PATCH 6/6] seccomp: adding documentation to new seccomp model
Adding new documention under docs/ to describe every one and each new option added by the refactoring patchset. Signed-off-by: Eduardo Otubo --- docs/seccomp.txt | 31 +++ 1 file changed, 31 insertions(+) create mode 100644 docs/seccomp.txt diff --git a/docs/seccomp.txt b/docs/seccomp.txt new file mode 100644 index 00..4b7edba312 --- /dev/null +++ b/docs/seccomp.txt @@ -0,0 +1,31 @@ +QEMU Seccomp system call filter +=== + +Starting from Qemu version 2.10, the seccomp filter does not work as a +whitelist but as a blacklist instead. This method allows safer deploys since +only the strictly forbidden system calls will be black-listed and the +possibility of breaking any workload is close to zero. + +The default option (-sandbox on) has a slightly looser security though and the +reason is that it shouldn't break any backwards compatibility with previous +deploys and command lines already running. But if the intent is to have a +better security from this version on, one should make use of the following +additional options properly: + +* [,obsolete=allow]: It allows Qemu to run safely on old system that still + relies on old system calls. + +* [,elevateprivileges=deny|allow|children]: It allows or denies Qemu process + to elevate its privileges by blacklisting all set*uid|gid system calls. The + 'children' option sets the PR_SET_NO_NEW_PRIVS to 1 which allows helpers + (forls and execs) to run unprivileged. + +* [,spawn=deny]: It blacklists fork and execve syste calls, avoiding Qemu to + spawn new threads or processes. + +* [,resourcecontrol=deny]: It blacklists all process affinity and scheduler + priority system calls to avoid any bigger of the process. + + +-- +Eduardo Otubo -- 2.13.0
Re: [Qemu-devel] [Qemu-trivial] [PATCH] filter-mirror: segfault when specifying non existent device
On Tue, Aug 22, 2017 at 09:19:20AM +0800, Zhang Chen wrote: > > > On 08/21/2017 11:50 PM, Eduardo Otubo wrote: > > When using filter-mirror like the example below where the interface > > 'ndev0' does not exist on the host, QEMU crashes into segmentation > > fault. > > > > $ qemu-system-x86_64 -S -machine pc -netdev user,id=ndev0 -object > > filter-mirror,id=test-object,netdev=ndev0 > > > > This happens because the function filter_mirror_setup() does not checks > > if the device actually exists and still keep on processing calling > > qemu_chr_find(). This patch fixes this issue. > > > > Signed-off-by: Eduardo Otubo > > Looks good for me. > > Reviewed-by: Zhang Chen Ping. > > Thanks > Zhang Chen > > > --- > > net/filter-mirror.c | 14 +++--- > > 1 file changed, 11 insertions(+), 3 deletions(-) > > > > diff --git a/net/filter-mirror.c b/net/filter-mirror.c > > index 90e2c92337..e18a4b16a0 100644 > > --- a/net/filter-mirror.c > > +++ b/net/filter-mirror.c > > @@ -213,14 +213,22 @@ static void filter_mirror_setup(NetFilterState *nf, > > Error **errp) > > MirrorState *s = FILTER_MIRROR(nf); > > Chardev *chr; > > +if (s->outdev == NULL) { > > +goto err; > > +} > > + > > chr = qemu_chr_find(s->outdev); > > + > > if (chr == NULL) { > > -error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, > > - "Device '%s' not found", s->outdev); > > -return; > > +goto err; > > } > > qemu_chr_fe_init(&s->chr_out, chr, errp); > > + > > +err: > > +error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, "Device '%s' not found", > > + nf->netdev_id); > > +return; > > } > > static void redirector_rs_finalize(SocketReadState *rs) > > -- > Thanks > Zhang Chen > > > > -- Eduardo Otubo Senior Software Engineer @ RedHat
Re: [Qemu-devel] [Qemu-trivial] [PATCH] dma/i82374: avoid double creation of i82374 device
On Fri, Sep 01, 2017 at 12:44:30PM -0300, Eduardo Habkost wrote: > On Fri, Sep 01, 2017 at 05:34:34PM +0200, Markus Armbruster wrote: > > Eduardo Habkost writes: > > > > > i82374 is compiled in only on ppc and sh4, so I'm CCing the > > > maintainers for those architectures. > > > > > > On Fri, Sep 01, 2017 at 01:03:32PM +0200, Eduardo Otubo wrote: > > >> When used with the following command line: > > >> > > >> ./ppc64-softmmu/qemu-system-ppc64 -S -machine 40p,accel=tcg -device > > >> i82374 > > >> > > >> QEMU with machine type 40p already creates the device i82374. If > > >> specified in the command line, it will try to create it again, hence > > >> generating the error. Well pointed, forgot to describe the actual error. I may inlcude for the next version of the patch. For for correctness sake, here it is: ./ppc64-softmmu/qemu-system-ppc64 -S -machine 40p,accel=tcg -device i82374 qemu-system-ppc64: hw/isa/isa-bus.c:110: isa_bus_dma: Assertion `!bus->dma[0] && !bus->dma[1]' failed. Aborted (core dumped) > > > > > > Which error? > > > > > > > > >> One way to avoid this problem is to set > > >> user_creatable=false. > > >> > > >> Signed-off-by: Eduardo Otubo > > > > > > The patch does more than just avoiding double creation: it > > > prevents usage of "-device i82374" completely. > > > > > > Maybe nobody needs it to work with -device today (would the > > > device even work?) and it is OK to set user_creatable=false until > > > we fix the crash. But we need to be sure of that. > > > > > >> --- > > >> hw/dma/i82374.c | 1 + > > >> 1 file changed, 1 insertion(+) > > >> > > >> diff --git a/hw/dma/i82374.c b/hw/dma/i82374.c > > >> index 6c0f975df0..5275d822e0 100644 > > >> --- a/hw/dma/i82374.c > > >> +++ b/hw/dma/i82374.c > > >> @@ -139,6 +139,7 @@ static void i82374_class_init(ObjectClass *klass, > > >> void *data) > > >> dc->realize = i82374_realize; > > >> dc->vmsd = &vmstate_i82374; > > >> dc->props = i82374_properties; > > >> +dc->user_creatable = false; > > > > > > A "Reason:" comment explaining why user_creatable=false is > > > mandatory. See the comment above user_creatable declaration in > > > qdev-core.h for reference. > > > > > > I suggest the following: > > > > > > /* > > > * Reason: i82374_realize() crashes (assertion failure inside > > > isa_bus_dma() > > > * if the device is instantiated twice. > > > */ I agree with the comment above. If there's nothing left to fix/add I'll just send a v2 for this shortly. > > > > We need to find out *why* it crashes. Once we know, we can likely write > > a better comment. > > It crashes because isa_bus_dma() isn't supposed to be called > twice for the same bus. > > Making isa_bus_dma()/DMA_init()/i82374_realize() return an error > instead of asserting would be even better than setting > user_creatable=false. > > -- > Eduardo > -- Eduardo Otubo Senior Software Engineer @ RedHat
Re: [Qemu-devel] [Qemu-trivial] [PATCH] dma/i82374: avoid double creation of i82374 device
On Sat, Sep 02, 2017 at 11:15:20AM +0200, Aurelien Jarno wrote: > On 2017-09-01 11:30, Eduardo Habkost wrote: > > i82374 is compiled in only on ppc and sh4, so I'm CCing the > > maintainers for those architectures. > > The i82374 device is not useful nor usable on SH4. It has just been > added in commit 85d3846a39 to be able to run the tests. > > Aurelien > Any word from the ppc guys? -- Eduardo Otubo Senior Software Engineer @ RedHat
Re: [Qemu-devel] [PATCHv4 2/6] seccomp: add obsolete argument to command line
On Fri, Sep 01, 2017 at 12:05:41PM +0100, Daniel P. Berrange wrote: > On Fri, Sep 01, 2017 at 12:58:14PM +0200, Eduardo Otubo wrote: > > This patch introduces the argument [,obsolete=allow] to the `-sandbox on' > > option. It allows Qemu to run safely on old system that still relies on > > old system calls. > > > > Signed-off-by: Eduardo Otubo > > --- > > include/sysemu/seccomp.h | 3 ++- > > qemu-options.hx | 12 ++-- > > qemu-seccomp.c | 23 ++- > > vl.c | 22 +- > > 4 files changed, 55 insertions(+), 5 deletions(-) > > > > > @@ -72,6 +85,14 @@ int seccomp_start(void) > > > > for (i = 0; i < ARRAY_SIZE(blacklist); i++) { > > switch (blacklist[i].set) { > > +case QEMU_SECCOMP_SET_OBSOLETE: > > +if (!(seccomp_opts & QEMU_SECCOMP_SET_OBSOLETE)) { > > +goto add_syscall; > > +} else { > > +continue; > > +} > > + > > +break; > > THis can be simplified: > > if ((seccomp_opts & QEMU_SECCOMP_SET_OBSOLETE)) { > continue; > } > > break; > > thus avoiding need to 'goto' > > Likewise for all following patches Do you think there's anything else to fix on this series? if nothing else emerges, I'll send the v5 tomorrow (also with the style fixes). -- Eduardo Otubo Senior Software Engineer @ RedHat
Re: [Qemu-devel] [Qemu-trivial] [PATCH] dma/i82374: avoid double creation of i82374 device
On Thu, Sep 07, 2017 at 06:05:37PM +0200, Paolo Bonzini wrote: > Il 02 set 2017 11:17 AM, "Aurelien Jarno" ha scritto: > > On 2017-09-01 11:30, Eduardo Habkost wrote: > > i82374 is compiled in only on ppc and sh4, so I'm CCing the > > maintainers for those architectures. > > The i82374 device is not useful nor usable on SH4. It has just been > added in commit 85d3846a39 to be able to run the tests. > > > But that means that the patch is wrong and probably was not tested with > "make check". > > Eduardo's proposal is the right one. > Great, I'll just add the missing details and resend the v2. Thanks for the review. Regards, -- Eduardo Otubo Senior Software Engineer @ RedHat
Re: [Qemu-devel] [PATCH] buildsys: Move seccomp cflags/libs to per object
On Thu, Sep 07, 2017 at 04:53:16PM +0800, Fam Zheng wrote: > Like many other libraries, libseccomp cflags and libs should only apply > to the building of necessary objects. Do so in the usual way with the > help of per object variables. > > Signed-off-by: Fam Zheng I'll include in the next pull request. Thanks for the patch. Acked-by: Eduardo Otubo > --- > Makefile.objs | 2 ++ > configure | 6 -- > 2 files changed, 6 insertions(+), 2 deletions(-) > > diff --git a/Makefile.objs b/Makefile.objs > index 24a4ea08b8..d9cf7ad791 100644 > --- a/Makefile.objs > +++ b/Makefile.objs > @@ -70,6 +70,8 @@ common-obj-y += backends/ > common-obj-y += chardev/ > > common-obj-$(CONFIG_SECCOMP) += qemu-seccomp.o > +qemu-seccomp.o-cflags := $(SECCOMP_CFLAGS) > +qemu-seccomp.o-libs := $(SECCOMP_LIBS) > > common-obj-$(CONFIG_FDT) += device_tree.o > > diff --git a/configure b/configure > index fb7e34a901..fb81a0189b 100755 > --- a/configure > +++ b/configure > @@ -2052,8 +2052,8 @@ if test "$seccomp" != "no" ; then > > if test "$libseccomp_minver" != "" && > $pkg_config --atleast-version=$libseccomp_minver libseccomp ; then > -libs_softmmu="$libs_softmmu $($pkg_config --libs libseccomp)" > -QEMU_CFLAGS="$QEMU_CFLAGS $($pkg_config --cflags libseccomp)" > +seccomp_cflags="$($pkg_config --cflags libseccomp)" > +seccomp_libs="$($pkg_config --libs libseccomp)" > seccomp="yes" > else > if test "$seccomp" = "yes" ; then > @@ -5875,6 +5875,8 @@ fi > > if test "$seccomp" = "yes"; then >echo "CONFIG_SECCOMP=y" >> $config_host_mak > + echo "SECCOMP_CFLAGS=$seccomp_cflags" >> $config_host_mak > + echo "SECCOMP_LIBS=$seccomp_libs" >> $config_host_mak > fi > > # XXX: suppress that > -- > 2.13.5 > > -- Eduardo Otubo Senior Software Engineer @ RedHat
[Qemu-devel] [PATCHv5 1/5] seccomp: changing from whitelist to blacklist
This patch changes the default behavior of the seccomp filter from whitelist to blacklist. By default now all system calls are allowed and a small black list of definitely forbidden ones was created. Signed-off-by: Eduardo Otubo --- include/sysemu/seccomp.h | 2 + qemu-seccomp.c | 264 ++- vl.c | 1 - 3 files changed, 35 insertions(+), 232 deletions(-) diff --git a/include/sysemu/seccomp.h b/include/sysemu/seccomp.h index cfc06008cb..23b9c3c789 100644 --- a/include/sysemu/seccomp.h +++ b/include/sysemu/seccomp.h @@ -15,6 +15,8 @@ #ifndef QEMU_SECCOMP_H #define QEMU_SECCOMP_H +#define QEMU_SECCOMP_SET_DEFAULT (1 << 0) + #include int seccomp_start(void); diff --git a/qemu-seccomp.c b/qemu-seccomp.c index df75d9c471..bc9a1f77ff 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -28,232 +28,34 @@ struct QemuSeccompSyscall { int32_t num; -uint8_t priority; +int type; +uint8_t set; }; -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(socketcall), 250 }, -{ SCMP_SYS(read), 249 }, -{ SCMP_SYS(io_submit), 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(socket), 245 }, -{ SCMP_SYS(setsockopt), 245 }, -{ SCMP_SYS(recvmsg), 245 }, -{ SCMP_SYS(sendmsg), 245 }, -{ SCMP_SYS(accept), 245 }, -{ SCMP_SYS(connect), 245 }, -{ SCMP_SYS(socketpair), 245 }, -{ SCMP_SYS(bind), 245 }, -{ SCMP_SYS(listen), 245 }, -{ SCMP_SYS(semget), 245 }, -{ SCMP_SYS(ipc), 245 }, -{ SCMP_SYS(gettimeofday), 245 }, -{ SCMP_SYS(readlink), 245 }, -{ SCMP_SYS(access), 245 }, -{ SCMP_SYS(prctl), 245 }, -{ SCMP_SYS(signalfd), 245 }, -{ SCMP_SYS(getrlimit), 245 }, -{ SCMP_SYS(getrusage), 245 }, -{ SCMP_SYS(set_tid_address), 245 }, -{ SCMP_SYS(statfs), 245 }, -{ SCMP_SYS(unlink), 245 }, -{ SCMP_SYS(wait4), 245 }, -{ SCMP_SYS(fcntl64), 245 }, -{ SCMP_SYS(fstat64), 245 }, -{ SCMP_SYS(stat64), 245 }, -{ SCMP_SYS(getgid32), 245 }, -{ SCMP_SYS(getegid32), 245 }, -{ SCMP_SYS(getuid32), 245 }, -{ SCMP_SYS(geteuid32), 245 }, -{ SCMP_SYS(sigreturn), 245 }, -{ SCMP_SYS(_newselect), 245 }, -{ SCMP_SYS(_llseek), 245 }, -{ SCMP_SYS(mmap2), 245 }, -{ SCMP_SYS(sigprocmask), 245 }, -{ SCMP_SYS(sched_getparam), 245 }, -{ SCMP_SYS(sched_getscheduler), 245 }, -{ SCMP_SYS(fstat), 245 }, -{ SCMP_SYS(clock_getres), 245 }, -{ SCMP_SYS(sched_get_priority_min), 245 }, -{ SCMP_SYS(sched_get_priority_max), 245 }, -{ SCMP_SYS(stat), 245 }, -{ SCMP_SYS(uname), 245 }, -{ SCMP_SYS(eventfd2), 245 }, -{ SCMP_SYS(io_getevents), 245 }, -{ SCMP_SYS(dup), 245 }, -{ SCMP_SYS(dup2), 245 }, -{ SCMP_SYS(dup3), 245 }, -{ SCMP_SYS(gettid), 245 }, -{ SCMP_SYS(getgid), 245 }, -{ SCMP_SYS(getegid), 245 }, -{ SCMP_SYS(getuid), 245 }, -{ SCMP_SYS(geteuid), 245 }, -{ SCMP_SYS(timer_create), 245 }, -{ SCMP_SYS(times), 245 }, -{ SCMP_SYS(exit), 245 }, -{ SCMP_SYS(clock_gettime), 245 }, -{ SCMP_SYS(time), 245 }, -{ SCMP_SYS(restart_syscall), 245 }, -{ SCMP_SYS(pwrite64), 245 }, -{ SCMP_SYS(nanosleep), 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(rt_sigreturn), 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(pselect6), 245 }, -{ SCMP_SYS(fork), 245 }, -{ SCMP_SYS(rt_sigprocmask), 245 }, -{ SCMP_SYS(write), 244 }, -{ SCMP_SYS(fcntl), 243 }, -{ SCMP_SYS(tgkill), 242 }, -{ SCMP_SYS(kill), 242 }, -{ SCMP_SYS(rt_sigaction), 242 }, -{ SCMP_SYS(pipe2), 242 }, -{ SCMP_SYS(munmap), 242 }, -{ SCMP_SYS(mremap), 242 }, -{ SCMP_SYS(fdatasync), 242 }, -{ SCMP_SYS(close), 242 }, -{ SCMP_SYS(rt_sigpending), 242 }, -{ SCMP_SYS(rt_sigtimedwait), 242 }, -{ SCMP_SYS(readv), 242 }, -{ SCMP_SYS(writev), 242 }, -{ SCMP_SYS(preadv), 242 }, -{ SCMP_SYS(pwritev), 242 }, -{ SCMP_SYS(setrlimit), 242 }, -{ SCMP_SYS(ftruncate), 242 }, -{ SCMP_SYS(lstat), 242 }, -{ SCMP_SYS(pipe), 242 }, -{ SCMP_SYS(umask), 242 }, -{ SCMP_SYS(chdir), 242 }, -{ SCMP_SYS(setitimer), 242 }, -{ SCMP_SYS(setsid), 242 }, -{ SCMP_SYS(poll), 242 }, -{ SCMP_SYS(epoll_create
[Qemu-devel] [PATCHv5 3/5] seccomp: add elevateprivileges argument to command line
This patch introduces the new argument [,elevateprivileges=allow|deny|children] to the `-sandbox on'. It allows or denies Qemu process to elevate its privileges by blacklisting all set*uid|gid system calls. The 'children' option will let forks and execves run unprivileged. Signed-off-by: Eduardo Otubo --- include/sysemu/seccomp.h | 1 + qemu-options.hx | 12 +--- qemu-seccomp.c | 19 +++ vl.c | 27 +++ 4 files changed, 56 insertions(+), 3 deletions(-) diff --git a/include/sysemu/seccomp.h b/include/sysemu/seccomp.h index 215138a372..4a9e63c7cd 100644 --- a/include/sysemu/seccomp.h +++ b/include/sysemu/seccomp.h @@ -17,6 +17,7 @@ #define QEMU_SECCOMP_SET_DEFAULT (1 << 0) #define QEMU_SECCOMP_SET_OBSOLETE(1 << 1) +#define QEMU_SECCOMP_SET_PRIVILEGED (1 << 2) #include diff --git a/qemu-options.hx b/qemu-options.hx index 72150c6b84..5c1b163fb5 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4017,20 +4017,26 @@ Old param mode (ARM only). ETEXI DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \ -"-sandbox on[,obsolete=allow|deny]\n" \ +"-sandbox on[,obsolete=allow|deny][,elevateprivileges=allow|deny|children]\n" \ "Enable seccomp mode 2 system call filter (default 'off').\n" \ "use 'obsolete' to allow obsolete system calls that are provided\n" \ "by the kernel, but typically no longer used by modern\n" \ -"C library implementations.\n", +"C library implementations.\n" \ +"use 'elevateprivileges' to allow or deny QEMU process to elevate\n" \ +"its privileges by blacklisting all set*uid|gid system calls.\n" \ +"The value 'children' will deny set*uid|gid system calls for\n" \ +"main QEMU process but will allow forks and execves to run unprivileged\n", QEMU_ARCH_ALL) STEXI -@item -sandbox @var{arg}[,obsolete=@var{string}] +@item -sandbox @var{arg}[,obsolete=@var{string}][,elevateprivileges=@var{string}] @findex -sandbox Enable Seccomp mode 2 system call filter. 'on' will enable syscall filtering and 'off' will disable it. The default is 'off'. @table @option @item obsolete=@var{string} Enable Obsolete system calls +@item elevateprivileges=@var{string} +Disable set*uid|gid system calls @end table ETEXI diff --git a/qemu-seccomp.c b/qemu-seccomp.c index 126e5ee2d5..2bad16cafb 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -68,6 +68,17 @@ static const struct QemuSeccompSyscall blacklist[] = { { SCMP_SYS(sysfs), 2, QEMU_SECCOMP_SET_OBSOLETE }, { SCMP_SYS(uselib), 2, QEMU_SECCOMP_SET_OBSOLETE }, { SCMP_SYS(ustat), 2, QEMU_SECCOMP_SET_OBSOLETE }, +/* privileged */ +{ SCMP_SYS(setuid), 4, QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setgid), 4, QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setpgid),4, QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setsid), 4, QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setreuid), 4, QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setregid), 4, QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setresuid), 4, QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setresgid), 4, QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setfsuid), 4, QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setfsgid), 4, QEMU_SECCOMP_SET_PRIVILEGED }, }; @@ -90,6 +101,14 @@ int seccomp_start(uint32_t seccomp_opts) continue; } break; +case QEMU_SECCOMP_SET_PRIVILEGED: +if (seccomp_opts & QEMU_SECCOMP_SET_PRIVILEGED) { +break; +} else { +continue; +} + +break; default: break; } diff --git a/vl.c b/vl.c index dafbe30e2b..413cfe8504 100644 --- a/vl.c +++ b/vl.c @@ -29,6 +29,7 @@ #ifdef CONFIG_SECCOMP #include "sysemu/seccomp.h" +#include "sys/prctl.h" #endif #if defined(CONFIG_VDE) @@ -275,6 +276,10 @@ static QemuOptsList qemu_sandbox_opts = { .name = "obsolete", .type = QEMU_OPT_STRING, }, +{ +.name = "elevateprivileges", +.type = QEMU_OPT_STRING, +}, { /* end of list */ } }, }; @@ -1054,6 +1059,28 @@ static int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp) } } +
[Qemu-devel] [PATCHv5 0/6] seccomp: feature refactoring
v5: * replaced strcmp by g_str_equal * removed useless goto * fixed style problems v4: * include another field on the struct for the modes * remove priority * fixed typos * error handling for prctl * add allow|deny values for all options * error hanlding for wrong values for all options * change how binary values are treated * reformat help text v3: * Style problems fixed v2: * The semantics of the options "allow/deny" instead of booleans "on/off" remains. * Added option 'children' to elevateprivileges * Added documentation to docs/ v1: * First version based on the discussion https://lists.gnu.org/archive/html/qemu-devel/2017-02/msg03348.html Eduardo Otubo (6): seccomp: changing from whitelist to blacklist seccomp: add obsolete argument to command line seccomp: add elevateprivileges argument to command line seccomp: add spawn argument to command line seccomp: add resourcecontrol argument to command line seccomp: adding documentation to new seccomp model docs/seccomp.txt | 31 + include/sysemu/seccomp.h | 8 +- qemu-options.hx | 26 +++- qemu-seccomp.c | 325 ++- vl.c | 82 +++- 5 files changed, 235 insertions(+), 237 deletions(-) create mode 100644 docs/seccomp.txt -- 2.13.5
[Qemu-devel] [PATCHv5 2/5] seccomp: add obsolete argument to command line
This patch introduces the argument [,obsolete=allow] to the `-sandbox on' option. It allows Qemu to run safely on old system that still relies on old system calls. Signed-off-by: Eduardo Otubo --- include/sysemu/seccomp.h | 3 ++- qemu-options.hx | 12 ++-- qemu-seccomp.c | 20 +++- vl.c | 22 +- 4 files changed, 52 insertions(+), 5 deletions(-) diff --git a/include/sysemu/seccomp.h b/include/sysemu/seccomp.h index 23b9c3c789..215138a372 100644 --- a/include/sysemu/seccomp.h +++ b/include/sysemu/seccomp.h @@ -16,8 +16,9 @@ #define QEMU_SECCOMP_H #define QEMU_SECCOMP_SET_DEFAULT (1 << 0) +#define QEMU_SECCOMP_SET_OBSOLETE(1 << 1) #include -int seccomp_start(void); +int seccomp_start(uint32_t seccomp_opts); #endif diff --git a/qemu-options.hx b/qemu-options.hx index 9f6e2adfff..72150c6b84 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4017,13 +4017,21 @@ Old param mode (ARM only). ETEXI DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \ -"-sandbox Enable seccomp mode 2 system call filter (default 'off').\n", +"-sandbox on[,obsolete=allow|deny]\n" \ +"Enable seccomp mode 2 system call filter (default 'off').\n" \ +"use 'obsolete' to allow obsolete system calls that are provided\n" \ +"by the kernel, but typically no longer used by modern\n" \ +"C library implementations.\n", QEMU_ARCH_ALL) STEXI -@item -sandbox @var{arg} +@item -sandbox @var{arg}[,obsolete=@var{string}] @findex -sandbox Enable Seccomp mode 2 system call filter. 'on' will enable syscall filtering and 'off' will disable it. The default is 'off'. +@table @option +@item obsolete=@var{string} +Enable Obsolete system calls +@end table ETEXI DEF("readconfig", HAS_ARG, QEMU_OPTION_readconfig, diff --git a/qemu-seccomp.c b/qemu-seccomp.c index bc9a1f77ff..126e5ee2d5 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -56,9 +56,22 @@ static const struct QemuSeccompSyscall blacklist[] = { { SCMP_SYS(tuxcall),1, QEMU_SECCOMP_SET_DEFAULT }, { SCMP_SYS(ulimit), 1, QEMU_SECCOMP_SET_DEFAULT }, { SCMP_SYS(vserver),1, QEMU_SECCOMP_SET_DEFAULT }, +/* obsolete */ +{ SCMP_SYS(readdir),2, QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(_sysctl),2, QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(bdflush),2, QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(create_module), 2, QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(get_kernel_syms),2, QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(query_module), 2, QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(sgetmask), 2, QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(ssetmask), 2, QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(sysfs), 2, QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(uselib), 2, QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(ustat), 2, QEMU_SECCOMP_SET_OBSOLETE }, }; -int seccomp_start(void) + +int seccomp_start(uint32_t seccomp_opts) { int rc = 0; unsigned int i = 0; @@ -72,6 +85,11 @@ int seccomp_start(void) for (i = 0; i < ARRAY_SIZE(blacklist); i++) { switch (blacklist[i].set) { +case QEMU_SECCOMP_SET_OBSOLETE: +if ((seccomp_opts & QEMU_SECCOMP_SET_OBSOLETE)) { +continue; +} +break; default: break; } diff --git a/vl.c b/vl.c index 76e0b3a946..dafbe30e2b 100644 --- a/vl.c +++ b/vl.c @@ -271,6 +271,10 @@ static QemuOptsList qemu_sandbox_opts = { .name = "enable", .type = QEMU_OPT_BOOL, }, +{ +.name = "obsolete", +.type = QEMU_OPT_STRING, +}, { /* end of list */ } }, }; @@ -1034,7 +1038,23 @@ static int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp) { if (qemu_opt_get_bool(opts, "enable", false)) { #ifdef CONFIG_SECCOMP -if (seccomp_start() < 0) { +uint32_t seccomp_opts = 0x0; +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"); +} +} + +if (seccomp_start(seccomp_opts) < 0) { error_report("failed to install seccomp syscall filter " "in the kernel"); return -1; -- 2.13.5
[Qemu-devel] [PATCHv5 4/5] seccomp: add spawn argument to command line
This patch adds [,spawn=deny] argument to `-sandbox on' option. It blacklists fork and execve system calls, avoiding Qemu to spawn new threads or processes. Signed-off-by: Eduardo Otubo --- include/sysemu/seccomp.h | 1 + qemu-options.hx | 9 +++-- qemu-seccomp.c | 12 vl.c | 16 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/include/sysemu/seccomp.h b/include/sysemu/seccomp.h index 4a9e63c7cd..3ab5fc4f61 100644 --- a/include/sysemu/seccomp.h +++ b/include/sysemu/seccomp.h @@ -18,6 +18,7 @@ #define QEMU_SECCOMP_SET_DEFAULT (1 << 0) #define QEMU_SECCOMP_SET_OBSOLETE(1 << 1) #define QEMU_SECCOMP_SET_PRIVILEGED (1 << 2) +#define QEMU_SECCOMP_SET_SPAWN (1 << 3) #include diff --git a/qemu-options.hx b/qemu-options.hx index 5c1b163fb5..2b04b9f170 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4018,6 +4018,7 @@ ETEXI DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \ "-sandbox on[,obsolete=allow|deny][,elevateprivileges=allow|deny|children]\n" \ +" [,spawn=allow|deny]\n" \ "Enable seccomp mode 2 system call filter (default 'off').\n" \ "use 'obsolete' to allow obsolete system calls that are provided\n" \ "by the kernel, but typically no longer used by modern\n" \ @@ -4025,10 +4026,12 @@ DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \ "use 'elevateprivileges' to allow or deny QEMU process to elevate\n" \ "its privileges by blacklisting all set*uid|gid system calls.\n" \ "The value 'children' will deny set*uid|gid system calls for\n" \ -"main QEMU process but will allow forks and execves to run unprivileged\n", +"main QEMU process but will allow forks and execves to run unprivileged\n" \ +"use 'spawn' to avoid QEMU to spawn new threads or processes by\n" \ +" blacklisting *fork and execve\n", QEMU_ARCH_ALL) STEXI -@item -sandbox @var{arg}[,obsolete=@var{string}][,elevateprivileges=@var{string}] +@item -sandbox @var{arg}[,obsolete=@var{string}][,elevateprivileges=@var{string}][,spawn=@var{string}] @findex -sandbox Enable Seccomp mode 2 system call filter. 'on' will enable syscall filtering and 'off' will disable it. The default is 'off'. @@ -4037,6 +4040,8 @@ disable it. The default is 'off'. Enable Obsolete system calls @item elevateprivileges=@var{string} Disable set*uid|gid system calls +@item spawn=@var{string} +Disable *fork and execve @end table ETEXI diff --git a/qemu-seccomp.c b/qemu-seccomp.c index 2bad16cafb..4c169febf8 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -79,6 +79,10 @@ static const struct QemuSeccompSyscall blacklist[] = { { SCMP_SYS(setresgid), 4, QEMU_SECCOMP_SET_PRIVILEGED }, { SCMP_SYS(setfsuid), 4, QEMU_SECCOMP_SET_PRIVILEGED }, { SCMP_SYS(setfsgid), 4, QEMU_SECCOMP_SET_PRIVILEGED }, +/* spawn */ +{ SCMP_SYS(fork), 8, QEMU_SECCOMP_SET_SPAWN }, +{ SCMP_SYS(vfork), 8, QEMU_SECCOMP_SET_SPAWN }, +{ SCMP_SYS(execve), 8, QEMU_SECCOMP_SET_SPAWN }, }; @@ -109,6 +113,14 @@ int seccomp_start(uint32_t seccomp_opts) } break; +case QEMU_SECCOMP_SET_SPAWN: +if (seccomp_opts & QEMU_SECCOMP_SET_SPAWN) { +break; +} else { +continue; +} + +break; default: break; } diff --git a/vl.c b/vl.c index 413cfe8504..0af137da17 100644 --- a/vl.c +++ b/vl.c @@ -280,6 +280,10 @@ static QemuOptsList qemu_sandbox_opts = { .name = "elevateprivileges", .type = QEMU_OPT_STRING, }, +{ +.name = "spawn", +.type = QEMU_OPT_STRING, +}, { /* end of list */ } }, }; @@ -1081,6 +1085,18 @@ static int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp) } } +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; +} +} + if (seccomp_start(seccomp_opts) < 0) { error_report("failed to install seccomp syscall filter " "in the kernel"); -- 2.13.5
[Qemu-devel] [PATCHv5 5/5] seccomp: add resourcecontrol argument to command line
This patch adds [,resourcecontrol=deny] to `-sandbox on' option. It blacklists all process affinity and scheduler priority system calls to avoid any bigger of the process. Signed-off-by: Eduardo Otubo --- include/sysemu/seccomp.h | 1 + qemu-options.hx | 9 ++--- qemu-seccomp.c | 19 +++ vl.c | 16 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/include/sysemu/seccomp.h b/include/sysemu/seccomp.h index 3ab5fc4f61..e67c2dc840 100644 --- a/include/sysemu/seccomp.h +++ b/include/sysemu/seccomp.h @@ -19,6 +19,7 @@ #define QEMU_SECCOMP_SET_OBSOLETE(1 << 1) #define QEMU_SECCOMP_SET_PRIVILEGED (1 << 2) #define QEMU_SECCOMP_SET_SPAWN (1 << 3) +#define QEMU_SECCOMP_SET_RESOURCECTL (1 << 4) #include diff --git a/qemu-options.hx b/qemu-options.hx index 2b04b9f170..600614f6e5 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4018,7 +4018,7 @@ ETEXI DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \ "-sandbox on[,obsolete=allow|deny][,elevateprivileges=allow|deny|children]\n" \ -" [,spawn=allow|deny]\n" \ +" [,spawn=allow|deny][,resourcecontrol=allow|deny]\n" \ "Enable seccomp mode 2 system call filter (default 'off').\n" \ "use 'obsolete' to allow obsolete system calls that are provided\n" \ "by the kernel, but typically no longer used by modern\n" \ @@ -4028,10 +4028,11 @@ DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \ "The value 'children' will deny set*uid|gid system calls for\n" \ "main QEMU process but will allow forks and execves to run unprivileged\n" \ "use 'spawn' to avoid QEMU to spawn new threads or processes by\n" \ -" blacklisting *fork and execve\n", +" blacklisting *fork and execve\n" \ +"use 'resourcecontrol' to disable process affinity and schedular priority\n", QEMU_ARCH_ALL) STEXI -@item -sandbox @var{arg}[,obsolete=@var{string}][,elevateprivileges=@var{string}][,spawn=@var{string}] +@item -sandbox @var{arg}[,obsolete=@var{string}][,elevateprivileges=@var{string}][,spawn=@var{string}][,resourcecontrol=@var{string}] @findex -sandbox Enable Seccomp mode 2 system call filter. 'on' will enable syscall filtering and 'off' will disable it. The default is 'off'. @@ -4042,6 +4043,8 @@ Enable Obsolete system calls Disable set*uid|gid system calls @item spawn=@var{string} Disable *fork and execve +@item resourcecontrol=@var{string} +Disable process affinity and schedular priority @end table ETEXI diff --git a/qemu-seccomp.c b/qemu-seccomp.c index 4c169febf8..e7c19c8165 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -83,6 +83,17 @@ static const struct QemuSeccompSyscall blacklist[] = { { SCMP_SYS(fork), 8, QEMU_SECCOMP_SET_SPAWN }, { SCMP_SYS(vfork), 8, QEMU_SECCOMP_SET_SPAWN }, { SCMP_SYS(execve), 8, QEMU_SECCOMP_SET_SPAWN }, +/* resource control */ +{ SCMP_SYS(getpriority),16, QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(setpriority),16, QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(sched_setparam), 16, QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(sched_getparam), 16, QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(sched_setscheduler), 16, QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(sched_getscheduler), 16, QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(sched_setaffinity), 16, QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(sched_getaffinity), 16, QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(sched_get_priority_max), 16, QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(sched_get_priority_min), 16, QEMU_SECCOMP_SET_RESOURCECTL }, }; @@ -121,6 +132,14 @@ int seccomp_start(uint32_t seccomp_opts) } break; +case QEMU_SECCOMP_SET_RESOURCECTL: +if (seccomp_opts & QEMU_SECCOMP_SET_RESOURCECTL) { +break; +} else { +continue; +} + +break; default: break; } diff --git a/vl.c b/vl.c index 0af137da17..ce3883ccb1 100644 --- a/vl.c +++ b/vl.c @@ -284,6 +284,10 @@ static QemuOptsList qemu_sandbox_opts = { .name = "spawn", .type = QEMU_OPT_STRING, }, +{ +.name = "resourcecontrol", +.type = QEMU_OPT_STRING, +}, { /* end of list */ } }, }; @@ -1097,6 +1101,18 @@ static int parse_sandbox(void *o
Re: [Qemu-devel] [PATCHv5 1/5] seccomp: changing from whitelist to blacklist
On Fri, Sep 08, 2017 at 11:43:27AM +0200, Thomas Huth wrote: > On 08.09.2017 11:10, Eduardo Otubo wrote: > > This patch changes the default behavior of the seccomp filter from > > whitelist to blacklist. By default now all system calls are allowed and > > a small black list of definitely forbidden ones was created. > > > > Signed-off-by: Eduardo Otubo > > --- > > include/sysemu/seccomp.h | 2 + > > qemu-seccomp.c | 264 > > ++- > > vl.c | 1 - > > 3 files changed, 35 insertions(+), 232 deletions(-) > > > > diff --git a/include/sysemu/seccomp.h b/include/sysemu/seccomp.h > > index cfc06008cb..23b9c3c789 100644 > > --- a/include/sysemu/seccomp.h > > +++ b/include/sysemu/seccomp.h > > @@ -15,6 +15,8 @@ > > #ifndef QEMU_SECCOMP_H > > #define QEMU_SECCOMP_H > > > > +#define QEMU_SECCOMP_SET_DEFAULT (1 << 0) > > + > > #include > > > > int seccomp_start(void); > > diff --git a/qemu-seccomp.c b/qemu-seccomp.c > > index df75d9c471..bc9a1f77ff 100644 > > --- a/qemu-seccomp.c > > +++ b/qemu-seccomp.c > > @@ -28,232 +28,34 @@ > > > > struct QemuSeccompSyscall { > > int32_t num; > > -uint8_t priority; > > +int type; > > What's this "type" field good for? I failed to spot the place in the > sources where you are using it...? Anyway, some comments here right > after the struct members would be useful. The type is exactly the type of the system call on the blacklist array below. Being QEMU_SECCOMP_SET_DEFAULT, QEMU_SECCOMP_SET_OBSOLETE, etc. Do you think comments here worth a full v6? > > Thomas > > > +uint8_t set; > > }; > > > > -static const struct QemuSeccompSyscall seccomp_whitelist[] = { > > -{ SCMP_SYS(timer_settime), 255 }, > [...] > > -{ SCMP_SYS(memfd_create), 240 }, > > -#ifdef HAVE_CACHEFLUSH > > -{ SCMP_SYS(cacheflush), 240 }, > > -#endif > > -{ SCMP_SYS(sysinfo), 240 }, > > +static const struct QemuSeccompSyscall blacklist[] = { > > +/* default set of syscalls to blacklist */ > > +{ SCMP_SYS(reboot), 1, QEMU_SECCOMP_SET_DEFAULT }, > > +{ SCMP_SYS(swapon), 1, QEMU_SECCOMP_SET_DEFAULT }, > > +{ SCMP_SYS(swapoff),1, QEMU_SECCOMP_SET_DEFAULT }, > > +{ SCMP_SYS(syslog), 1, QEMU_SECCOMP_SET_DEFAULT }, > > +{ SCMP_SYS(mount), 1, QEMU_SECCOMP_SET_DEFAULT }, > > +{ SCMP_SYS(umount), 1, QEMU_SECCOMP_SET_DEFAULT }, > > +{ SCMP_SYS(kexec_load), 1, QEMU_SECCOMP_SET_DEFAULT }, > > +{ SCMP_SYS(afs_syscall),1, QEMU_SECCOMP_SET_DEFAULT }, > > +{ SCMP_SYS(break), 1, QEMU_SECCOMP_SET_DEFAULT }, > > +{ SCMP_SYS(ftime), 1, QEMU_SECCOMP_SET_DEFAULT }, > > +{ SCMP_SYS(getpmsg),1, QEMU_SECCOMP_SET_DEFAULT }, > > +{ SCMP_SYS(gtty), 1, QEMU_SECCOMP_SET_DEFAULT }, > > +{ SCMP_SYS(lock), 1, QEMU_SECCOMP_SET_DEFAULT }, > > +{ SCMP_SYS(mpx),1, QEMU_SECCOMP_SET_DEFAULT }, > > +{ SCMP_SYS(prof), 1, QEMU_SECCOMP_SET_DEFAULT }, > > +{ SCMP_SYS(profil), 1, QEMU_SECCOMP_SET_DEFAULT }, > > +{ SCMP_SYS(putpmsg),1, QEMU_SECCOMP_SET_DEFAULT }, > > +{ SCMP_SYS(security), 1, QEMU_SECCOMP_SET_DEFAULT }, > > +{ SCMP_SYS(stty), 1, QEMU_SECCOMP_SET_DEFAULT }, > > +{ SCMP_SYS(tuxcall),1, QEMU_SECCOMP_SET_DEFAULT }, > > +{ SCMP_SYS(ulimit), 1, QEMU_SECCOMP_SET_DEFAULT }, > > +{ SCMP_SYS(vserver),1, QEMU_SECCOMP_SET_DEFAULT }, > > }; > > > > int seccomp_start(void) > > @@ -262,19 +64,19 @@ int seccomp_start(void) > > unsigned int i = 0; > > scmp_filter_ctx ctx; > > > > -ctx = seccomp_init(SCMP_ACT_KILL); > > +ctx = seccomp_init(SCMP_ACT_ALLOW); > > if (ctx == NULL) { > > rc = -1; > > goto seccomp_return; > > } > > > > -for (i = 0; i < ARRAY_SIZE(seccomp_whitelist); i++) { > > -rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, > > seccomp_whitelist[i].num, 0); > > -if (rc < 0) { > > -goto seccomp_return; > > +for (i = 0; i < ARRAY_SIZE(blacklist); i++) { > > +switch (blacklist[i].set) { > >
Re: [Qemu-devel] [PATCHv5 1/5] seccomp: changing from whitelist to blacklist
On Fri, Sep 08, 2017 at 11:52:42AM +0200, Thomas Huth wrote: > On 08.09.2017 11:50, Eduardo Otubo wrote: > > On Fri, Sep 08, 2017 at 11:43:27AM +0200, Thomas Huth wrote: > >> On 08.09.2017 11:10, Eduardo Otubo wrote: > >>> This patch changes the default behavior of the seccomp filter from > >>> whitelist to blacklist. By default now all system calls are allowed and > >>> a small black list of definitely forbidden ones was created. > >>> > >>> Signed-off-by: Eduardo Otubo > >>> --- > >>> include/sysemu/seccomp.h | 2 + > >>> qemu-seccomp.c | 264 > >>> ++- > >>> vl.c | 1 - > >>> 3 files changed, 35 insertions(+), 232 deletions(-) > >>> > >>> diff --git a/include/sysemu/seccomp.h b/include/sysemu/seccomp.h > >>> index cfc06008cb..23b9c3c789 100644 > >>> --- a/include/sysemu/seccomp.h > >>> +++ b/include/sysemu/seccomp.h > >>> @@ -15,6 +15,8 @@ > >>> #ifndef QEMU_SECCOMP_H > >>> #define QEMU_SECCOMP_H > >>> > >>> +#define QEMU_SECCOMP_SET_DEFAULT (1 << 0) > >>> + > >>> #include > >>> > >>> int seccomp_start(void); > >>> diff --git a/qemu-seccomp.c b/qemu-seccomp.c > >>> index df75d9c471..bc9a1f77ff 100644 > >>> --- a/qemu-seccomp.c > >>> +++ b/qemu-seccomp.c > >>> @@ -28,232 +28,34 @@ > >>> > >>> struct QemuSeccompSyscall { > >>> int32_t num; > >>> -uint8_t priority; > >>> +int type; > >> > >> What's this "type" field good for? I failed to spot the place in the > >> sources where you are using it...? Anyway, some comments here right > >> after the struct members would be useful. > > > > The type is exactly the type of the system call on the blacklist array > > below. Being QEMU_SECCOMP_SET_DEFAULT, QEMU_SECCOMP_SET_OBSOLETE, etc. > > Sorry, I still do not understand. If that's the case, what's the > difference between the "type" field and the "set" field? Where do you > use the "type" field? HARGH, sorry. Perhaps I was debugging tis for too long and didn't notice it. This was for debug purposes only. I'll remove and resend. Thanks for spotting this. > >>> +uint8_t set; > >>> }; > >>> > >>> -static const struct QemuSeccompSyscall seccomp_whitelist[] = { > >>> -{ SCMP_SYS(timer_settime), 255 }, > >> [...] > >>> -{ SCMP_SYS(memfd_create), 240 }, > >>> -#ifdef HAVE_CACHEFLUSH > >>> -{ SCMP_SYS(cacheflush), 240 }, > >>> -#endif > >>> -{ SCMP_SYS(sysinfo), 240 }, > >>> +static const struct QemuSeccompSyscall blacklist[] = { > >>> +/* default set of syscalls to blacklist */ > >>> +{ SCMP_SYS(reboot), 1, QEMU_SECCOMP_SET_DEFAULT }, > >>> +{ SCMP_SYS(swapon), 1, QEMU_SECCOMP_SET_DEFAULT }, > >>> +{ SCMP_SYS(swapoff),1, QEMU_SECCOMP_SET_DEFAULT }, > >>> +{ SCMP_SYS(syslog), 1, QEMU_SECCOMP_SET_DEFAULT }, > >>> +{ SCMP_SYS(mount), 1, QEMU_SECCOMP_SET_DEFAULT }, > >>> +{ SCMP_SYS(umount), 1, QEMU_SECCOMP_SET_DEFAULT }, > >>> +{ SCMP_SYS(kexec_load), 1, QEMU_SECCOMP_SET_DEFAULT }, > >>> +{ SCMP_SYS(afs_syscall),1, QEMU_SECCOMP_SET_DEFAULT }, > >>> +{ SCMP_SYS(break), 1, QEMU_SECCOMP_SET_DEFAULT }, > >>> +{ SCMP_SYS(ftime), 1, QEMU_SECCOMP_SET_DEFAULT }, > >>> +{ SCMP_SYS(getpmsg),1, QEMU_SECCOMP_SET_DEFAULT }, > >>> +{ SCMP_SYS(gtty), 1, QEMU_SECCOMP_SET_DEFAULT }, > >>> +{ SCMP_SYS(lock), 1, QEMU_SECCOMP_SET_DEFAULT }, > >>> +{ SCMP_SYS(mpx),1, QEMU_SECCOMP_SET_DEFAULT }, > >>> +{ SCMP_SYS(prof), 1, QEMU_SECCOMP_SET_DEFAULT }, > >>> +{ SCMP_SYS(profil), 1, QEMU_SECCOMP_SET_DEFAULT }, > >>> +{ SCMP_SYS(putpmsg),1, QEMU_SECCOMP_SET_DEFAULT }, > >>> +{ SCMP_SYS(security), 1, QEMU_SECCOMP_SET_DEFAULT }, > >>> +{ SCMP_SYS(stty), 1, QEMU_SECCOMP_SET_DEFAULT }, >
Re: [Qemu-devel] [PATCHv5 4/5] seccomp: add spawn argument to command line
On Fri, Sep 08, 2017 at 11:50:12AM +0200, Thomas Huth wrote: > On 08.09.2017 11:10, Eduardo Otubo wrote: > > This patch adds [,spawn=deny] argument to `-sandbox on' option. It > > blacklists fork and execve system calls, avoiding Qemu to spawn new > > threads or processes. > > > > Signed-off-by: Eduardo Otubo > > --- > > include/sysemu/seccomp.h | 1 + > > qemu-options.hx | 9 +++-- > > qemu-seccomp.c | 12 > > vl.c | 16 > > 4 files changed, 36 insertions(+), 2 deletions(-) > > > > diff --git a/include/sysemu/seccomp.h b/include/sysemu/seccomp.h > > index 4a9e63c7cd..3ab5fc4f61 100644 > > --- a/include/sysemu/seccomp.h > > +++ b/include/sysemu/seccomp.h > > @@ -18,6 +18,7 @@ > > #define QEMU_SECCOMP_SET_DEFAULT (1 << 0) > > #define QEMU_SECCOMP_SET_OBSOLETE(1 << 1) > > #define QEMU_SECCOMP_SET_PRIVILEGED (1 << 2) > > +#define QEMU_SECCOMP_SET_SPAWN (1 << 3) > > > > #include > > > > diff --git a/qemu-options.hx b/qemu-options.hx > > index 5c1b163fb5..2b04b9f170 100644 > > --- a/qemu-options.hx > > +++ b/qemu-options.hx > > @@ -4018,6 +4018,7 @@ ETEXI > > > > DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \ > > "-sandbox > > on[,obsolete=allow|deny][,elevateprivileges=allow|deny|children]\n" \ > > +" [,spawn=allow|deny]\n" \ > > "Enable seccomp mode 2 system call filter (default > > 'off').\n" \ > > "use 'obsolete' to allow obsolete system calls that > > are provided\n" \ > > "by the kernel, but typically no longer used by > > modern\n" \ > > @@ -4025,10 +4026,12 @@ DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \ > > "use 'elevateprivileges' to allow or deny QEMU process > > to elevate\n" \ > > "its privileges by blacklisting all set*uid|gid > > system calls.\n" \ > > "The value 'children' will deny set*uid|gid system > > calls for\n" \ > > -"main QEMU process but will allow forks and > > execves to run unprivileged\n", > > +"main QEMU process but will allow forks and > > execves to run unprivileged\n" \ > > +"use 'spawn' to avoid QEMU to spawn new threads or > > processes by\n" \ > > +" blacklisting *fork and execve\n", > > QEMU_ARCH_ALL) > > STEXI > > -@item -sandbox > > @var{arg}[,obsolete=@var{string}][,elevateprivileges=@var{string}] > > +@item -sandbox > > @var{arg}[,obsolete=@var{string}][,elevateprivileges=@var{string}][,spawn=@var{string}] > > @findex -sandbox > > Enable Seccomp mode 2 system call filter. 'on' will enable syscall > > filtering and 'off' will > > disable it. The default is 'off'. > > @@ -4037,6 +4040,8 @@ disable it. The default is 'off'. > > Enable Obsolete system calls > > @item elevateprivileges=@var{string} > > Disable set*uid|gid system calls > > +@item spawn=@var{string} > > +Disable *fork and execve > > @end table > > ETEXI > > > > diff --git a/qemu-seccomp.c b/qemu-seccomp.c > > index 2bad16cafb..4c169febf8 100644 > > --- a/qemu-seccomp.c > > +++ b/qemu-seccomp.c > > @@ -79,6 +79,10 @@ static const struct QemuSeccompSyscall blacklist[] = { > > { SCMP_SYS(setresgid), 4, QEMU_SECCOMP_SET_PRIVILEGED }, > > { SCMP_SYS(setfsuid), 4, QEMU_SECCOMP_SET_PRIVILEGED }, > > { SCMP_SYS(setfsgid), 4, QEMU_SECCOMP_SET_PRIVILEGED }, > > +/* spawn */ > > +{ SCMP_SYS(fork), 8, QEMU_SECCOMP_SET_SPAWN }, > > +{ SCMP_SYS(vfork), 8, QEMU_SECCOMP_SET_SPAWN }, > > +{ SCMP_SYS(execve), 8, QEMU_SECCOMP_SET_SPAWN }, > > }; > > > > > > @@ -109,6 +113,14 @@ int seccomp_start(uint32_t seccomp_opts) > > } > > > > break; > > +case QEMU_SECCOMP_SET_SPAWN: > > +if (seccomp_opts & QEMU_SECCOMP_SET_SPAWN) { > > +break; > > +} else { > > +continue; > > +} > > + > > Remove the above empty line? > > Anyway, it's somewhat ugly that you need a switch-case statement here at > all. Couldn't you simply check it like this: > > if (!(seccomp_opts & blacklist[i].set)) { > continue; > } > ? > > You then just have to invert the meaning of the > QEMU_SECCOMP_SET_OBSOLETE bit in the second patch, so that this bit is > treated in the same way as the others (i.e. use > uint32_t seccomp_opts = QEMU_SECCOMP_SET_OBSOLETE; > instead of > uint32_t seccomp_opts = 0x0; > in vl.c in the second patch). That's indeed much better, but perhaps: uint32_t seccomp_opts = QEMU_SECCOMP_SET_DEFAULT | QEMU_SECCOMP_SET_OBSOLETE; ? -- Eduardo Otubo Senior Software Engineer @ RedHat
[Qemu-devel] [PATCHv6 0/6] seccomp: feature refactoring
v6: * remove switch-case * invert obsolete option logic at vl.c * remove debug info v5: * replaced strcmp by g_str_equal * removed useless goto * fixed style problems v4: * include another field on the struct for the modes * remove priority * fixed typos * error handling for prctl * add allow|deny values for all options * error hanlding for wrong values for all options * change how binary values are treated * reformat help text v3: * Style problems fixed v2: * The semantics of the options "allow/deny" instead of booleans "on/off" remains. * Added option 'children' to elevateprivileges * Added documentation to docs/ v1: * First version based on the discussion https://lists.gnu.org/archive/html/qemu-devel/2017-02/msg03348.html Eduardo Otubo (6): seccomp: changing from whitelist to blacklist seccomp: add obsolete argument to command line seccomp: add elevateprivileges argument to command line seccomp: add spawn argument to command line seccomp: add resourcecontrol argument to command line seccomp: adding documentation to new seccomp model docs/seccomp.txt | 31 + include/sysemu/seccomp.h | 8 +- qemu-options.hx | 26 +++- qemu-seccomp.c | 325 ++- vl.c | 82 +++- 5 files changed, 235 insertions(+), 237 deletions(-) create mode 100644 docs/seccomp.txt -- 2.13.5
[Qemu-devel] [PATCHv6 1/5] seccomp: changing from whitelist to blacklist
This patch changes the default behavior of the seccomp filter from whitelist to blacklist. By default now all system calls are allowed and a small black list of definitely forbidden ones was created. Signed-off-by: Eduardo Otubo --- include/sysemu/seccomp.h | 2 + qemu-seccomp.c | 260 +-- vl.c | 1 - 3 files changed, 30 insertions(+), 233 deletions(-) diff --git a/include/sysemu/seccomp.h b/include/sysemu/seccomp.h index cfc06008cb..23b9c3c789 100644 --- a/include/sysemu/seccomp.h +++ b/include/sysemu/seccomp.h @@ -15,6 +15,8 @@ #ifndef QEMU_SECCOMP_H #define QEMU_SECCOMP_H +#define QEMU_SECCOMP_SET_DEFAULT (1 << 0) + #include int seccomp_start(void); diff --git a/qemu-seccomp.c b/qemu-seccomp.c index df75d9c471..f66613fc71 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -28,232 +28,33 @@ struct QemuSeccompSyscall { int32_t num; -uint8_t priority; +uint8_t set; }; -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(socketcall), 250 }, -{ SCMP_SYS(read), 249 }, -{ SCMP_SYS(io_submit), 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(socket), 245 }, -{ SCMP_SYS(setsockopt), 245 }, -{ SCMP_SYS(recvmsg), 245 }, -{ SCMP_SYS(sendmsg), 245 }, -{ SCMP_SYS(accept), 245 }, -{ SCMP_SYS(connect), 245 }, -{ SCMP_SYS(socketpair), 245 }, -{ SCMP_SYS(bind), 245 }, -{ SCMP_SYS(listen), 245 }, -{ SCMP_SYS(semget), 245 }, -{ SCMP_SYS(ipc), 245 }, -{ SCMP_SYS(gettimeofday), 245 }, -{ SCMP_SYS(readlink), 245 }, -{ SCMP_SYS(access), 245 }, -{ SCMP_SYS(prctl), 245 }, -{ SCMP_SYS(signalfd), 245 }, -{ SCMP_SYS(getrlimit), 245 }, -{ SCMP_SYS(getrusage), 245 }, -{ SCMP_SYS(set_tid_address), 245 }, -{ SCMP_SYS(statfs), 245 }, -{ SCMP_SYS(unlink), 245 }, -{ SCMP_SYS(wait4), 245 }, -{ SCMP_SYS(fcntl64), 245 }, -{ SCMP_SYS(fstat64), 245 }, -{ SCMP_SYS(stat64), 245 }, -{ SCMP_SYS(getgid32), 245 }, -{ SCMP_SYS(getegid32), 245 }, -{ SCMP_SYS(getuid32), 245 }, -{ SCMP_SYS(geteuid32), 245 }, -{ SCMP_SYS(sigreturn), 245 }, -{ SCMP_SYS(_newselect), 245 }, -{ SCMP_SYS(_llseek), 245 }, -{ SCMP_SYS(mmap2), 245 }, -{ SCMP_SYS(sigprocmask), 245 }, -{ SCMP_SYS(sched_getparam), 245 }, -{ SCMP_SYS(sched_getscheduler), 245 }, -{ SCMP_SYS(fstat), 245 }, -{ SCMP_SYS(clock_getres), 245 }, -{ SCMP_SYS(sched_get_priority_min), 245 }, -{ SCMP_SYS(sched_get_priority_max), 245 }, -{ SCMP_SYS(stat), 245 }, -{ SCMP_SYS(uname), 245 }, -{ SCMP_SYS(eventfd2), 245 }, -{ SCMP_SYS(io_getevents), 245 }, -{ SCMP_SYS(dup), 245 }, -{ SCMP_SYS(dup2), 245 }, -{ SCMP_SYS(dup3), 245 }, -{ SCMP_SYS(gettid), 245 }, -{ SCMP_SYS(getgid), 245 }, -{ SCMP_SYS(getegid), 245 }, -{ SCMP_SYS(getuid), 245 }, -{ SCMP_SYS(geteuid), 245 }, -{ SCMP_SYS(timer_create), 245 }, -{ SCMP_SYS(times), 245 }, -{ SCMP_SYS(exit), 245 }, -{ SCMP_SYS(clock_gettime), 245 }, -{ SCMP_SYS(time), 245 }, -{ SCMP_SYS(restart_syscall), 245 }, -{ SCMP_SYS(pwrite64), 245 }, -{ SCMP_SYS(nanosleep), 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(rt_sigreturn), 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(pselect6), 245 }, -{ SCMP_SYS(fork), 245 }, -{ SCMP_SYS(rt_sigprocmask), 245 }, -{ SCMP_SYS(write), 244 }, -{ SCMP_SYS(fcntl), 243 }, -{ SCMP_SYS(tgkill), 242 }, -{ SCMP_SYS(kill), 242 }, -{ SCMP_SYS(rt_sigaction), 242 }, -{ SCMP_SYS(pipe2), 242 }, -{ SCMP_SYS(munmap), 242 }, -{ SCMP_SYS(mremap), 242 }, -{ SCMP_SYS(fdatasync), 242 }, -{ SCMP_SYS(close), 242 }, -{ SCMP_SYS(rt_sigpending), 242 }, -{ SCMP_SYS(rt_sigtimedwait), 242 }, -{ SCMP_SYS(readv), 242 }, -{ SCMP_SYS(writev), 242 }, -{ SCMP_SYS(preadv), 242 }, -{ SCMP_SYS(pwritev), 242 }, -{ SCMP_SYS(setrlimit), 242 }, -{ SCMP_SYS(ftruncate), 242 }, -{ SCMP_SYS(lstat), 242 }, -{ SCMP_SYS(pipe), 242 }, -{ SCMP_SYS(umask), 242 }, -{ SCMP_SYS(chdir), 242 }, -{ SCMP_SYS(setitimer), 242 }, -{ SCMP_SYS(setsid), 242 }, -{ SCMP_SYS(poll), 242 }, -{ SCMP_SYS(epoll_create), 242 }, -{ SC
[Qemu-devel] [PATCHv6 2/5] seccomp: add obsolete argument to command line
This patch introduces the argument [,obsolete=allow] to the `-sandbox on' option. It allows Qemu to run safely on old system that still relies on old system calls. Signed-off-by: Eduardo Otubo --- include/sysemu/seccomp.h | 3 ++- qemu-options.hx | 12 ++-- qemu-seccomp.c | 19 ++- vl.c | 23 ++- 4 files changed, 52 insertions(+), 5 deletions(-) diff --git a/include/sysemu/seccomp.h b/include/sysemu/seccomp.h index 23b9c3c789..215138a372 100644 --- a/include/sysemu/seccomp.h +++ b/include/sysemu/seccomp.h @@ -16,8 +16,9 @@ #define QEMU_SECCOMP_H #define QEMU_SECCOMP_SET_DEFAULT (1 << 0) +#define QEMU_SECCOMP_SET_OBSOLETE(1 << 1) #include -int seccomp_start(void); +int seccomp_start(uint32_t seccomp_opts); #endif diff --git a/qemu-options.hx b/qemu-options.hx index 9f6e2adfff..72150c6b84 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4017,13 +4017,21 @@ Old param mode (ARM only). ETEXI DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \ -"-sandbox Enable seccomp mode 2 system call filter (default 'off').\n", +"-sandbox on[,obsolete=allow|deny]\n" \ +"Enable seccomp mode 2 system call filter (default 'off').\n" \ +"use 'obsolete' to allow obsolete system calls that are provided\n" \ +"by the kernel, but typically no longer used by modern\n" \ +"C library implementations.\n", QEMU_ARCH_ALL) STEXI -@item -sandbox @var{arg} +@item -sandbox @var{arg}[,obsolete=@var{string}] @findex -sandbox Enable Seccomp mode 2 system call filter. 'on' will enable syscall filtering and 'off' will disable it. The default is 'off'. +@table @option +@item obsolete=@var{string} +Enable Obsolete system calls +@end table ETEXI DEF("readconfig", HAS_ARG, QEMU_OPTION_readconfig, diff --git a/qemu-seccomp.c b/qemu-seccomp.c index f66613fc71..8a5fbd2ff1 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -55,9 +55,22 @@ static const struct QemuSeccompSyscall blacklist[] = { { SCMP_SYS(tuxcall),QEMU_SECCOMP_SET_DEFAULT }, { SCMP_SYS(ulimit), QEMU_SECCOMP_SET_DEFAULT }, { SCMP_SYS(vserver),QEMU_SECCOMP_SET_DEFAULT }, +/* obsolete */ +{ SCMP_SYS(readdir),QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(_sysctl),QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(bdflush),QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(create_module), QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(get_kernel_syms),QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(query_module), QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(sgetmask), QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(ssetmask), QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(sysfs), QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(uselib), QEMU_SECCOMP_SET_OBSOLETE }, +{ SCMP_SYS(ustat), QEMU_SECCOMP_SET_OBSOLETE }, }; -int seccomp_start(void) + +int seccomp_start(uint32_t seccomp_opts) { int rc = 0; unsigned int i = 0; @@ -70,6 +83,10 @@ int seccomp_start(void) } for (i = 0; i < ARRAY_SIZE(blacklist); i++) { +if (!(seccomp_opts & blacklist[i].set)) { +continue; +} + rc = seccomp_rule_add(ctx, SCMP_ACT_KILL, blacklist[i].num, 0); if (rc < 0) { goto seccomp_return; diff --git a/vl.c b/vl.c index 76e0b3a946..62b71dd529 100644 --- a/vl.c +++ b/vl.c @@ -271,6 +271,10 @@ static QemuOptsList qemu_sandbox_opts = { .name = "enable", .type = QEMU_OPT_BOOL, }, +{ +.name = "obsolete", +.type = QEMU_OPT_STRING, +}, { /* end of list */ } }, }; @@ -1034,7 +1038,24 @@ static int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp) { if (qemu_opt_get_bool(opts, "enable", false)) { #ifdef CONFIG_SECCOMP -if (seccomp_start() < 0) { +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"); +} +} + +if (seccomp_start(seccomp_opts) < 0) { error_report("failed to install seccomp syscall filter " "in the kernel"); return -1; -- 2.13.5
[Qemu-devel] [PATCHv6 3/5] seccomp: add elevateprivileges argument to command line
This patch introduces the new argument [,elevateprivileges=allow|deny|children] to the `-sandbox on'. It allows or denies Qemu process to elevate its privileges by blacklisting all set*uid|gid system calls. The 'children' option will let forks and execves run unprivileged. Signed-off-by: Eduardo Otubo --- include/sysemu/seccomp.h | 1 + qemu-options.hx | 12 +--- qemu-seccomp.c | 11 +++ vl.c | 27 +++ 4 files changed, 48 insertions(+), 3 deletions(-) diff --git a/include/sysemu/seccomp.h b/include/sysemu/seccomp.h index 215138a372..4a9e63c7cd 100644 --- a/include/sysemu/seccomp.h +++ b/include/sysemu/seccomp.h @@ -17,6 +17,7 @@ #define QEMU_SECCOMP_SET_DEFAULT (1 << 0) #define QEMU_SECCOMP_SET_OBSOLETE(1 << 1) +#define QEMU_SECCOMP_SET_PRIVILEGED (1 << 2) #include diff --git a/qemu-options.hx b/qemu-options.hx index 72150c6b84..5c1b163fb5 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4017,20 +4017,26 @@ Old param mode (ARM only). ETEXI DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \ -"-sandbox on[,obsolete=allow|deny]\n" \ +"-sandbox on[,obsolete=allow|deny][,elevateprivileges=allow|deny|children]\n" \ "Enable seccomp mode 2 system call filter (default 'off').\n" \ "use 'obsolete' to allow obsolete system calls that are provided\n" \ "by the kernel, but typically no longer used by modern\n" \ -"C library implementations.\n", +"C library implementations.\n" \ +"use 'elevateprivileges' to allow or deny QEMU process to elevate\n" \ +"its privileges by blacklisting all set*uid|gid system calls.\n" \ +"The value 'children' will deny set*uid|gid system calls for\n" \ +"main QEMU process but will allow forks and execves to run unprivileged\n", QEMU_ARCH_ALL) STEXI -@item -sandbox @var{arg}[,obsolete=@var{string}] +@item -sandbox @var{arg}[,obsolete=@var{string}][,elevateprivileges=@var{string}] @findex -sandbox Enable Seccomp mode 2 system call filter. 'on' will enable syscall filtering and 'off' will disable it. The default is 'off'. @table @option @item obsolete=@var{string} Enable Obsolete system calls +@item elevateprivileges=@var{string} +Disable set*uid|gid system calls @end table ETEXI diff --git a/qemu-seccomp.c b/qemu-seccomp.c index 8a5fbd2ff1..978d66bd28 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -67,6 +67,17 @@ static const struct QemuSeccompSyscall blacklist[] = { { SCMP_SYS(sysfs), QEMU_SECCOMP_SET_OBSOLETE }, { SCMP_SYS(uselib), QEMU_SECCOMP_SET_OBSOLETE }, { SCMP_SYS(ustat), QEMU_SECCOMP_SET_OBSOLETE }, +/* privileged */ +{ SCMP_SYS(setuid), QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setgid), QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setpgid),QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setsid), QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setreuid), QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setregid), QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setresuid), QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setresgid), QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setfsuid), QEMU_SECCOMP_SET_PRIVILEGED }, +{ SCMP_SYS(setfsgid), QEMU_SECCOMP_SET_PRIVILEGED }, }; diff --git a/vl.c b/vl.c index 62b71dd529..ff3b5c766a 100644 --- a/vl.c +++ b/vl.c @@ -29,6 +29,7 @@ #ifdef CONFIG_SECCOMP #include "sysemu/seccomp.h" +#include "sys/prctl.h" #endif #if defined(CONFIG_VDE) @@ -275,6 +276,10 @@ static QemuOptsList qemu_sandbox_opts = { .name = "obsolete", .type = QEMU_OPT_STRING, }, +{ +.name = "elevateprivileges", +.type = QEMU_OPT_STRING, +}, { /* end of list */ } }, }; @@ -1055,6 +1060,28 @@ static int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp) } } +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*/ +
[Qemu-devel] [PATCHv6 5/5] seccomp: add resourcecontrol argument to command line
This patch adds [,resourcecontrol=deny] to `-sandbox on' option. It blacklists all process affinity and scheduler priority system calls to avoid any bigger of the process. Signed-off-by: Eduardo Otubo --- include/sysemu/seccomp.h | 1 + qemu-options.hx | 9 ++--- qemu-seccomp.c | 11 +++ vl.c | 16 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/include/sysemu/seccomp.h b/include/sysemu/seccomp.h index 3ab5fc4f61..e67c2dc840 100644 --- a/include/sysemu/seccomp.h +++ b/include/sysemu/seccomp.h @@ -19,6 +19,7 @@ #define QEMU_SECCOMP_SET_OBSOLETE(1 << 1) #define QEMU_SECCOMP_SET_PRIVILEGED (1 << 2) #define QEMU_SECCOMP_SET_SPAWN (1 << 3) +#define QEMU_SECCOMP_SET_RESOURCECTL (1 << 4) #include diff --git a/qemu-options.hx b/qemu-options.hx index 2b04b9f170..600614f6e5 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4018,7 +4018,7 @@ ETEXI DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \ "-sandbox on[,obsolete=allow|deny][,elevateprivileges=allow|deny|children]\n" \ -" [,spawn=allow|deny]\n" \ +" [,spawn=allow|deny][,resourcecontrol=allow|deny]\n" \ "Enable seccomp mode 2 system call filter (default 'off').\n" \ "use 'obsolete' to allow obsolete system calls that are provided\n" \ "by the kernel, but typically no longer used by modern\n" \ @@ -4028,10 +4028,11 @@ DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \ "The value 'children' will deny set*uid|gid system calls for\n" \ "main QEMU process but will allow forks and execves to run unprivileged\n" \ "use 'spawn' to avoid QEMU to spawn new threads or processes by\n" \ -" blacklisting *fork and execve\n", +" blacklisting *fork and execve\n" \ +"use 'resourcecontrol' to disable process affinity and schedular priority\n", QEMU_ARCH_ALL) STEXI -@item -sandbox @var{arg}[,obsolete=@var{string}][,elevateprivileges=@var{string}][,spawn=@var{string}] +@item -sandbox @var{arg}[,obsolete=@var{string}][,elevateprivileges=@var{string}][,spawn=@var{string}][,resourcecontrol=@var{string}] @findex -sandbox Enable Seccomp mode 2 system call filter. 'on' will enable syscall filtering and 'off' will disable it. The default is 'off'. @@ -4042,6 +4043,8 @@ Enable Obsolete system calls Disable set*uid|gid system calls @item spawn=@var{string} Disable *fork and execve +@item resourcecontrol=@var{string} +Disable process affinity and schedular priority @end table ETEXI diff --git a/qemu-seccomp.c b/qemu-seccomp.c index f3878a5e29..b770a77d33 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -82,6 +82,17 @@ static const struct QemuSeccompSyscall blacklist[] = { { SCMP_SYS(fork), QEMU_SECCOMP_SET_SPAWN }, { SCMP_SYS(vfork), QEMU_SECCOMP_SET_SPAWN }, { SCMP_SYS(execve), QEMU_SECCOMP_SET_SPAWN }, +/* resource control */ +{ SCMP_SYS(getpriority),QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(setpriority),QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(sched_setparam), QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(sched_getparam), QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(sched_setscheduler), QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(sched_getscheduler), QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(sched_setaffinity), QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(sched_getaffinity), QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(sched_get_priority_max), QEMU_SECCOMP_SET_RESOURCECTL }, +{ SCMP_SYS(sched_get_priority_min), QEMU_SECCOMP_SET_RESOURCECTL }, }; diff --git a/vl.c b/vl.c index 369e3411b1..79ecacdcc6 100644 --- a/vl.c +++ b/vl.c @@ -284,6 +284,10 @@ static QemuOptsList qemu_sandbox_opts = { .name = "spawn", .type = QEMU_OPT_STRING, }, +{ +.name = "resourcecontrol", +.type = QEMU_OPT_STRING, +}, { /* end of list */ } }, }; @@ -1098,6 +1102,18 @@ static int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp) } } +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"); -- 2.13.5
[Qemu-devel] [PATCHv6 4/5] seccomp: add spawn argument to command line
This patch adds [,spawn=deny] argument to `-sandbox on' option. It blacklists fork and execve system calls, avoiding Qemu to spawn new threads or processes. Signed-off-by: Eduardo Otubo --- include/sysemu/seccomp.h | 1 + qemu-options.hx | 9 +++-- qemu-seccomp.c | 4 vl.c | 16 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/include/sysemu/seccomp.h b/include/sysemu/seccomp.h index 4a9e63c7cd..3ab5fc4f61 100644 --- a/include/sysemu/seccomp.h +++ b/include/sysemu/seccomp.h @@ -18,6 +18,7 @@ #define QEMU_SECCOMP_SET_DEFAULT (1 << 0) #define QEMU_SECCOMP_SET_OBSOLETE(1 << 1) #define QEMU_SECCOMP_SET_PRIVILEGED (1 << 2) +#define QEMU_SECCOMP_SET_SPAWN (1 << 3) #include diff --git a/qemu-options.hx b/qemu-options.hx index 5c1b163fb5..2b04b9f170 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4018,6 +4018,7 @@ ETEXI DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \ "-sandbox on[,obsolete=allow|deny][,elevateprivileges=allow|deny|children]\n" \ +" [,spawn=allow|deny]\n" \ "Enable seccomp mode 2 system call filter (default 'off').\n" \ "use 'obsolete' to allow obsolete system calls that are provided\n" \ "by the kernel, but typically no longer used by modern\n" \ @@ -4025,10 +4026,12 @@ DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \ "use 'elevateprivileges' to allow or deny QEMU process to elevate\n" \ "its privileges by blacklisting all set*uid|gid system calls.\n" \ "The value 'children' will deny set*uid|gid system calls for\n" \ -"main QEMU process but will allow forks and execves to run unprivileged\n", +"main QEMU process but will allow forks and execves to run unprivileged\n" \ +"use 'spawn' to avoid QEMU to spawn new threads or processes by\n" \ +" blacklisting *fork and execve\n", QEMU_ARCH_ALL) STEXI -@item -sandbox @var{arg}[,obsolete=@var{string}][,elevateprivileges=@var{string}] +@item -sandbox @var{arg}[,obsolete=@var{string}][,elevateprivileges=@var{string}][,spawn=@var{string}] @findex -sandbox Enable Seccomp mode 2 system call filter. 'on' will enable syscall filtering and 'off' will disable it. The default is 'off'. @@ -4037,6 +4040,8 @@ disable it. The default is 'off'. Enable Obsolete system calls @item elevateprivileges=@var{string} Disable set*uid|gid system calls +@item spawn=@var{string} +Disable *fork and execve @end table ETEXI diff --git a/qemu-seccomp.c b/qemu-seccomp.c index 978d66bd28..f3878a5e29 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -78,6 +78,10 @@ static const struct QemuSeccompSyscall blacklist[] = { { SCMP_SYS(setresgid), QEMU_SECCOMP_SET_PRIVILEGED }, { SCMP_SYS(setfsuid), QEMU_SECCOMP_SET_PRIVILEGED }, { SCMP_SYS(setfsgid), QEMU_SECCOMP_SET_PRIVILEGED }, +/* spawn */ +{ SCMP_SYS(fork), QEMU_SECCOMP_SET_SPAWN }, +{ SCMP_SYS(vfork), QEMU_SECCOMP_SET_SPAWN }, +{ SCMP_SYS(execve), QEMU_SECCOMP_SET_SPAWN }, }; diff --git a/vl.c b/vl.c index ff3b5c766a..369e3411b1 100644 --- a/vl.c +++ b/vl.c @@ -280,6 +280,10 @@ static QemuOptsList qemu_sandbox_opts = { .name = "elevateprivileges", .type = QEMU_OPT_STRING, }, +{ +.name = "spawn", +.type = QEMU_OPT_STRING, +}, { /* end of list */ } }, }; @@ -1082,6 +1086,18 @@ static int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp) } } +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; +} +} + if (seccomp_start(seccomp_opts) < 0) { error_report("failed to install seccomp syscall filter " "in the kernel"); -- 2.13.5
Re: [Qemu-devel] [PATCH] configure: Allow --enable-seccomp on s390x, too
On Thu, Sep 14, 2017 at 12:36:03PM +0200, Thomas Huth wrote: > libseccomp supports s390x since version 2.3.0, and I was able to start > a VM with "-sandbox on" without any obvious problems by using this patch, > so it should be safe to allow --enable-seccomp on s390x nowadays, too. > I don't have a s390x hardware to test so I'll have to trust you. Anyone from IBM interested in testing this patch as well? > Signed-off-by: Thomas Huth > --- > configure | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/configure b/configure > index fd7e3a5..83ba64e 100755 > --- a/configure > +++ b/configure > @@ -2032,7 +2032,7 @@ if test "$seccomp" != "no" ; then > arm|aarch64) > libseccomp_minver="2.2.3" > ;; > -ppc|ppc64) > +ppc|ppc64|s390x) > libseccomp_minver="2.3.0" > ;; > *) > -- > 1.8.3.1 > -- Eduardo Otubo Senior Software Engineer @ RedHat
Re: [Qemu-devel] [PATCH] configure: Allow --enable-seccomp on s390x, too
On Thu, Sep 14, 2017 at 01:55:46PM +0200, Christian Borntraeger wrote: > On 09/14/2017 12:36 PM, Thomas Huth wrote: > > libseccomp supports s390x since version 2.3.0, and I was able to start > > a VM with "-sandbox on" without any obvious problems by using this patch, > > so it should be safe to allow --enable-seccomp on s390x nowadays, too. > > Seems to work fine on s390x. > Acked-by: Christian Borntraeger Cool, thanks :-) Acked-by: Eduardo Otubo > > > > > Signed-off-by: Thomas Huth > > --- > > configure | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > diff --git a/configure b/configure > > index fd7e3a5..83ba64e 100755 > > --- a/configure > > +++ b/configure > > @@ -2032,7 +2032,7 @@ if test "$seccomp" != "no" ; then > > arm|aarch64) > > libseccomp_minver="2.2.3" > > ;; > > -ppc|ppc64) > > +ppc|ppc64|s390x) > > libseccomp_minver="2.3.0" > > ;; > > *) > > > -- Eduardo Otubo Senior Software Engineer @ RedHat
Re: [Qemu-devel] [Qemu-trivial] [PATCH 23/34] hw/dma/i8257: rename DMA_init() to i8257_dma_init()
On Fri, Sep 22, 2017 at 03:08:03PM -0300, Philippe Mathieu-Daudé wrote: > On 09/22/2017 02:43 PM, Hervé Poussineau wrote: > > Le 22/09/2017 à 18:01, Philippe Mathieu-Daudé a écrit : > [...] > > > +void i8257_dma_init(ISABus *bus, int high_page_enable); > > > + > > > > As you're changing the DMA_init prototype, can you add an Error **errp > > parameter, and pass &error_abort in each caller? > > > > See http://lists.gnu.org/archive/html/qemu-devel/2017-09/msg00262.html > > for more details > > If Eduardo doesn't have a patch ready I can do it. Please go ahead. You can also use my patch set (v2) for that as a base if you want. https://lists.gnu.org/archive/html/qemu-devel/2017-09/msg08007.html -- Eduardo Otubo Senior Software Engineer @ RedHat
[Qemu-devel] CPU hotplug on Windows 2016 as guest
Hi guys, I'm just trying Qemu 2.7 and 2.8 and Windows 2016 as guest and cpu hotplug doesn't seem to be working. CPU appears on qemu device tree, but doesn't appear inside the guest (nor control panel, performance monitor or device manager) Anyone going through this? -- Eduardo Otubo ProfitBricks GmbH signature.asc Description: PGP signature
Re: [Qemu-devel] [PATCH] seccomp: report more useful errors from seccomp
On 25/03/2019 - 15:52:27, Daniel P. Berrange wrote: > On Mon, Mar 25, 2019 at 04:25:19PM +0100, Marc-André Lureau wrote: > > Hi > > > > On Mon, Mar 25, 2019 at 3:07 PM Daniel P. Berrangé > > wrote: > > > > > > Most of the seccomp functions return errnos as a negative return > > > value. The code is currently ignoring these and reporting a generic > > > error message for all seccomp failure scenarios making debugging > > > painful. Report a more precise error from each failed call and include > > > errno if it is available. > > > > > > Signed-off-by: Daniel P. Berrangé > > > > Is this for 4.0? Eligible imho. > > I don't really mind either way. Patch looks good. Acked-by: Eduardo Otubo > > > > > Reviewed-by: Marc-André Lureau > > > > > --- > > > qemu-seccomp.c | 20 +--- > > > 1 file changed, 13 insertions(+), 7 deletions(-) > > > > > > diff --git a/qemu-seccomp.c b/qemu-seccomp.c > > > index 36d5829831..8daa9e0528 100644 > > > --- a/qemu-seccomp.c > > > +++ b/qemu-seccomp.c > > > @@ -138,21 +138,23 @@ static uint32_t qemu_seccomp_get_kill_action(void) > > > } > > > > > > > > > -static int seccomp_start(uint32_t seccomp_opts) > > > +static int seccomp_start(uint32_t seccomp_opts, Error **errp) > > > { > > > -int rc = 0; > > > +int rc = -1; > > > unsigned int i = 0; > > > scmp_filter_ctx ctx; > > > uint32_t action = qemu_seccomp_get_kill_action(); > > > > > > ctx = seccomp_init(SCMP_ACT_ALLOW); > > > if (ctx == NULL) { > > > -rc = -1; > > > +error_setg(errp, "failed to initialize seccomp context"); > > > goto seccomp_return; > > > } > > > > > > rc = seccomp_attr_set(ctx, SCMP_FLTATR_CTL_TSYNC, 1); > > > if (rc != 0) { > > > +error_setg_errno(errp, -rc, > > > + "failed to set seccomp thread synchronization"); > > > goto seccomp_return; > > > } > > > > > > @@ -164,15 +166,21 @@ static int seccomp_start(uint32_t seccomp_opts) > > > rc = seccomp_rule_add_array(ctx, action, blacklist[i].num, > > > blacklist[i].narg, > > > blacklist[i].arg_cmp); > > > if (rc < 0) { > > > +error_setg_errno(errp, -rc, > > > + "failed to add seccomp blacklist rules"); > > > goto seccomp_return; > > > } > > > } > > > > > > rc = seccomp_load(ctx); > > > +if (rc < 0) { > > > +error_setg_errno(errp, -rc, > > > + "failed to load seccomp syscall filter in > > > kernel"); > > > +} > > > > > >seccomp_return: > > > seccomp_release(ctx); > > > -return rc; > > > +return rc < 0 ? -1 : 0; > > > } > > > > > > #ifdef CONFIG_SECCOMP > > > @@ -242,9 +250,7 @@ int parse_sandbox(void *opaque, QemuOpts *opts, Error > > > **errp) > > > } > > > } > > > > > > -if (seccomp_start(seccomp_opts) < 0) { > > > -error_setg(errp, "failed to install seccomp syscall filter " > > > - "in the kernel"); > > > +if (seccomp_start(seccomp_opts, errp) < 0) { > > > return -1; > > > } > > > } > > > -- > > > 2.20.1 > > > > > > > > > > > > -- > > Marc-André Lureau > > Regards, > Daniel > -- > |: https://berrange.com -o-https://www.flickr.com/photos/dberrange :| > |: https://libvirt.org -o-https://fstop138.berrange.com :| > |: https://entangle-photo.org-o-https://www.instagram.com/dberrange :| -- Eduardo Otubo signature.asc Description: PGP signature
[Qemu-devel] [PULL 0/2] seccomp branch queue
The following changes since commit 49fc899f8d673dd9e73f3db0d9e9ea60b77c331b: Update version for v4.0.0-rc1 release (2019-03-26 17:02:29 +) are available in the Git repository at: https://github.com/otubo/qemu.git tags/pull-seccomp-20190327 for you to fetch changes up to 9d6951a9463e0fb8d39cc546f9c37756aed5b19d: seccomp: report more useful errors from seccomp (2019-03-27 10:55:13 +0100) pull-seccomp-20190327 Daniel P. Berrangé (2): seccomp: don't kill process for resource control syscalls seccomp: report more useful errors from seccomp qemu-seccomp.c | 52 ++-- 1 file changed, 38 insertions(+), 14 deletions(-) -- 2.17.2
[Qemu-devel] [PULL 1/2] seccomp: don't kill process for resource control syscalls
From: Daniel P. Berrangé The Mesa library tries to set process affinity on some of its threads in order to optimize its performance. Currently this results in QEMU being immediately terminated when seccomp is enabled. Mesa doesn't consider failure of the process affinity settings to be fatal to its operation, but our seccomp policy gives it no choice in gracefully handling this denial. It is reasonable to consider that malicious code using the resource control syscalls to be a less serious attack than if they were trying to spawn processes or change UIDs and other such things. Generally speaking changing the resource control setting will "merely" affect quality of service of processes on the host. With this in mind, rather than kill the process, we can relax the policy for these syscalls to return the EPERM errno value. This allows callers to detect that QEMU does not want them to change resource allocations, and apply some reasonable fallback logic. The main downside to this is for code which uses these syscalls but does not check the return value, blindly assuming they will always succeeed. Returning an errno could result in sub-optimal behaviour. Arguably though such code is already broken & needs fixing regardless. Signed-off-by: Daniel P. Berrangé Reviewed-by: Marc-André Lureau Acked-by: Eduardo Otubo --- qemu-seccomp.c | 32 +--- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/qemu-seccomp.c b/qemu-seccomp.c index 36d5829831..cf520883c7 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -121,20 +121,37 @@ qemu_seccomp(unsigned int operation, unsigned int flags, void *args) #endif } -static uint32_t qemu_seccomp_get_kill_action(void) +static uint32_t qemu_seccomp_get_action(int set) { +switch (set) { +case QEMU_SECCOMP_SET_DEFAULT: +case QEMU_SECCOMP_SET_OBSOLETE: +case QEMU_SECCOMP_SET_PRIVILEGED: +case QEMU_SECCOMP_SET_SPAWN: { #if defined(SECCOMP_GET_ACTION_AVAIL) && defined(SCMP_ACT_KILL_PROCESS) && \ defined(SECCOMP_RET_KILL_PROCESS) -{ -uint32_t action = SECCOMP_RET_KILL_PROCESS; +static int kill_process = -1; +if (kill_process == -1) { +uint32_t action = SECCOMP_RET_KILL_PROCESS; -if (qemu_seccomp(SECCOMP_GET_ACTION_AVAIL, 0, &action) == 0) { +if (qemu_seccomp(SECCOMP_GET_ACTION_AVAIL, 0, &action) == 0) { +kill_process = 1; +} +kill_process = 0; +} +if (kill_process == 1) { return SCMP_ACT_KILL_PROCESS; } -} #endif +return SCMP_ACT_TRAP; +} + +case QEMU_SECCOMP_SET_RESOURCECTL: +return SCMP_ACT_ERRNO(EPERM); -return SCMP_ACT_TRAP; +default: +g_assert_not_reached(); +} } @@ -143,7 +160,6 @@ static int seccomp_start(uint32_t seccomp_opts) int rc = 0; unsigned int i = 0; scmp_filter_ctx ctx; -uint32_t action = qemu_seccomp_get_kill_action(); ctx = seccomp_init(SCMP_ACT_ALLOW); if (ctx == NULL) { @@ -157,10 +173,12 @@ static int seccomp_start(uint32_t seccomp_opts) } for (i = 0; i < ARRAY_SIZE(blacklist); i++) { +uint32_t action; if (!(seccomp_opts & blacklist[i].set)) { continue; } +action = qemu_seccomp_get_action(blacklist[i].set); rc = seccomp_rule_add_array(ctx, action, blacklist[i].num, blacklist[i].narg, blacklist[i].arg_cmp); if (rc < 0) { -- 2.17.2