* [Qemu-devel] [PULL 0/3] seccomp branch queue
@ 2018-08-22 15:40 Eduardo Otubo
2018-08-22 15:40 ` [Qemu-devel] [PULL 1/3] seccomp: use SIGSYS signal instead of killing the thread Eduardo Otubo
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Eduardo Otubo @ 2018-08-22 15:40 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, marcandre.lureau
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
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Qemu-devel] [PULL 1/3] seccomp: use SIGSYS signal instead of killing the thread
2018-08-22 15:40 [Qemu-devel] [PULL 0/3] seccomp branch queue Eduardo Otubo
@ 2018-08-22 15:40 ` Eduardo Otubo
2018-08-22 15:40 ` [Qemu-devel] [PULL 2/3] seccomp: prefer SCMP_ACT_KILL_PROCESS if available Eduardo Otubo
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Eduardo Otubo @ 2018-08-22 15:40 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, marcandre.lureau
From: Marc-André Lureau <marcandre.lureau@redhat.com>
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 <marcandre.lureau@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Acked-by: Eduardo Otubo <otubo@redhat.com>
---
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
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [Qemu-devel] [PULL 2/3] seccomp: prefer SCMP_ACT_KILL_PROCESS if available
2018-08-22 15:40 [Qemu-devel] [PULL 0/3] seccomp branch queue Eduardo Otubo
2018-08-22 15:40 ` [Qemu-devel] [PULL 1/3] seccomp: use SIGSYS signal instead of killing the thread Eduardo Otubo
@ 2018-08-22 15:40 ` Eduardo Otubo
2018-08-22 15:40 ` [Qemu-devel] [PULL 3/3] seccomp: set the seccomp filter to all threads Eduardo Otubo
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Eduardo Otubo @ 2018-08-22 15:40 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, marcandre.lureau
From: Marc-André Lureau <marcandre.lureau@redhat.com>
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 <marcandre.lureau@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Acked-by: Eduardo Otubo <otubo@redhat.com>
---
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 <sys/prctl.h>
#include <seccomp.h>
#include "sysemu/seccomp.h"
+#include <linux/seccomp.h>
/* 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
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [Qemu-devel] [PULL 3/3] seccomp: set the seccomp filter to all threads
2018-08-22 15:40 [Qemu-devel] [PULL 0/3] seccomp branch queue Eduardo Otubo
2018-08-22 15:40 ` [Qemu-devel] [PULL 1/3] seccomp: use SIGSYS signal instead of killing the thread Eduardo Otubo
2018-08-22 15:40 ` [Qemu-devel] [PULL 2/3] seccomp: prefer SCMP_ACT_KILL_PROCESS if available Eduardo Otubo
@ 2018-08-22 15:40 ` Eduardo Otubo
2018-08-22 16:03 ` [Qemu-devel] [PULL 0/3] seccomp branch queue Eric Blake
2018-08-22 16:06 ` Daniel P. Berrangé
4 siblings, 0 replies; 6+ messages in thread
From: Eduardo Otubo @ 2018-08-22 15:40 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, marcandre.lureau
From: Marc-André Lureau <marcandre.lureau@redhat.com>
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 <marcandre.lureau@redhat.com>
Acked-by: Eduardo Otubo <otubo@redhat.com>
---
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
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] [PULL 0/3] seccomp branch queue
2018-08-22 15:40 [Qemu-devel] [PULL 0/3] seccomp branch queue Eduardo Otubo
` (2 preceding siblings ...)
2018-08-22 15:40 ` [Qemu-devel] [PULL 3/3] seccomp: set the seccomp filter to all threads Eduardo Otubo
@ 2018-08-22 16:03 ` Eric Blake
2018-08-22 16:06 ` Daniel P. Berrangé
4 siblings, 0 replies; 6+ messages in thread
From: Eric Blake @ 2018-08-22 16:03 UTC (permalink / raw)
To: Eduardo Otubo, qemu-devel; +Cc: peter.maydell, marcandre.lureau
On 08/22/2018 10:40 AM, Eduardo Otubo wrote:
> 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
Let's hold off on this pull request until the technical debate on 3/3
has settled (namely, there's no point in letting the process continue if
tsync fails on older OS, because it is NOT providing the security that
it claims).
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3266
Virtualization: qemu.org | libvirt.org
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] [PULL 0/3] seccomp branch queue
2018-08-22 15:40 [Qemu-devel] [PULL 0/3] seccomp branch queue Eduardo Otubo
` (3 preceding siblings ...)
2018-08-22 16:03 ` [Qemu-devel] [PULL 0/3] seccomp branch queue Eric Blake
@ 2018-08-22 16:06 ` Daniel P. Berrangé
4 siblings, 0 replies; 6+ messages in thread
From: Daniel P. Berrangé @ 2018-08-22 16:06 UTC (permalink / raw)
To: Eduardo Otubo; +Cc: qemu-devel, peter.maydell, marcandre.lureau
Please don't merge this PULL request - the behaviour of the 3rd patch
is still being debated.
On Wed, Aug 22, 2018 at 05:40:27PM +0200, Eduardo Otubo wrote:
> 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
>
>
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 :|
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2018-08-22 16:07 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-08-22 15:40 [Qemu-devel] [PULL 0/3] seccomp branch queue Eduardo Otubo
2018-08-22 15:40 ` [Qemu-devel] [PULL 1/3] seccomp: use SIGSYS signal instead of killing the thread Eduardo Otubo
2018-08-22 15:40 ` [Qemu-devel] [PULL 2/3] seccomp: prefer SCMP_ACT_KILL_PROCESS if available Eduardo Otubo
2018-08-22 15:40 ` [Qemu-devel] [PULL 3/3] seccomp: set the seccomp filter to all threads Eduardo Otubo
2018-08-22 16:03 ` [Qemu-devel] [PULL 0/3] seccomp branch queue Eric Blake
2018-08-22 16:06 ` Daniel P. Berrangé
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).