From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wm1-f50.google.com (mail-wm1-f50.google.com [209.85.128.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 69EF631353D for ; Wed, 31 Dec 2025 10:35:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.50 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767177320; cv=none; b=LxloJOidxNTIvvvZnj76eD6TxHCz/TgONCzmG2OK6D4vNKIkdNKmcCMY59OMCKVKHHTqByGT5d+hpRnMdDtFqSk7H6Pvys7/KXO3v+0guf2uZ9X20Poa63FtYxf+onBv3bzxLeoLDYqOg8L2ObRjDQlo3jKPR7wxOtkVE+3bRwo= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767177320; c=relaxed/simple; bh=ngvrqmbAfSOKPFNEwvQkQErVHESmImgxn2wZ4f27JTQ=; h=Date:From:To:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=BpAzCnbPk7UNFKV4W/SFy48uIkl2fDGthWxLb5joL//YdLE56XK3xAJ1Wy4UK8CkSvMRjCLaXtiiypo/hni/mjTgCgacYCweflfQNbmPXX7LTvUohkFh3fCDTehbopzgCrB8kWlBoGQWX/2WyDWeui5KXXaL+lrXdTZJDqxRel4= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=UIfZpLbA; arc=none smtp.client-ip=209.85.128.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="UIfZpLbA" Received: by mail-wm1-f50.google.com with SMTP id 5b1f17b1804b1-477563e28a3so65342915e9.1 for ; Wed, 31 Dec 2025 02:35:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1767177314; x=1767782114; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:subject:cc:to:from:date:from:to:cc:subject:date :message-id:reply-to; bh=BxgVjlzXoj/7VVIT7fpDBTaGCP9fmvaOXIxXQVrJfKk=; b=UIfZpLbA01p2NLYV7+lLruZdR2hPLfFCW/YC1Wop7uc2zgTGOTshTx0JMeHSPR0wEL eXVGVUmi3pO/2BveR6+baO8p5jTl69Qae4I4z8Iyt7+Mhwkf4I0UgIqZjWw0ELSdjlyr KcHTsNfsG3KRkMaZ7Gnp/thnFNY/pY2I79nJAIZpGbnO7fE+xw1CafFq3S8dAbbFlUPz gD6RD5affTFdQPEp2espEULrJAz065M+3e5qIXcLUMFbir6p4QTOqMbpPwrf4rkUJOak HYlsylqItIY/vUoM0SniRztqgwVLDu+H84eHCpANlNYGmWFLHqmaIC7Lh4p9rhi0//pJ qXcA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767177314; x=1767782114; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:subject:cc:to:from:date:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=BxgVjlzXoj/7VVIT7fpDBTaGCP9fmvaOXIxXQVrJfKk=; b=iuSRaswoiEfP7L2Z5es1ZLS5fOTFLrF81nJ2VwcJKK/PR6nUOCDBn7syZNoQcucT1x /iAye/sPZjROQyLe5lO2Sc0FtqHqHmb18AM1SJmGiMZl69EY2WqCRv6Dy+yAmOGyGcOt Z3uL/Qou14AJQxIM4ZxawCQpJHnrjYsoszAGHuA5j4xLaDnsHNoXKEHZ3/dDURGqScIB JZvB9MnyzW7e64/nZN0LVOBOn9B93b5gmmIDo78xNqsOqWKPq97NvAwtecnlNmNExLn6 xExp4zu9NSoiayGViEThCBAzURU57kuxnySsY0ur3ZfYgWieQ/4HexzPQsOeQsE2or4+ rC9A== X-Forwarded-Encrypted: i=1; AJvYcCWGzIyC1jMp54KuKHXc4G1ElhIN0hoa+PQJfIAakypnEgKITb5b2bYg7HgVv+jRbWjuzQexrllzbPgyYcQ=@vger.kernel.org X-Gm-Message-State: AOJu0YxJHYy8qEumacT/U06jtbbEucdEZGDCbdPUX4Ej2x8YuvF/G6Od 7zEKzPlOUMTUGuhLxpUrLphiCvNTYVurbYcyNzXdAX57furYG3BmYYs4 X-Gm-Gg: AY/fxX5fNvnjQ320RYG5bjMLOWHoziRAOiYC7GKXbe/BtW4upvSZOETG3nSQjHhDfeb kOl7utCRU3qSp35vKiRF1dz7x5JFqnNzyoQVteZJaU0pkD8piWGPqdCaS3DORzPJ5JFL4SDBAPw m694MXzkNPVMQvm0X5YYAivsOf0IS6aH68JXVz+YyLKhYzJ3bg4qkYw4+YGI2eLq/FCDPmrAtxU RtiI5Y1Ez17THFrBJxS0SHZuwMCgHTuxugVZLyHGzRDwR0r4JamYUA2va7zK54i76J4w2t2mEB7 Ze3dDjSJoV4Af9ax36jDNkDGC05GUxbnZRsAHcjFCM8PWhomXqPruS9ANFcCl0ZnmyOV8HsO+BC UgIG1qetFSwSFJpD2Og2UGLhXttBU+dyGhkfRfIIba+6Wpl6SvkKcbV5Ik6rVr+fs+OHRXYNBZT wYSfFB2OTthKD10Od+s+OjyGXmHxhiJVRoEfeOIWz1ATVKkqBWgrWg X-Google-Smtp-Source: AGHT+IGFZOTIgtWFSH0pU0VnrIeE7lu8+s32LkUBkL8YW4CdU6oEKIiSIf2E8TP6yxBnZSZw2e2I2Q== X-Received: by 2002:a05:600c:444d:b0:475:ddad:c3a9 with SMTP id 5b1f17b1804b1-47d18bdfc61mr473615595e9.13.1767177313452; Wed, 31 Dec 2025 02:35:13 -0800 (PST) Received: from pumpkin (82-69-66-36.dsl.in-addr.zen.co.uk. [82.69.66.36]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-47d19346dfcsm773106345e9.1.2025.12.31.02.35.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 31 Dec 2025 02:35:13 -0800 (PST) Date: Wed, 31 Dec 2025 10:35:11 +0000 From: David Laight To: Vivian Wang Cc: Deepak Gupta , Lukas Gerlach , linux-riscv@lists.infradead.org, palmer@dabbelt.com, pjw@kernel.org, aou@eecs.berkeley.edu, alex@ghiti.fr, linux-kernel@vger.kernel.org, daniel.weber@cispa.de, michael.schwarz@cispa.de, marton.bognar@kuleuven.be, jo.vanbulck@kuleuven.be Subject: Re: [PATCH 1/2] riscv: Use pointer masking to limit uaccess speculation Message-ID: <20251231103511.5ddb768b@pumpkin> In-Reply-To: References: <20251218191332.35849-1-lukas.gerlach@cispa.de> <20251218191332.35849-2-lukas.gerlach@cispa.de> <20251227212859.3a83d65e@pumpkin> <20251228223430.43f14d51@pumpkin> <20251229123212.25ef3c4b@pumpkin> X-Mailer: Claws Mail 4.1.1 (GTK 3.24.38; arm-unknown-linux-gnueabihf) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit On Wed, 31 Dec 2025 11:47:16 +0800 Vivian Wang wrote: > On 12/29/25 20:32, David Laight wrote: > > On Sun, 28 Dec 2025 22:34:30 +0000 > > David Laight wrote: > > > >> On Sat, 27 Dec 2025 17:59:38 -0800 > >> Deepak Gupta wrote: > >> > >>> On Sat, Dec 27, 2025 at 09:28:59PM +0000, David Laight wrote: > >>>> On Fri, 19 Dec 2025 16:44:11 -0800 > >>>> Deepak Gupta wrote: > >>>> > >>>>> On Thu, Dec 18, 2025 at 08:13:31PM +0100, Lukas Gerlach wrote: > >>>>>> Similarly to x86 and arm64, mitigate speculation past an access_ok() > >>>>>> check by masking the pointer before use. > >>>>>> > >>>>>> On RISC-V, user addresses have the MSB clear while kernel addresses > >>>>>> have the MSB set. The uaccess_mask_ptr() function clears the MSB, > >>>>>> ensuring any kernel pointer becomes invalid and will fault, while > >>>>>> valid user pointers remain unchanged. This prevents speculative > >>>>>> access to kernel memory via user copy functions. > >>>>>> > >>>>>> The masking is applied to __get_user, __put_user, raw_copy_from_user, > >>>>>> raw_copy_to_user, clear_user, and the unsafe_* variants. > >>>>>> > >>>>>> Signed-off-by: Lukas Gerlach > >>>>>> --- > >>>>>> arch/riscv/include/asm/uaccess.h | 41 +++++++++++++++++++++++++------- > >>>>>> 1 file changed, 32 insertions(+), 9 deletions(-) > >>>>>> > >>>>>> diff --git a/arch/riscv/include/asm/uaccess.h b/arch/riscv/include/asm/uaccess.h > >>>>>> index 36bba6720c26..ceee1d62ff9b 100644 > >>>>>> --- a/arch/riscv/include/asm/uaccess.h > >>>>>> +++ b/arch/riscv/include/asm/uaccess.h > >>>>>> @@ -74,6 +74,23 @@ static inline unsigned long __untagged_addr_remote(struct mm_struct *mm, unsigne > >>>>>> #define __typefits(x, type, not) \ > >>>>>> __builtin_choose_expr(sizeof(x) <= sizeof(type), (unsigned type)0, not) > >>>>>> > >>>>>> +/* > >>>>>> + * Sanitize a uaccess pointer such that it cannot reach any kernel address. > >>>>>> + * > >>>>>> + * On RISC-V, virtual addresses are sign-extended from the top implemented bit. > >>>>>> + * User addresses have the MSB clear; kernel addresses have the MSB set. > >>>>>> + * Clearing the MSB ensures any kernel pointer becomes non-canonical and will > >>>>>> + * fault, while valid user pointers remain unchanged. > >>>>>> + */ > >>>>>> +#define uaccess_mask_ptr(ptr) ((__typeof__(ptr))__uaccess_mask_ptr(ptr)) > >>>>>> +static inline void __user *__uaccess_mask_ptr(const void __user *ptr) > >>>>>> +{ > >>>>>> + unsigned long val = (unsigned long)ptr; > >>>>>> + > >>>>>> + val = (val << 1) >> 1; > >>>>>> + return (void __user *)val; > >>>>> This is only clearing b63 which is what we don't need here. > >>>> It is also entirely the wrong operation. > >>>> A kernel address needs converting into an address that is guaranteed > >>>> to fault - not a user address that might be valid. > >>> This is about speculative accesses and not actual accesses. Due to some > >>> speculation it is possible that in speculative path a wrong address is > >>> generated with MSB=1. This simply ensures that bit is cleared for agen > >>> even in speculative path. > >> You said you were following what x86 did - this isn't what is does. > >> Avoiding the conditional branch in access_ok() is actually a big win. > >> That is true even without the issues with speculative accesses to kernel > >> memory. > >> The 'address masking' (badly named - it isn't just masking) is a replacement > >> for access_ok(), it changes kernel addresses to invalid ones so that the > >> access faults and the trap/fault fixup code detects the error. > > If you can guarantee that address 0 is never mapped into userspace > > (not true for x86 for historic reasons) then I think you can convert > > kernel addresses to zero - which will then fault. > > This is simpler than using the base of the guard page (which is still > > needed for sequential accesses). > > Something like: > > addr &= (addr >= guard_page) - 1; > > will then work - but it needs (partially) coding in assembler to > > guarantee that 'setae' (or equivalent) is used rather than a > > conditional branch. > > > > Maybe use: > > addr |= (long)addr >> 63 > > To map kernel addresses to -1? That also requires that address 0 is never mapped into userspace. The first access might be offset from the actual base address. (It is too hard to check that code accesses the first member of a structure first - and some obvious candidate bits of code don't.) There are also issues on x86-64 (I think amd cpu) which mean that just testing the high bit isn't good enough, the check has to use the highest valid user address (ie one below the 'big address hole'). Linus added to code to patch the correct constant into the comparison instruction in order to avoid a memory read because a different limit is needed to 4 and 5 level page tables. Whether that applies to riscv is another matter, but if the hardware actually uses a lower bit to select kernel addresses (perhaps in parallel with validating that the top few bits are all the same) then you do need to compare against the top user address. I suspect that if you don't do it now, at some point there'll be an 'issue' that needs the correct limit address used. David