From patchwork Wed Jul 13 21:55:56 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kees Cook X-Patchwork-Id: 9228559 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 521CF60868 for ; Wed, 13 Jul 2016 21:58:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3D2AA28307 for ; Wed, 13 Jul 2016 21:58:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 31DFA28319; Wed, 13 Jul 2016 21:58: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=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED, T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id C661B28307 for ; Wed, 13 Jul 2016 21:58:58 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1bNS9r-0003np-Cx; Wed, 13 Jul 2016 21:57:31 +0000 Received: from mail-pf0-x22a.google.com ([2607:f8b0:400e:c00::22a]) by bombadil.infradead.org with esmtps (Exim 4.85_2 #1 (Red Hat Linux)) id 1bNS8z-0003Jt-Nt for linux-arm-kernel@lists.infradead.org; Wed, 13 Jul 2016 21:56:41 +0000 Received: by mail-pf0-x22a.google.com with SMTP id i123so22243859pfg.0 for ; Wed, 13 Jul 2016 14:56:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=dxYvPUVxi6pSu0SOwEYNrtiMsBux3QVE71bvXEOmctw=; b=b98TG9mIQkEXGpBPvd8OhIqN+oCEWuRik1uhBVx/FxKogfuwDDpHV6rrayr43TU7R4 hgHS6vYgWtdQK3Ww/jfCyVG5qRe8dcQFhxvbb1ByqdULtw0/NgRFiNLab/I+VZHFPCVZ RwvbIUb/QuM76Kwwk+gQBZnIND3bU2X/8XRng= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=dxYvPUVxi6pSu0SOwEYNrtiMsBux3QVE71bvXEOmctw=; b=XKcndZuZVKLe3KbSQF5+uO0jOEJhkJShJ/bMTIh0r3lM7+EG8b2fLOajhpuxc1Vgpu votpHR6mg10yFUi9gmOvsxRorkL9LBWo/Rh34HFmnlyQm8Ls+iyfUL1mvc2k/oegQ1dw azfH32wloLUnKlujpo44XdLZx2qoJS3YpsTJJ+aLLUYA0uihWI0ZHgCkGI3uWAZTXGjF Rv4CsVLRFM2Ns+tcX7EID8qXXlSKp2I5Yl8ISzkL+2f5My7Wfl5TBTngnMgdXhFoSggn htr2aY5WmFPL1+Y39uO+TEbXfHMax5qbqrQYzwCRnSfUEIkoX96yfSUYEsOu29U0HAwZ j42w== X-Gm-Message-State: ALyK8tI1TAnye54VDNG2tmQ3mftClWqY8lMudElj3U8nECp/FqwRecLj8Gu69HYCgnkvMJWl X-Received: by 10.98.2.208 with SMTP id 199mr7200418pfc.80.1468446975907; Wed, 13 Jul 2016 14:56:15 -0700 (PDT) Received: from www.outflux.net (173-164-112-133-Oregon.hfc.comcastbusiness.net. [173.164.112.133]) by smtp.gmail.com with ESMTPSA id br6sm5154900pac.0.2016.07.13.14.56.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 13 Jul 2016 14:56:14 -0700 (PDT) From: Kees Cook To: linux-kernel@vger.kernel.org Subject: [PATCH v2 03/11] x86/uaccess: Enable hardened usercopy Date: Wed, 13 Jul 2016 14:55:56 -0700 Message-Id: <1468446964-22213-4-git-send-email-keescook@chromium.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1468446964-22213-1-git-send-email-keescook@chromium.org> References: <1468446964-22213-1-git-send-email-keescook@chromium.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160713_145637_948952_7F7F567E X-CRM114-Status: GOOD ( 14.44 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Jan Kara , kernel-hardening@lists.openwall.com, Catalin Marinas , Will Deacon , linux-mm@kvack.org, sparclinux@vger.kernel.org, linux-ia64@vger.kernel.org, Christoph Lameter , Andrea Arcangeli , linux-arch@vger.kernel.org, Michael Ellerman , x86@kernel.org, Russell King , linux-arm-kernel@lists.infradead.org, Benjamin Herrenschmidt , PaX Team , Borislav Petkov , Mathias Krause , Fenghua Yu , Rik van Riel , Kees Cook , Vitaly Wool , David Rientjes , Tony Luck , Andy Lutomirski , Joonsoo Kim , Dmitry Vyukov , Laura Abbott , Brad Spengler , Ard Biesheuvel , Pekka Enberg , Casey Schaufler , Andrew Morton , linuxppc-dev@lists.ozlabs.org, "David S. Miller" 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 Enables CONFIG_HARDENED_USERCOPY checks on x86. This is done both in copy_*_user() and __copy_*_user() because copy_*_user() actually calls down to _copy_*_user() and not __copy_*_user(). Based on code from PaX and grsecurity. Signed-off-by: Kees Cook --- arch/x86/Kconfig | 2 ++ arch/x86/include/asm/uaccess.h | 10 ++++++---- arch/x86/include/asm/uaccess_32.h | 2 ++ arch/x86/include/asm/uaccess_64.h | 2 ++ 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 4407f596b72c..39d89e058249 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -80,11 +80,13 @@ config X86 select HAVE_ALIGNED_STRUCT_PAGE if SLUB select HAVE_AOUT if X86_32 select HAVE_ARCH_AUDITSYSCALL + select HAVE_ARCH_HARDENED_USERCOPY select HAVE_ARCH_HUGE_VMAP if X86_64 || X86_PAE select HAVE_ARCH_JUMP_LABEL select HAVE_ARCH_KASAN if X86_64 && SPARSEMEM_VMEMMAP select HAVE_ARCH_KGDB select HAVE_ARCH_KMEMCHECK + select HAVE_ARCH_LINEAR_KERNEL_MAPPING if X86_64 select HAVE_ARCH_MMAP_RND_BITS if MMU select HAVE_ARCH_MMAP_RND_COMPAT_BITS if MMU && COMPAT select HAVE_ARCH_SECCOMP_FILTER diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h index 2982387ba817..aa9cc58409c6 100644 --- a/arch/x86/include/asm/uaccess.h +++ b/arch/x86/include/asm/uaccess.h @@ -742,9 +742,10 @@ copy_from_user(void *to, const void __user *from, unsigned long n) * case, and do only runtime checking for non-constant sizes. */ - if (likely(sz < 0 || sz >= n)) + if (likely(sz < 0 || sz >= n)) { + check_object_size(to, n, false); n = _copy_from_user(to, from, n); - else if(__builtin_constant_p(n)) + } else if(__builtin_constant_p(n)) copy_from_user_overflow(); else __copy_from_user_overflow(sz, n); @@ -762,9 +763,10 @@ copy_to_user(void __user *to, const void *from, unsigned long n) might_fault(); /* See the comment in copy_from_user() above. */ - if (likely(sz < 0 || sz >= n)) + if (likely(sz < 0 || sz >= n)) { + check_object_size(from, n, true); n = _copy_to_user(to, from, n); - else if(__builtin_constant_p(n)) + } else if(__builtin_constant_p(n)) copy_to_user_overflow(); else __copy_to_user_overflow(sz, n); diff --git a/arch/x86/include/asm/uaccess_32.h b/arch/x86/include/asm/uaccess_32.h index 4b32da24faaf..7d3bdd1ed697 100644 --- a/arch/x86/include/asm/uaccess_32.h +++ b/arch/x86/include/asm/uaccess_32.h @@ -37,6 +37,7 @@ unsigned long __must_check __copy_from_user_ll_nocache_nozero static __always_inline unsigned long __must_check __copy_to_user_inatomic(void __user *to, const void *from, unsigned long n) { + check_object_size(from, n, true); return __copy_to_user_ll(to, from, n); } @@ -95,6 +96,7 @@ static __always_inline unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n) { might_fault(); + check_object_size(to, n, false); if (__builtin_constant_p(n)) { unsigned long ret; diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h index 2eac2aa3e37f..673059a109fe 100644 --- a/arch/x86/include/asm/uaccess_64.h +++ b/arch/x86/include/asm/uaccess_64.h @@ -54,6 +54,7 @@ int __copy_from_user_nocheck(void *dst, const void __user *src, unsigned size) { int ret = 0; + check_object_size(dst, size, false); if (!__builtin_constant_p(size)) return copy_user_generic(dst, (__force void *)src, size); switch (size) { @@ -119,6 +120,7 @@ int __copy_to_user_nocheck(void __user *dst, const void *src, unsigned size) { int ret = 0; + check_object_size(src, size, true); if (!__builtin_constant_p(size)) return copy_user_generic((__force void *)dst, src, size); switch (size) {