From patchwork Tue Jul 17 19:19:14 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eduardo Otubo X-Patchwork-Id: 171543 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 583762C007E for ; Wed, 18 Jul 2012 05:20:55 +1000 (EST) Received: from localhost ([::1]:51301 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SrDKH-00058P-8L for incoming@patchwork.ozlabs.org; Tue, 17 Jul 2012 15:20:53 -0400 Received: from eggs.gnu.org ([208.118.235.92]:54262) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SrDJt-0004Pn-0A for qemu-devel@nongnu.org; Tue, 17 Jul 2012 15:20:30 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SrDJr-0002Mr-3E for qemu-devel@nongnu.org; Tue, 17 Jul 2012 15:20:28 -0400 Received: from e24smtp05.br.ibm.com ([32.104.18.26]:41734) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SrDJq-0002LO-OS for qemu-devel@nongnu.org; Tue, 17 Jul 2012 15:20:27 -0400 Received: from /spool/local by e24smtp05.br.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 17 Jul 2012 16:20:25 -0300 Received: from d24dlp02.br.ibm.com (9.18.248.206) by e24smtp05.br.ibm.com (10.172.0.141) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Tue, 17 Jul 2012 16:20:23 -0300 Received: from d24relay02.br.ibm.com (d24relay02.br.ibm.com [9.13.184.26]) by d24dlp02.br.ibm.com (Postfix) with ESMTP id 7BFA71DC004E for ; Tue, 17 Jul 2012 15:20:23 -0400 (EDT) Received: from d24av05.br.ibm.com (d24av05.br.ibm.com [9.18.232.44]) by d24relay02.br.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id q6HJJb2131916122 for ; Tue, 17 Jul 2012 16:19:37 -0300 Received: from d24av05.br.ibm.com (loopback [127.0.0.1]) by d24av05.br.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id q6HJKMQP013535 for ; Tue, 17 Jul 2012 16:20:22 -0300 Received: from vader.local.com ([9.12.226.34]) by d24av05.br.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id q6HJJpnx012694; Tue, 17 Jul 2012 16:20:08 -0300 From: Eduardo Otubo To: qemu-devel@nongnu.org Date: Tue, 17 Jul 2012 16:19:14 -0300 Message-Id: <35c32eeef29cc4eed49a75c52f9ad0f880092659.1342552002.git.otubo@linux.vnet.ibm.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: References: In-Reply-To: References: X-Content-Scanned: Fidelis XPS MAILER x-cbid: 12071719-2362-0000-0000-000007D241FE X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 32.104.18.26 Cc: pmoore@redhat.com, blauwirbel@gmail.com, anthony@codemonkey.ws, wad@chromium.org, Eduardo Otubo Subject: [Qemu-devel] [PATCHv4 3/4] Adding qemu-seccomp-debug.[ch] X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 --- qemu-seccomp-debug.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++ qemu-seccomp-debug.h | 38 ++++++++++++++++++++ 2 files changed, 133 insertions(+) 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 + * + * 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" + +#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); + 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; + } + 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 + * + * 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. + */ +#ifndef QEMU_SECCOMP_TRAP_H +#define QEMU_SECCOMP_TRAP_H + +#include +#include +#include +#include + +#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