diff mbox series

[net-next,4/4] sockptr: Change sockptr_t to be a struct of a kernel and user pointer.

Message ID 18fcf82093314112a569aa8327b52f1c@AcuMS.aculab.com (mailing list archive)
State Deferred
Delegated to: Netdev Maintainers
Headers show
Series sockptr: Change sockptr_t to be a struct | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for net-next, async
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 7866 this patch: 7866
netdev/cc_maintainers fail 4 maintainers not CCed: dsahern@kernel.org bpf@vger.kernel.org noureddine@arista.com 0x7f454c46@gmail.com
netdev/build_clang success Errors and warnings before: 2570 this patch: 2570
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 8400 this patch: 8400
netdev/checkpatch warning CHECK: From:/Signed-off-by: email comments mismatch: 'From: David Laight <David.Laight@ACULAB.COM>' != 'Signed-off-by: David Laight <david.laight@aculab.com>'
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

David Laight Dec. 25, 2023, 9:58 a.m. UTC
The original commit for sockptr_t tried to use the pointer value
to determine whether a pointer was user or kernel.
This can't work on some architecures and was buffy on x86.
So the is_kernel descriminator was added after the union of pointers.

However this is still open to misuse and accidents.
Replace the union with a struct and remove the is_kernel member.
The user and kernel values are now in different places.
The size doesn't change - it was always padded out to 'two pointers'.

The only functional difference is that NULL pointers are always 'user'.
So dereferncing will (usually) fault in copy_from_user() rather than
panic if supplied as a kernel address.

Simple driver code that uses kernel sockets still works.
I've not tested bpf - but that should work unless it is breaking
the rules.

Signed-off-by: David Laight <david.laight@aculab.com>
---
 include/linux/sockptr.h | 15 +++++----------
 1 file changed, 5 insertions(+), 10 deletions(-)
diff mbox series

Patch

diff --git a/include/linux/sockptr.h b/include/linux/sockptr.h
index 307961b41541..7516c2ada6a8 100644
--- a/include/linux/sockptr.h
+++ b/include/linux/sockptr.h
@@ -12,21 +12,18 @@ 
 #include <linux/uaccess.h>
 
 typedef struct {
-	union {
-		void		*kernel;
-		void __user	*user;
-	};
-	bool		is_kernel : 1;
+	void		*kernel;
+	void __user	*user;
 } sockptr_t;
 
 static inline bool sockptr_is_kernel(sockptr_t sockptr)
 {
-	return sockptr.is_kernel;
+	return !!sockptr.kernel;
 }
 
 static inline sockptr_t KERNEL_SOCKPTR(void *p)
 {
-	return (sockptr_t) { .kernel = p, .is_kernel = true };
+	return (sockptr_t) { .kernel = p };
 }
 
 static inline sockptr_t USER_SOCKPTR(void __user *p)
@@ -36,9 +33,7 @@  static inline sockptr_t USER_SOCKPTR(void __user *p)
 
 static inline bool sockptr_is_null(sockptr_t sockptr)
 {
-	if (sockptr_is_kernel(sockptr))
-		return !sockptr.kernel;
-	return !sockptr.user;
+	return !sockptr.user && !sockptr.kernel;
 }
 
 static inline int copy_from_sockptr_offset(void *dst, sockptr_t src,