qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCHv5 3/4] Adding qemu-seccomp-debug.[ch]


From: Anthony Liguori
Subject: Re: [Qemu-devel] [PATCHv5 3/4] Adding qemu-seccomp-debug.[ch]
Date: Fri, 03 Aug 2012 15:54:40 -0500
User-agent: Notmuch/0.13.2+93~ged93d79 (http://notmuchmail.org) Emacs/23.3.1 (x86_64-pc-linux-gnu)

Eduardo Otubo <address@hidden> writes:

> The new 'trap' (debug) mode will capture the illegal system call before it is
> executed. The feature and the implementation is based on Will Drewry's
> patch - https://lkml.org/lkml/2012/4/12/449
>
> v4:
>  * New files in v4
>  * If SCMP_ACT_TRAP flag used when calling seccomp_init(), the kernel will
>    send a SIGSYS every time a not whitelisted syscall is called. This
>    sighandler install_seccomp_syscall_debug() is installed in this mode so
>    we can intercept the signal and print to the user the illegal syscall.
>    The process resumes after that.
>  * The behavior of the code inside a signal handler sometimes is
>    unpredictable (as stated in man 7 signals). That's why I deliberately
>    used write() and _exit() functions, and had the string-to-int helper
>    functions as well.
>
> Signed-off-by: Eduardo Otubo <address@hidden>
> ---
>  qemu-seccomp-debug.c |   95 
> ++++++++++++++++++++++++++++++++++++++++++++++++++
>  qemu-seccomp-debug.h |   38 ++++++++++++++++++++
>  2 files changed, 133 insertions(+), 0 deletions(-)
>  create mode 100644 qemu-seccomp-debug.c
>  create mode 100644 qemu-seccomp-debug.h
>
> diff --git a/qemu-seccomp-debug.c b/qemu-seccomp-debug.c
> new file mode 100644
> index 0000000..162c2f1
> --- /dev/null
> +++ b/qemu-seccomp-debug.c
> @@ -0,0 +1,95 @@
> +
> +/*
> + * QEMU seccomp mode 2 support with libseccomp
> + * Debug system calls helper functions
> + *
> + * Copyright IBM, Corp. 2012
> + *
> + * Authors:
> + *  Eduardo Otubo    <address@hidden>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2.  See
> + * the COPYING file in the top-level directory.
> + *
> + * 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-seccomp-debug.h"
> +#include "asm-generic/unistd.h"

This looks like an odd include to me.  I assume you're relying on Linux
headers being installed?  You should at least do <asm-generic/unistd.h>
but I wonder why you need this in the first place.

> +
> +#define safe_warn(data) write(STDERR_FILENO, (const void *) data, 
> sizeof(data))
> +
> +static int count_digits(int number)
> +{
> +    int digits = 0;
> +    while (number) {
> +        number /= 10;
> +        digits++;
> +    }
> +
> +    return digits;
> +}
> +
> +static char *sput_i(int integer, char *string)
> +{
> +    if (integer / 10 != 0) {
> +        string = sput_i(integer / 10, string);
> +    }
> +    *string++ = (char) ('0' + integer % 10);
> +    return string;
> +}
> +
> +static void int_to_asc(int integer, char *string)
> +{
> +    *sput_i(integer, string) = '\n';
> +}
> +
> +static void syscall_debug(int nr, siginfo_t *info, void *void_context)
> +{
> +    ucontext_t *ctx = (ucontext_t *) (void_context);
> +    char errormsg[] = "seccomp: illegal syscall trapped: ";
> +    char syscall_char[count_digits(__NR_syscalls) + 1];
> +    int syscall_num = 0;
> +
> +    if (info->si_code != SYS_SECCOMP) {
> +        return;
> +    }
> +    if (!ctx) {
> +        return;
> +    }
> +    syscall_num = ctx->uc_mcontext.gregs[REG_SYSCALL];
> +    if (syscall_num < 0 || syscall_num >= __NR_syscalls) {
> +        if ((safe_warn("seccomp: error reading syscall from register\n") < 
> 0)) {
> +            return;
> +        }
> +        return;
> +    }
> +    int_to_asc(syscall_num, syscall_char);

I assume you're doign this because of fear of signal safety?  Is there a
reason to believe that snprintf() wouldn't be signal safe?  Even if it's
not on the white list, the implementation can't reasonably rely on
global data, can it?

> +    if ((safe_warn(errormsg) < 0) || (safe_warn(syscall_char) < 0)) {
> +        return;
> +    }
> +    return;
> +}
> +
> +int install_seccomp_syscall_debug(void)
> +{
> +    struct sigaction act;
> +    sigset_t mask;
> +
> +    memset(&act, 0, sizeof(act));
> +    sigemptyset(&mask);
> +    sigaddset(&mask, SIGSYS);
> +
> +    act.sa_sigaction = &syscall_debug;
> +    act.sa_flags = SA_SIGINFO;
> +    if (sigaction(SIGSYS, &act, NULL) < 0) {
> +        perror("seccomp: sigaction returned with errors\n");
> +        return -1;
> +    }
> +    if (pthread_sigmask(SIG_UNBLOCK, &mask, NULL)) {
> +        perror("seccomp: sigprocmask returned with errors\n");
> +        return -1;
> +    }

This looks fishy to me.  We aggressively modify our signal mask in order
to launch a KVM VCPU so I'm pretty sure we'll quickly block SIGSYS.  I
think you need to touch more code than this for it to work.

Regards,

Anthony Liguori

> +    return 0;
> +}
> diff --git a/qemu-seccomp-debug.h b/qemu-seccomp-debug.h
> new file mode 100644
> index 0000000..d3863d6
> --- /dev/null
> +++ b/qemu-seccomp-debug.h
> @@ -0,0 +1,38 @@
> +/*
> + * QEMU seccomp mode 2 support with libseccomp
> + * Trap system calls helper functions
> + *
> + * Copyright IBM, Corp. 2012
> + *
> + * Authors:
> + *  Eduardo Otubo    <address@hidden>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2.  See
> + * the COPYING file in the top-level directory.
> + *
> + * Contributions after 2012-01-13 are licensed under the terms of the
> + * GNU GPL, version 2 or (at your option) any later version.

Version 2 or later for all new files.  Don't include this disclaimer in
new code.

Regards,

Anthony Liguori

> + */
> +#ifndef QEMU_SECCOMP_TRAP_H
> +#define QEMU_SECCOMP_TRAP_H
> +
> +#include <signal.h>
> +#include <string.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +
> +#if defined(__i386__)
> +#define REG_SYSCALL REG_EAX
> +#elif defined(__x86_64__)
> +#define REG_SYSCALL REG_RAX
> +#else
> +#error Unsupported platform
> +#endif
> +
> +#ifndef SYS_SECCOMP
> +#define SYS_SECCOMP 1
> +#endif
> +
> +int install_seccomp_syscall_debug(void);
> +
> +#endif
> -- 
> 1.7.1



reply via email to

[Prev in Thread] Current Thread [Next in Thread]