From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wr1-f50.google.com (mail-wr1-f50.google.com [209.85.221.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 57C3D2882B4 for ; Sun, 28 Dec 2025 22:34:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.50 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766961276; cv=none; b=gm7WVm7vHe2hd4jQDWGcQdDBuH4n2Ke+A6tAo1ENyYLnAk7ZTlcMUh+wHW+qKB1xQDvu4b9mxQGs8/NlLqkpae8ZgoRVNpTRLjbBRyaA2ZtwUeOcuI0QFu1lHU2oAGQqJBJyfjwxERzZqh48IrV4CdQrIs0l2MHWL2GnM3V110o= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766961276; c=relaxed/simple; bh=iZzId3WjYEwQr+67B0DfelFHBLkDr8K9QZLgl/w8H7w=; h=Date:From:To:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=KStknK/YQYKsNO6EXkDSd1Xo922bfG7rnDHXElrtsdUAnAXG/eXWCuCD24g8CyeVoJBzB1Ehb6NRBMomq1Uw95/y6ZsJ1F6XUZ6uGk2AyIQ1ZJKx4u5oGZ9tIC5MVqGbVzipp5EbSZIsyuPqFN8v618Rc+mJJq+wbfiwRtKAgsI= 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=iDk2lhz2; arc=none smtp.client-ip=209.85.221.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="iDk2lhz2" Received: by mail-wr1-f50.google.com with SMTP id ffacd0b85a97d-42fb2314f52so4774133f8f.0 for ; Sun, 28 Dec 2025 14:34:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1766961272; x=1767566072; 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=NXjZf+tn3B3Qabds0F1z0VkO28kPzyfD3esGmMbwL7c=; b=iDk2lhz2wr9TE7n0WocFvUNbQ9GJF3pBYHNCjXK4OCrluk9oXcxHtQr5gX+a1zwNRl GIt/nEidN9GBqSFh6OokZ24gDqYDWaLrLW4h0vf88myTKefaeos3OBy6TZoZWKNKGtiS GDT/vhfNDncQ3M9wq5dWVDmMRSFGUCnsGmBUImvRPrD4waCZix5x8zMglQ5Oo2LLmoVX JT9icUH1OhKC0FryrK0K1JApjEfDqL4nViPVFrtntFxOmjzFTSQRpCqGS/OKAP7lb1g8 bb9jOSb1od9Hf4mZctwBb0nnLSgGrR03hctMsJt6/vw26gh5+NFJRDjqUQlkVhBwOYtH fhOQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1766961272; x=1767566072; 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=NXjZf+tn3B3Qabds0F1z0VkO28kPzyfD3esGmMbwL7c=; b=hgpck3lwPA2fYlTSb9sHLujKHYDQWjFt55ojG5Jh/VPLLpms3jyOxpqbCjKMI8nsn6 EMoOMauc2W3YPMMIbV44QHb1aGUlCVoAw+cwbveMYaN6nSc5xXeeCu4XFAGXVJIPUH6V CO/2HVbxmHvh2aYQwfNl5TB+vLiUZLwGzpuTOgrItN2Xkk0cHWdblkgP09WK9P285u+r vrteEfsmbwhMJoQNyR77DTpbTh7vRqKYc1MJH5kFbJXI3DGC30ZiluTxeXRTekUOdyBk GDxRiL+uyTfXfc3lqZY0cti+RJofMTTGNBvPZh2/H2NFgpDfkEpwlzpN/wWv1j6ueFnP tH/g== X-Forwarded-Encrypted: i=1; AJvYcCWV4IhvJQ/FERMeoi5nFqIHgubWt8+P6ldgM+fauyMUPm2Tx1wYTw7tuYVE/6yL54ie6EoJn1ZJWq4BXxE=@vger.kernel.org X-Gm-Message-State: AOJu0Yw9kiLXYpK0Cb9AaDDZ+Ghx2iBRYQxAFqV4vI8sz5/z7Elm9xEs K8tyOJynxaGzOB7CnbW500zyFB6P+Z4B2oFHFfMOqzjWNpA1Hgvppl7C X-Gm-Gg: AY/fxX66pKgrhL5rknLv9l3XdS/hHfU4s9nBmFZ2vGZD8/z7Jtd9MNw4IOaMHrqbPXZ yffvxASjtbS5RsPLbVidXMb065Iiy3wvzbN2OQQJJI7IWGCylL5A0Qpvz+JgHbafh6lWiolMBd0 0p5a0PUca1zSnc07for1EXeBEBHREm76x2jUKNPJHkPvfPDYOUvyGS2xDErKRPZeiuOCCcaWm9R aeTz0NfwSs79iTfk7ovYfQUY+ZwVzSyQM2pJToizhzG1K15fxiyfnkpbCLbfwhlZafZWtif1/GM OmMeLUhMPqhGffGSeGLk0Pi/nV7k2G/qXUp0CYGd9Yy7oolsRtrpwiOiXK+WZEWOIxvT4bSxrkR tZlwRhVNtEi6W3y73uN9oLme7BiMCha4PQN5Uk6ow92iGUjIJBY7ZbeeaXkafkUX08I7IMOLy0M Y/bUugpV7aN4OjGqJBTIwaZwJb75J5fM6lZV1BLOUJgQzX6G3DPg/Z X-Google-Smtp-Source: AGHT+IFoq4x6do98drZk2/+TsAmmyZxgFWNlbbcTlwdADP+61k5uWEghVQlJcCQJSCQ8JKhIGVdnCw== X-Received: by 2002:a05:6000:4024:b0:42f:b9c6:c894 with SMTP id ffacd0b85a97d-4324e70957dmr33395938f8f.52.1766961272230; Sun, 28 Dec 2025 14:34:32 -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 ffacd0b85a97d-43264613923sm43242644f8f.26.2025.12.28.14.34.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 28 Dec 2025 14:34:31 -0800 (PST) Date: Sun, 28 Dec 2025 22:34:30 +0000 From: David Laight To: Deepak Gupta Cc: 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: <20251228223430.43f14d51@pumpkin> In-Reply-To: References: <20251218191332.35849-1-lukas.gerlach@cispa.de> <20251218191332.35849-2-lukas.gerlach@cispa.de> <20251227212859.3a83d65e@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 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. David > > > > >You need a guard page of address space between valid user addresses > >and valid kernel addresses that is guaranteed to not be used. > > IIUC, risc-v does that already (last user page is unmapped and first > kernel page is unmapped). > > >Typically this is the top page of the user address space. > >All kernel addresses need converting to the base of the guard page > >using ALU operations (to avoid speculative accesses). > >So: ptr = min(ptr, guard_page); easiest done (as in x86-64) with > >a compare and conditional move. > >The ppc version is more complex because there isn't a usable conditional > >move instruction. > >I think this would work for x86-32: > > offset = ptr + -guard_page; > > mask = sbb(x,x); // ~0u if the add set the carry flag. > > ptr -= offset & mask; > >You need to find something that works for riscv. > > I believe what you're describing is `access_ok` in x86. `__access_ok` in > `asm-generic/access_ok.h` should cover same behavior for risc-v. > > > > >> > >> You should be clearing b47 (if bit indexing starts at 0) on Sv48 and b56 > >> on Sv57 system. > >> > >> Anything above b47/b56 isn't going to be used anyways in indexing into > >> page tables and will be ignored if pointer masking is enabled at S. > > > >Gah more broken hardware... > >Ignoring the high address bits doesn't work and is really a bad idea. > >Arm did it as well. > >Trying to do 'user pointer masking' for uaccess validation is a PITA > >if you have to allow for non-zero values in the high bits it makes > >life even more complicated. > > Pointer masking and preventing speculative accesses to kernel addresses > are two different things (although they're related because they impact > address generation part). > > Kernel may not have pointer masking enabled and in that case, it'll just > trap if high unused bits don't match b38/47/56. To accomodate that, there > already are patches in riscv to remove the tag in high unused bits before > access is made by the kernel. > > > > >And 'pointer masking' is so broken unless it is done at the page level > >and enforced by the hardware. > >What it does is make random/invalid addresses much more likely to be valid. > >An interpreter can use them internally, but they are so slow software > >masking (following the validation) shouldn't be a real issue. > > > > David > > > >