Received: by 2002:a05:6a10:9848:0:0:0:0 with SMTP id x8csp3326975pxf; Mon, 5 Apr 2021 09:07:04 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzXGwetGpoq5RxLkj+k5cuGMBtGYAxSYbD7+mg0wUjcNr/2THHHFWcIr10MkweWjNKxXW8q X-Received: by 2002:a17:906:729d:: with SMTP id b29mr6606708ejl.243.1617638824261; Mon, 05 Apr 2021 09:07:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1617638824; cv=none; d=google.com; s=arc-20160816; b=x0RccE+2rjD8jA51+wge8zwzv+aniuoU0GV3tBJEMyF1BcZ1aZl8vKmSjQG9zR7xmV iKNmmLyWm3avGfF5uerInjG44asD4OKszangOFoW/x8pkUiawBIoO3ZucSAfAyFp1/xs viDO7Or63U/b89xM2iy8oU7Lie0+P5KmHGKk8zBVydXIkOts7l+XVHM2BqxPaBwaGDSX 374ef9+PqnCebaSqnpnbb/hNA2thnnmTznDBzZcrrAha1js8oULO023CeWVr3QMd6Wqs hiP3eB3P25zmQ6MwTqUFpq2Wnrs1MFmV32f0YXbBB4DQwht3Tb6L8R3bJUL2LMYhaQHC vDMw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=99rEbVrrgY/ikwWcWt8+ZEjmow+SMiWzGsizFs9Ps/I=; b=0tTrpXiit8luLMxyeK5IZ6zSgD5/tzKJf8j8IqMXFONGauRuSuqN2xbdh0tIJ8ia6F 36YOFK2EmI+1pNEaa4ql1auACp6za5E2m/MuycMDIRZjKakfzm+mBdWPryrbtimReqDP JBpVCDzMpDI8wbQBwbR0gehWjqzlxfwzCDtimYwN/eDiXZ6c8EdOw03PH110aVPIT/Fo CacQ+VHNqv1yKpFqj2PdQdUxQKCC0lyjh70KuF3P/zGPX+8x+lB5JliVzq8JsshAyH4U eaCZs6Fhd5Ys2W1/cpMUqMbGf8S1uDOCOON79Ll+CwHoOp2z4+dk00PD3k/odOKo995U MiEQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=gQBdoiCp; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id ce25si5124881ejb.93.2021.04.05.09.06.41; Mon, 05 Apr 2021 09:07:04 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=gQBdoiCp; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240277AbhDEJO5 (ORCPT + 99 others); Mon, 5 Apr 2021 05:14:57 -0400 Received: from mail.kernel.org ([198.145.29.99]:58410 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238871AbhDEJLb (ORCPT ); Mon, 5 Apr 2021 05:11:31 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 026C2613B0; Mon, 5 Apr 2021 09:11:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1617613872; bh=TLfNtit7mxypnT50eV012j8QyfYlr8lSJ2xARyOlL5A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gQBdoiCpGYLZoN2OdWBU0Sy2glJLX3CyiC4jX5PN9qh4No4o/BT6iacxLyNvwHEO4 qJ4ubhtt7fB8av7olLG+b+ZZkxPQyu+DHkuXMytL36M1jtpJHhizR5R9YjR9gtWhVp 8XJNzo/cs99wKLBL4fU8HyHyG4cyNHXmMtxfu4os= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Ben Dooks , syzbot+e74b94fe601ab9552d69@syzkaller.appspotmail.com, Arnd Bergman , Palmer Dabbelt Subject: [PATCH 5.10 124/126] riscv: evaluate put_user() arg before enabling user access Date: Mon, 5 Apr 2021 10:54:46 +0200 Message-Id: <20210405085035.132419500@linuxfoundation.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210405085031.040238881@linuxfoundation.org> References: <20210405085031.040238881@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Ben Dooks commit 285a76bb2cf51b0c74c634f2aaccdb93e1f2a359 upstream. The header has a problem with put_user(a, ptr) if the 'a' is not a simple variable, such as a function. This can lead to the compiler producing code as so: 1: enable_user_access() 2: evaluate 'a' into register 'r' 3: put 'r' to 'ptr' 4: disable_user_acess() The issue is that 'a' is now being evaluated with the user memory protections disabled. So we try and force the evaulation by assigning 'x' to __val at the start, and hoping the compiler barriers in enable_user_access() do the job of ordering step 2 before step 1. This has shown up in a bug where 'a' sleeps and thus schedules out and loses the SR_SUM flag. This isn't sufficient to fully fix, but should reduce the window of opportunity. The first instance of this we found is in scheudle_tail() where the code does: $ less -N kernel/sched/core.c 4263 if (current->set_child_tid) 4264 put_user(task_pid_vnr(current), current->set_child_tid); Here, the task_pid_vnr(current) is called within the block that has enabled the user memory access. This can be made worse with KASAN which makes task_pid_vnr() a rather large call with plenty of opportunity to sleep. Signed-off-by: Ben Dooks Reported-by: syzbot+e74b94fe601ab9552d69@syzkaller.appspotmail.com Suggested-by: Arnd Bergman Signed-off-by: Greg Kroah-Hartman -- Changes since v1: - fixed formatting and updated the patch description with more info Changes since v2: - fixed commenting on __put_user() (schwab@linux-m68k.org) Change since v3: - fixed RFC in patch title. Should be ready to merge. Signed-off-by: Palmer Dabbelt --- arch/riscv/include/asm/uaccess.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) --- a/arch/riscv/include/asm/uaccess.h +++ b/arch/riscv/include/asm/uaccess.h @@ -306,7 +306,9 @@ do { \ * data types like structures or arrays. * * @ptr must have pointer-to-simple-variable type, and @x must be assignable - * to the result of dereferencing @ptr. + * to the result of dereferencing @ptr. The value of @x is copied to avoid + * re-ordering where @x is evaluated inside the block that enables user-space + * access (thus bypassing user space protection if @x is a function). * * Caller must check the pointer with access_ok() before calling this * function. @@ -316,12 +318,13 @@ do { \ #define __put_user(x, ptr) \ ({ \ __typeof__(*(ptr)) __user *__gu_ptr = (ptr); \ + __typeof__(*__gu_ptr) __val = (x); \ long __pu_err = 0; \ \ __chk_user_ptr(__gu_ptr); \ \ __enable_user_access(); \ - __put_user_nocheck(x, __gu_ptr, __pu_err); \ + __put_user_nocheck(__val, __gu_ptr, __pu_err); \ __disable_user_access(); \ \ __pu_err; \