From patchwork Fri Nov 3 23:04:25 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laura Abbott X-Patchwork-Id: 10041327 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 4C2B4600C5 for ; Fri, 3 Nov 2017 23:04:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3E84429921 for ; Fri, 3 Nov 2017 23:04:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3284429924; Fri, 3 Nov 2017 23:04:48 +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.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from mother.openwall.net (mother.openwall.net [195.42.179.200]) by mail.wl.linuxfoundation.org (Postfix) with SMTP id 4DBA629921 for ; Fri, 3 Nov 2017 23:04:46 +0000 (UTC) Received: (qmail 24459 invoked by uid 550); 3 Nov 2017 23:04:44 -0000 Mailing-List: contact kernel-hardening-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Delivered-To: mailing list kernel-hardening@lists.openwall.com Received: (qmail 24433 invoked from network); 3 Nov 2017 23:04:43 -0000 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:in-reply-to; bh=hIuH7feV/3Yr2tCufVteXry0sJPILfzRI2ezezib8uc=; b=fQxNLDQUMDvC9y3WuxyL2pw7PP0uOASO5gEXpPHxUtebiW3+D/ulgTeBOwrr5XiDmb HnNNf5KV5YFnww1VeXtltOnn0Wg0Ci1+e5bggr6UHOBTqn72BTlMOz6twWBrOdj89r6A 309CMRb+v4A5XUAeGgWBb/ZmjEoqDTYH4UCatrrFhRuE+aPBaADpzBhi5ow4NibZwn8C npkWyxrOwpFuAo7AOz5IVvbrq9iiLNUdeDjzCenI/hc1S95DNLefQ6NTROVFs9kxzSZ6 +8cZ/jgEJeJobG/HWKy8o1tYjk/uJe9H4hOhXxEwru2Jnpc1P/ehIsvOM64QRwAvgvoz C5/w== X-Gm-Message-State: AMCzsaXEBc36sNyhne4/F/RWajYKUPhkjgGHzay74/4biIqkujAQNSKq +1xO4Lz8+gLXz2a6kUtdrqfX5tnDvQg= X-Google-Smtp-Source: ABhQp+S/cqiiCJ7dsPqbMp3UQTzLkWIaXTBLbNlt77FK8OR3sPGI5DMq6uLCS+99qkYzxmt/vX58XQ== X-Received: by 10.202.89.134 with SMTP id n128mr4964874oib.64.1509750271227; Fri, 03 Nov 2017 16:04:31 -0700 (PDT) From: Laura Abbott To: kernel-hardening@lists.openwall.com Cc: Laura Abbott , linux-kernel@vger.kernel.org, Mark Rutland , Kees Cook , x86@kernel.org Date: Fri, 3 Nov 2017 16:04:25 -0700 Message-Id: <20171103230426.19114-1-labbott@redhat.com> X-Mailer: git-send-email 2.13.5 In-reply-to: <20171026090942.7041-1-mark.rutland@arm.com> Subject: [kernel-hardening] [RFC PATCH 1/2] x86: Avoid multiple evaluations in __{get, put}_user_size X-Virus-Scanned: ClamAV using ClamSMTP Currently __{get,put}_user_size() expand their ptr argument in several places, and some callers pass in expressions with side effects. For example, fs/binfmt_elf.c, passes sp++ as the ptr argument to a chain of __put_user() calls. So far this isn't a problem, as each of these uses is mutually exclusive. However, in subsequent patches we will need to make use of the ptr argument several times, and ensure that we evaluate the ptr expression exactly once to avoid corrupting the pointer. In preparation for such uses, this patch reorganises __{get,put}_user_size to evaluate the ptr argument into a temporary __{gu,pu}_ptr variable, ensuring that side-effects occur exaclty once. There should be no functional change as a result of this patch. Based on work done for arm64 by Mark Rutland. Signed-off-by: Laura Abbott --- This is setup patch for checking __{get,put}_user on x86 based on Mark Rutland's work for arm64 lkml.kernel.org/r/<20171026090942.7041-1-mark.rutland@arm.com> --- arch/x86/include/asm/uaccess.h | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h index 574dff4d2913..d23fb5844404 100644 --- a/arch/x86/include/asm/uaccess.h +++ b/arch/x86/include/asm/uaccess.h @@ -275,21 +275,25 @@ extern void __put_user_8(void); #define __put_user_size(x, ptr, size, retval, errret) \ do { \ + typeof(ptr) __pu_ptr = (ptr); \ retval = 0; \ - __chk_user_ptr(ptr); \ + __chk_user_ptr(__pu_ptr); \ switch (size) { \ case 1: \ - __put_user_asm(x, ptr, retval, "b", "b", "iq", errret); \ + __put_user_asm(x, __pu_ptr, retval, "b", "b", "iq", \ + errret); \ break; \ case 2: \ - __put_user_asm(x, ptr, retval, "w", "w", "ir", errret); \ + __put_user_asm(x, __pu_ptr, retval, "w", "w", "ir", \ + errret); \ break; \ case 4: \ - __put_user_asm(x, ptr, retval, "l", "k", "ir", errret); \ + __put_user_asm(x, __pu_ptr, retval, "l", "k", "ir", \ + errret); \ break; \ case 8: \ - __put_user_asm_u64((__typeof__(*ptr))(x), ptr, retval, \ - errret); \ + __put_user_asm_u64((__typeof__(*ptr))(x), __pu_ptr, \ + retval, \ errret); \ break; \ default: \ __put_user_bad(); \ @@ -352,20 +356,24 @@ do { \ #define __get_user_size(x, ptr, size, retval, errret) \ do { \ + typeof(ptr) __gu_ptr = (ptr); \ retval = 0; \ - __chk_user_ptr(ptr); \ + __chk_user_ptr(__gu_ptr); \ switch (size) { \ case 1: \ - __get_user_asm(x, ptr, retval, "b", "b", "=q", errret); \ + __get_user_asm(x, __gu_ptr, retval, "b", "b", "=q", \ + errret); \ break; \ case 2: \ - __get_user_asm(x, ptr, retval, "w", "w", "=r", errret); \ + __get_user_asm(x, __gu_ptr, retval, "w", "w", "=r", \ + errret); \ break; \ case 4: \ - __get_user_asm(x, ptr, retval, "l", "k", "=r", errret); \ + __get_user_asm(x, __gu_ptr, retval, "l", "k", "=r", \ + errret); \ break; \ case 8: \ - __get_user_asm_u64(x, ptr, retval, errret); \ + __get_user_asm_u64(x, __gu_ptr, retval, errret); \ break; \ default: \ (x) = __get_user_bad(); \