From patchwork Wed Mar 8 21:38:41 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Garnier X-Patchwork-Id: 9612029 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id C685060414 for ; Wed, 8 Mar 2017 21:39:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B612F2862A for ; Wed, 8 Mar 2017 21:39:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A78C62862E; Wed, 8 Mar 2017 21:39:59 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,DKIM_VALID autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 26B9A28635 for ; Wed, 8 Mar 2017 21:39:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To: References:List-Owner; bh=kCtDWhHL3aCltGnZmBMbMW17TDaf+MX8WkYv6MCzqss=; b=JJ2 dEL5fAJiIYZH/v6fLmv1RZW8bpkfeZZXXW2gj8WG/+najrXCJuQ2gQSYXdmDDve/q8R/olW/8HJmX SRJuSRkDIMK32UErGQpedCPqTEMbGHsAMmaEGhWLH9mGZKrATos06j5NgOic9yHI4ESb+DRamQK0z mzybRUGvt623uZ6XXCMWwxH02P2i7CGM8bC26MgkmoTS3rC/ab9SGhy8Tr/jlyPLKl1DhSEOam2Mi DDmBlWv4e8ap98ctnIUoZcFue9Ekk1gimtoXRFR7vnvJyTnjN8JAaiDr/LZISB/muKqgwGyo765uh DjEMmkAwG9/HZZcVvs/X/AxaVaiPg8A==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1cljJI-0000pq-9I; Wed, 08 Mar 2017 21:39:52 +0000 Received: from mail-pg0-x233.google.com ([2607:f8b0:400e:c05::233]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1cljIm-0000bg-T0 for linux-arm-kernel@lists.infradead.org; Wed, 08 Mar 2017 21:39:23 +0000 Received: by mail-pg0-x233.google.com with SMTP id b129so17724281pgc.2 for ; Wed, 08 Mar 2017 13:38:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=ZmM5e39PualAXwe1JUCXjH+mTyvPrxbISNLQxpvJvKQ=; b=D5uBc2K1MdPW4/e05XzIv0BrWoVKzntKz6vu476ScLGtcBb8bU5+Lifb+aIPlSIcBI xiH3w3CcxJ+r24kPsg2W1JCG6EeKrr417VoOAduWZFkmvtYbMVkpxn27SUNkQS0xDtgi DXQBVBnZ1CPYLA+rR9vAIVuoxji9rWFEPz2ALk54za4xpsteIvqEBmPVGrzOr1BqYsjN DwcSt4QigOmnadtkgTHuiuDjXUip/zXjIZq0aLc2FrYcBdEvjlzsvp0HlWa4zc/JXQwN VdBWmObzQd+X6tlp+JeH1JASgRxXffq1SHgO4uthjL5DN14zPEZXHGPKlMS3dvHMXSGZ /VNg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=ZmM5e39PualAXwe1JUCXjH+mTyvPrxbISNLQxpvJvKQ=; b=Y+YUBCt3HrB1IeOqX3MgE9ttJ8I2V35doFL1azIv1A7VM9PtfixvRKGemG7dneXsNK 23bxpBkg3KAfNEZMZV3QaIiDRtIGJlW8dtANaNarvKUWQ4kMPqDrNXH1nvqN4K1qRFC2 oAWscjHOBbmDroJit4qeSHSz68G1Kg4YQIVM3g28nzxOlMp5w/Q+kPIA1hJ3IZJAtcx2 Bp5jMFe9EjBscGPbteGMJbJwdVbddoXq5QK5xFSVTGji3w8p952P9hBkKNZZrpc58ihg 9GxNBW5tBlMtFNvNLzxsGSf9omWKTowejaBUFfvKVbtjpxKEO2q1rzbJTV11WO6JsgUW U4mQ== X-Gm-Message-State: AMke39lbugVas/75SltxaMLse/rWCxlS3oVWW/92G8QnWO0SFwsIX5B7jXOlfPXGqlVx/+Uu X-Received: by 10.99.168.5 with SMTP id o5mr9694533pgf.148.1489009139267; Wed, 08 Mar 2017 13:38:59 -0800 (PST) Received: from skynet.sea.corp.google.com ([100.100.206.185]) by smtp.gmail.com with ESMTPSA id h3sm7945921pfc.82.2017.03.08.13.38.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 08 Mar 2017 13:38:58 -0800 (PST) From: Thomas Garnier To: Arnd Bergmann , David Howells , Al Viro , Dave Hansen , Thomas Garnier , =?UTF-8?q?Ren=C3=A9=20Nyffenegger?= , Andrew Morton , Kees Cook , "Paul E . McKenney" , Petr Mladek , Andy Lutomirski , Ard Biesheuvel , Nicolas Pitre , Sebastian Andrzej Siewior , Sergey Senozhatsky , Helge Deller , Rik van Riel , Ingo Molnar , John Stultz , Thomas Gleixner , Oleg Nesterov , Stanislav Kinsburskiy , Pavel Tikhomirov , Stephen Smalley , Frederic Weisbecker , Ingo Molnar , "H . Peter Anvin" , Paolo Bonzini , Dmitry Safonov , Borislav Petkov , Josh Poimboeuf , Brian Gerst , Alexander Potapenko , Jan Beulich , Russell King , Will Deacon , Catalin Marinas , Mark Rutland , James Morse , Chris Metcalf , Laura Abbott , Andre Przywara Subject: [PATCH v1 1/4] syscalls: Restore address limit after a syscall Date: Wed, 8 Mar 2017 13:38:41 -0800 Message-Id: <20170308213844.131877-1-thgarnie@google.com> X-Mailer: git-send-email 2.12.0.246.ga2ecc84866-goog X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170308_133920_989184_42C3E617 X-CRM114-Status: GOOD ( 16.42 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-api@vger.kernel.org, x86@kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kernel-hardening@lists.openwall.com MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP This patch prevents a syscall to modify the address limit of the caller. The address limit is kept by the syscall wrapper and restored just after the syscall ends. For example, it would mitigation this bug: - https://bugs.chromium.org/p/project-zero/issues/detail?id=990 By default, this change warns if the segment is incorrect while returning to user-mode and fix it. The CONFIG_VERIFY_PRE_USERMODE_STATE_BUG option can be enabled to halt instead if needed. The CONFIG_ARCH_NO_SYSCALL_VERIFY_PRE_USERMODE_STATE option is also added so each architecture can optimize how the verify_pre_usermode_state function is called. Signed-off-by: Thomas Garnier --- Based on next-20170308 --- include/linux/syscalls.h | 19 +++++++++++++++++++ init/Kconfig | 16 ++++++++++++++++ kernel/sys.c | 11 +++++++++++ 3 files changed, 46 insertions(+) diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 980c3c9b06f8..78a2268ecd6e 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -191,6 +191,22 @@ extern struct trace_event_functions exit_syscall_print_funcs; SYSCALL_METADATA(sname, x, __VA_ARGS__) \ __SYSCALL_DEFINEx(x, sname, __VA_ARGS__) +asmlinkage void verify_pre_usermode_state(void); + +#ifndef CONFIG_ARCH_NO_SYSCALL_VERIFY_PRE_USERMODE_STATE +static inline bool has_user_ds(void) { + bool ret = segment_eq(get_fs(), USER_DS); + // Prevent re-ordering the call + barrier(); + return ret; +} +#else +static inline bool has_user_ds(void) { + return false; +} +#endif + + #define __PROTECT(...) asmlinkage_protect(__VA_ARGS__) #define __SYSCALL_DEFINEx(x, name, ...) \ asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \ @@ -199,7 +215,10 @@ extern struct trace_event_functions exit_syscall_print_funcs; asmlinkage long SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \ asmlinkage long SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \ { \ + bool user_caller = has_user_ds(); \ long ret = SYSC##name(__MAP(x,__SC_CAST,__VA_ARGS__)); \ + if (user_caller) \ + verify_pre_usermode_state(); \ __MAP(x,__SC_TEST,__VA_ARGS__); \ __PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__)); \ return ret; \ diff --git a/init/Kconfig b/init/Kconfig index c859c993c26f..ab958b59063f 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1929,6 +1929,22 @@ config PROFILING config TRACEPOINTS bool +# +# Set by each architecture that want to optimize how verify_pre_usermode_state +# is called. +# +config ARCH_NO_SYSCALL_VERIFY_PRE_USERMODE_STATE + bool + +config VERIFY_PRE_USERMODE_STATE_BUG + bool "Halt on incorrect state on returning to user-mode" + default n + help + By default a warning is logged and the state is fixed. This option + crashes the kernel instead. + + If unsure, say Y. + source "arch/Kconfig" endmenu # General setup diff --git a/kernel/sys.c b/kernel/sys.c index 196c7134bee6..cc2ebf7fae55 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -2459,3 +2459,14 @@ COMPAT_SYSCALL_DEFINE1(sysinfo, struct compat_sysinfo __user *, info) return 0; } #endif /* CONFIG_COMPAT */ + +/* Called before coming back to user-mode */ +asmlinkage void verify_pre_usermode_state(void) +{ +#ifdef CONFIG_VERIFY_PRE_USERMODE_STATE_BUG + BUG_ON(!segment_eq(get_fs(), USER_DS)); +#else + if (WARN_ON(!segment_eq(get_fs(), USER_DS))) + set_fs(USER_DS); +#endif +}