public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Jisheng Zhang <jszhang@kernel.org>
To: Paul Walmsley <paul.walmsley@sifive.com>,
	Palmer Dabbelt <palmer@dabbelt.com>,
	Albert Ou <aou@eecs.berkeley.edu>
Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org
Subject: [PATCH 1/4] riscv: implement user_access_begin and families
Date: Tue, 25 Jun 2024 12:04:57 +0800	[thread overview]
Message-ID: <20240625040500.1788-2-jszhang@kernel.org> (raw)
In-Reply-To: <20240625040500.1788-1-jszhang@kernel.org>

Currently, when a function like strncpy_from_user() is called,
the userspace access protection is disabled and enabled
for every word read.

By implementing user_access_begin and families, the protection
is disabled at the beginning of the copy and enabled at the end.

The __inttype macro is borrowed from x86 implementation.

Signed-off-by: Jisheng Zhang <jszhang@kernel.org>
---
 arch/riscv/include/asm/uaccess.h | 63 ++++++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)

diff --git a/arch/riscv/include/asm/uaccess.h b/arch/riscv/include/asm/uaccess.h
index 72ec1d9bd3f3..09d4ca37522c 100644
--- a/arch/riscv/include/asm/uaccess.h
+++ b/arch/riscv/include/asm/uaccess.h
@@ -28,6 +28,19 @@
 #define __disable_user_access()							\
 	__asm__ __volatile__ ("csrc sstatus, %0" : : "r" (SR_SUM) : "memory")
 
+/*
+ * This is the smallest unsigned integer type that can fit a value
+ * (up to 'long long')
+ */
+#define __inttype(x) __typeof__(		\
+	__typefits(x,char,			\
+	  __typefits(x,short,			\
+	    __typefits(x,int,			\
+	      __typefits(x,long,0ULL)))))
+
+#define __typefits(x,type,not) \
+	__builtin_choose_expr(sizeof(x)<=sizeof(type),(unsigned type)0,not)
+
 /*
  * The exception table consists of pairs of addresses: the first is the
  * address of an instruction that is allowed to fault, and the second is
@@ -335,6 +348,56 @@ do {									\
 		goto err_label;						\
 } while (0)
 
+static __must_check __always_inline bool user_access_begin(const void __user *ptr, size_t len)
+{
+	if (unlikely(!access_ok(ptr,len)))
+		return 0;
+	__enable_user_access();
+	return 1;
+}
+#define user_access_begin(a,b)	user_access_begin(a,b)
+#define user_access_end()	__disable_user_access();
+
+static inline unsigned long user_access_save(void) { return 0UL; }
+static inline void user_access_restore(unsigned long enabled) { }
+
+#define unsafe_put_user(x, ptr, label)	do {				\
+	long __kr_err = 0;						\
+	__put_user_nocheck(x, (ptr), __kr_err);				\
+	if (__kr_err) goto label;					\
+} while (0)
+
+#define unsafe_get_user(x, ptr, label)	do {				\
+	long __kr_err = 0;						\
+	__inttype(*(ptr)) __gu_val;					\
+	__get_user_nocheck(__gu_val, (ptr), __kr_err);			\
+	(x) = (__force __typeof__(*(ptr)))__gu_val;			\
+	if (__kr_err) goto label;					\
+} while (0)
+
+/*
+ * We want the unsafe accessors to always be inlined and use
+ * the error labels - thus the macro games.
+ */
+#define unsafe_copy_loop(dst, src, len, type, label)				\
+	while (len >= sizeof(type)) {						\
+		unsafe_put_user(*(type *)(src),(type __user *)(dst),label);	\
+		dst += sizeof(type);						\
+		src += sizeof(type);						\
+		len -= sizeof(type);						\
+	}
+
+#define unsafe_copy_to_user(_dst,_src,_len,label)			\
+do {									\
+	char __user *__ucu_dst = (_dst);				\
+	const char *__ucu_src = (_src);					\
+	size_t __ucu_len = (_len);					\
+	unsafe_copy_loop(__ucu_dst, __ucu_src, __ucu_len, u64, label);	\
+	unsafe_copy_loop(__ucu_dst, __ucu_src, __ucu_len, u32, label);	\
+	unsafe_copy_loop(__ucu_dst, __ucu_src, __ucu_len, u16, label);	\
+	unsafe_copy_loop(__ucu_dst, __ucu_src, __ucu_len, u8, label);	\
+} while (0)
+
 #else /* CONFIG_MMU */
 #include <asm-generic/uaccess.h>
 #endif /* CONFIG_MMU */
-- 
2.43.0


  reply	other threads:[~2024-06-25  4:19 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-06-25  4:04 [PATCH 0/4] riscv: uaccess: optimizations Jisheng Zhang
2024-06-25  4:04 ` Jisheng Zhang [this message]
2024-06-26 23:38   ` [PATCH 1/4] riscv: implement user_access_begin and families Cyril Bur
2024-06-25  4:04 ` [PATCH 2/4] riscv: uaccess: use input constraints for ptr of __put_user Jisheng Zhang
2024-06-25  5:54   ` Arnd Bergmann
2024-06-26 12:32     ` Jisheng Zhang
2024-06-26 12:49       ` Jisheng Zhang
2024-06-26 13:18         ` Jisheng Zhang
2024-06-26 13:35         ` Andreas Schwab
2024-06-26 13:54           ` Jisheng Zhang
2024-06-26 13:12   ` Andreas Schwab
2024-06-26 13:12     ` Jisheng Zhang
2024-06-26 14:25       ` Arnd Bergmann
2024-06-26 16:02         ` Jisheng Zhang
2024-06-27  6:46           ` Arnd Bergmann
2024-06-28 15:36         ` David Laight
2024-06-25  4:04 ` [PATCH 3/4] riscv: uaccess: use 'asm goto' for put_user() Jisheng Zhang
2024-07-05  2:22   ` kernel test robot
2024-07-06  0:02   ` kernel test robot
2024-06-25  4:05 ` [PATCH 4/4] riscv: uaccess: use 'asm goto output' for get_user Jisheng Zhang
2024-07-05  4:13   ` kernel test robot
2024-06-25  7:21 ` [PATCH 0/4] riscv: uaccess: optimizations Arnd Bergmann
2024-06-25 18:12   ` Linus Torvalds
2024-06-26 13:04     ` Jisheng Zhang
2024-06-30 16:59     ` Linus Torvalds
2024-07-05 11:25       ` Will Deacon
2024-07-05 17:58         ` Linus Torvalds
2024-07-08 13:52           ` Will Deacon
2024-07-08 15:30             ` Mark Rutland
2024-07-23 14:16               ` Will Deacon
2024-07-08 15:21           ` Mark Rutland
2024-07-24 22:57 ` Palmer Dabbelt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240625040500.1788-2-jszhang@kernel.org \
    --to=jszhang@kernel.org \
    --cc=aou@eecs.berkeley.edu \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-riscv@lists.infradead.org \
    --cc=palmer@dabbelt.com \
    --cc=paul.walmsley@sifive.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox