From patchwork Mon Sep 24 11:23:48 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Barcelo X-Patchwork-Id: 186364 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 E76282C0087 for ; Mon, 24 Sep 2012 21:24:24 +1000 (EST) Received: from localhost ([::1]:37465 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TG6ly-00063z-PN for incoming@patchwork.ozlabs.org; Mon, 24 Sep 2012 07:24:22 -0400 Received: from eggs.gnu.org ([208.118.235.92]:39680) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TG6ll-00063X-MO for qemu-devel@nongnu.org; Mon, 24 Sep 2012 07:24:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TG6lk-0003Tl-8e for qemu-devel@nongnu.org; Mon, 24 Sep 2012 07:24:09 -0400 Received: from mail-wg0-f41.google.com ([74.125.82.41]:56658) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TG6lj-0003Tg-UR for qemu-devel@nongnu.org; Mon, 24 Sep 2012 07:24:08 -0400 Received: by wgbds1 with SMTP id ds1so2537721wgb.4 for ; Mon, 24 Sep 2012 04:24:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:x-mailer; bh=BxpO4x/DBaE+z68cNoc2Wb+jsLO5V5E5I8s8D7tSVQ4=; b=yitoOaCZb+i62LIKglpymk9tJ/LxAEjbnhgiOaYy4U0UFhoBP0TOTO85lnL4vOvf3w XlDSKl96nwTYH3GxJxMf7Cl9F0i1NXWLifZjxtpHik0WdzMEdkSXI1RcWPMPBNWcHcFm 3NVUZD70Q+VdTnz2bRPjVOcfA9fNsZol0cAa3t90tqNMhJyFk1gcpTC3SUQBc2Q6cE/N /im9llDQXrafgvaTlRnO1gjwluhyxY6c99QpwSI10fKStePPmQvRfR8wYj/n4370OcCa kyaAPVHCyKK7boQ35bAbrxdOsxDF/J3Ivzhuq8mkW+sYpc+drBF5L2Hz+VGLbznJGwvq 8v9Q== Received: by 10.180.97.33 with SMTP id dx1mr13717680wib.18.1348485846277; Mon, 24 Sep 2012 04:24:06 -0700 (PDT) Received: from localhost.localdomain (62.57.4.176.dyn.user.ono.com. [62.57.4.176]) by mx.google.com with ESMTPS id cl8sm14300797wib.10.2012.09.24.04.24.04 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 24 Sep 2012 04:24:05 -0700 (PDT) From: Alex Barcelo To: qemu-devel@nongnu.org Date: Mon, 24 Sep 2012 13:23:48 +0200 Message-Id: <1348485828-8248-1-git-send-email-abarcelo@ac.upc.edu> X-Mailer: git-send-email 1.7.5.4 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 74.125.82.41 Cc: Riku Voipio , Alex Barcelo Subject: [Qemu-devel] [PATCH] linux-user: SIGSEGV protection on host/guest signal masks 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 There are some situations where the guest application changes the SIGSEGV and messes with qemu-user way of handling self-modifying code. In case of qemu-system, this happens. Emulation of qemu-system inside qemu-user doesn't work because of this. This patch doesn't aim to do a complete signal protection and achieve bulletproof signal management for every test case, instead it is a small easy-to-understand patch that resolves the most common problem. Signed-off-by: Alex Barcelo --- linux-user/syscall.c | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+), 0 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 6257a04..95bb818 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5897,6 +5897,16 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, } break; #endif + +/* + * Use SETSIGNAL and GETSIGNAL macros for SIGSEGV protection. + * + * This should protect SIGSEGV unconscious manipulations from guest apps + * (but we still do not let the emulated software play the signal game) + */ +#define SETSIGNAL(set) sigdelset( (set), SIGSEGV) +#define GETSIGNAL(get) sigaddset( (get), SIGSEGV) + #ifdef TARGET_NR_sigprocmask case TARGET_NR_sigprocmask: { @@ -5952,6 +5962,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, target_to_host_old_sigset(&set, p); unlock_user(p, arg2, 0); set_ptr = &set; + // override SIGSEGV when changing mask + SETSIGNAL(set_ptr); } else { how = 0; set_ptr = NULL; @@ -5960,6 +5972,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, if (!is_error(ret) && arg3) { if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0))) goto efault; + // ignore real SIGSEGV state in mask + GETSIGNAL(&oldset); host_to_target_old_sigset(p, &oldset); unlock_user(p, arg3, sizeof(target_sigset_t)); } @@ -5992,6 +6006,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, target_to_host_sigset(&set, p); unlock_user(p, arg2, 0); set_ptr = &set; + // override SIGSEGV when changing mask + SETSIGNAL(set_ptr); } else { how = 0; set_ptr = NULL; @@ -6001,6 +6017,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0))) goto efault; host_to_target_sigset(p, &oldset); + // ignore real SIGSEGV state in mask + GETSIGNAL(&oldset); unlock_user(p, arg3, sizeof(target_sigset_t)); } }