From patchwork Wed Feb 15 20:05:57 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kees Cook X-Patchwork-Id: 9574969 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 68B7B60493 for ; Wed, 15 Feb 2017 20:06:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5445028530 for ; Wed, 15 Feb 2017 20:06:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4641C28533; Wed, 15 Feb 2017 20:06:24 +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_SIGNED, DKIM_VALID autolearn=unavailable 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 C7F9C28530 for ; Wed, 15 Feb 2017 20:06:23 +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:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-ID:Subject:To:From :Date: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=j6YPudW7fbOtjslyX+wQxY817/jehjEJhl1m46TcqOs=; b=RcIAbfXqf0sQo0 Ax7R9HZTy8Hkex69aeBPmWq4BeZix7YNEjXtwLDTxqAFihscp9q7sBOA64dqNamO88PLAWKO9qmCI PIvGYc44hnfL3TQaVtLB3R59X7qq1j/Tv2WPM7qidvQwLfONMXvJYvoVo+3oo4VVli8sjY98fmnf4 OWwfGzvOu+slCdEb2MnqjV21Y6lP0a6nRRKIlk4RS61T9OLtrExludmb/+FkS9ic80R1dcGkWI5ne tB7I0TQganpWb15pyLkqCFy+N9D12hp4SJT+mowmVQURFTidCPJApysieFg1pPfSqoiko1O+A76oG F/Jq4YW1t+BZBkTkhetw==; 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 1ce5qJ-00028t-Hn; Wed, 15 Feb 2017 20:06:23 +0000 Received: from mail-pg0-x235.google.com ([2607:f8b0:400e:c05::235]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1ce5qG-00025b-AC for linux-arm-kernel@lists.infradead.org; Wed, 15 Feb 2017 20:06:22 +0000 Received: by mail-pg0-x235.google.com with SMTP id v184so39406701pgv.3 for ; Wed, 15 Feb 2017 12:05:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=date:from:to:cc:subject:message-id:mime-version:content-disposition; bh=gH+qRmGo7+F/+33AKmVBlFPuhZhqrX1at7o2gAVvUuE=; b=OOdGcBb/QSsjrXZ6xqzOdXQsYN9mmMPQEdUOCSdm+9RVIFiHBeOoqMlyzkaNEnuq3o 1pMzYs/3Vwb1+KNCa8J3Nq5NfyQVzTUrrdCZQd2BPilfmnPReJLsYli09RRkSJh+roxN utRDArKObm/saEb1PI3gSGopcrOuy6Iwr/Eoc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:mime-version :content-disposition; bh=gH+qRmGo7+F/+33AKmVBlFPuhZhqrX1at7o2gAVvUuE=; b=flmZ3a/dd4eGrAg3TMr90YaqHUbXGudebsfsMxIrI+tpEUBlVV6ycN62f5M/buktK8 GDpeLv+Kj/2uuY0ToMnwgwO2CXmX2XnJJ9vX/lKZl3NH8qxk0Vo9wqfBUopELjvAdxOj uKiVRGkQBHIXODmlW8Zz89PuHMXD7Qul4eZq2GoSN3tKx/hdRie2zLhIdbt7IKKj7CZY ClhX5nqRdCqS9rGDudEmiFZX/uNLuveAWEAqhPkjBAnZcSWxj9AZVW56qeKdD4zutx9q UUmkPt9SOrSIy5bePFG9lEPGs1GM85ObN05Ykv6+TaTy8DPGec1NOIMqMQAGIJV0rgaa /kFw== X-Gm-Message-State: AMke39k1u2/vTs6Y/7ox5bnRfC7mTu7RF4b7pmFbIb9Ua/5EiEUfOgYPD4NL47W1Y1LeVN6E X-Received: by 10.84.138.3 with SMTP id 3mr45413067plo.94.1487189159058; Wed, 15 Feb 2017 12:05:59 -0800 (PST) Received: from www.outflux.net ([2002:ada4:7085:0:c85a:f398:24d9:733e]) by smtp.gmail.com with ESMTPSA id p25sm9147169pfd.0.2017.02.15.12.05.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 15 Feb 2017 12:05:58 -0800 (PST) Date: Wed, 15 Feb 2017 12:05:57 -0800 From: Kees Cook To: Russell King Subject: [PATCH] ARM: uaccess: consistently check object sizes Message-ID: <20170215200557.GA37325@beast> MIME-Version: 1.0 Content-Disposition: inline X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170215_120620_410778_AF0EA4ED X-CRM114-Status: GOOD ( 12.35 ) 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: Mark Rutland , kernel-hardening@lists.openwall.com, linux-kernel@vger.kernel.org, Al Viro , Robin Murphy , linux-arm-kernel@lists.infradead.org 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 In commit 76624175dcae ("arm64: uaccess: consistently check object sizes"), the object size checks are moved outside the access_ok() so that bad destinations are detected before hitting the "memset(dest, 0, size)" in the copy_from_user() failure path. This makes the same change for arm, with attention given to possibly extracting the uaccess routines into a common header file for all architectures in the future. Suggested-by: Mark Rutland Signed-off-by: Kees Cook Acked-by: Mark Rutland --- arch/arm/include/asm/uaccess.h | 44 ++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h index 1f59ea051bab..b7e0125c0bbf 100644 --- a/arch/arm/include/asm/uaccess.h +++ b/arch/arm/include/asm/uaccess.h @@ -478,11 +478,10 @@ extern unsigned long __must_check arm_copy_from_user(void *to, const void __user *from, unsigned long n); static inline unsigned long __must_check -__copy_from_user(void *to, const void __user *from, unsigned long n) +__arch_copy_from_user(void *to, const void __user *from, unsigned long n) { unsigned int __ua_flags; - check_object_size(to, n, false); __ua_flags = uaccess_save_and_enable(); n = arm_copy_from_user(to, from, n); uaccess_restore(__ua_flags); @@ -495,18 +494,15 @@ extern unsigned long __must_check __copy_to_user_std(void __user *to, const void *from, unsigned long n); static inline unsigned long __must_check -__copy_to_user(void __user *to, const void *from, unsigned long n) +__arch_copy_to_user(void __user *to, const void *from, unsigned long n) { #ifndef CONFIG_UACCESS_WITH_MEMCPY unsigned int __ua_flags; - - check_object_size(from, n, true); __ua_flags = uaccess_save_and_enable(); n = arm_copy_to_user(to, from, n); uaccess_restore(__ua_flags); return n; #else - check_object_size(from, n, true); return arm_copy_to_user(to, from, n); #endif } @@ -526,25 +522,49 @@ __clear_user(void __user *addr, unsigned long n) } #else -#define __copy_from_user(to, from, n) (memcpy(to, (void __force *)from, n), 0) -#define __copy_to_user(to, from, n) (memcpy((void __force *)to, from, n), 0) +#define __arch_copy_from_user(to, from, n) \ + (memcpy(to, (void __force *)from, n), 0) +#define __arch_copy_to_user(to, from, n) \ + (memcpy((void __force *)to, from, n), 0) #define __clear_user(addr, n) (memset((void __force *)addr, 0, n), 0) #endif -static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n) +static inline unsigned long __must_check +__copy_from_user(void *to, const void __user *from, unsigned long n) +{ + check_object_size(to, n, false); + return __arch_copy_from_user(to, from, n); +} + +static inline unsigned long __must_check +copy_from_user(void *to, const void __user *from, unsigned long n) { unsigned long res = n; + + check_object_size(to, n, false); + if (likely(access_ok(VERIFY_READ, from, n))) - res = __copy_from_user(to, from, n); + res = __arch_copy_from_user(to, from, n); if (unlikely(res)) memset(to + (n - res), 0, res); return res; } -static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n) +static inline unsigned long __must_check +__copy_to_user(void __user *to, const void *from, unsigned long n) { + check_object_size(from, n, true); + + return __arch_copy_to_user(to, from, n); +} + +static inline unsigned long __must_check +copy_to_user(void __user *to, const void *from, unsigned long n) +{ + check_object_size(from, n, true); + if (access_ok(VERIFY_WRITE, to, n)) - n = __copy_to_user(to, from, n); + n = __arch_copy_to_user(to, from, n); return n; }