* [PATCH 1/5] uaccess: fix ignored_trailing logic in copy_struct_to_user()
2026-04-07 16:03 [PATCH 0/5] uaccess/sockptr: copy_struct_ fixes and more helpers Stefan Metzmacher
@ 2026-04-07 16:03 ` Stefan Metzmacher
2026-04-07 16:03 ` [PATCH 2/5] sockptr: fix usize check in copy_struct_from_sockptr() for user pointers Stefan Metzmacher
` (3 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Stefan Metzmacher @ 2026-04-07 16:03 UTC (permalink / raw)
To: linux-kernel
Cc: metze, Dmitry Safonov, Dmitry Safonov, Francesco Ruggeri,
Salam Noureddine, David Ahern, David S . Miller, Michal Luczaj,
David Wei, Luiz Augusto von Dentz, Luiz Augusto von Dentz,
Marcel Holtmann, Xin Long, Eric Dumazet, Kuniyuki Iwashima,
Paolo Abeni, Willem de Bruijn, Neal Cardwell, Jakub Kicinski,
Simon Horman, Aleksa Sarai, Christian Brauner, Kees Cook, netdev,
linux-bluetooth
Currently all callers pass ignored_trailing=NULL, but I have
code that will make use of.
Now it actually behaves like documented:
* If @usize < @ksize, then the kernel is trying to pass userspace a newer
struct than it supports. Thus we only copy the interoperable portions
(@usize) and ignore the rest (but @ignored_trailing is set to %true if
any of the trailing (@ksize - @usize) bytes are non-zero).
Fixes: 424a55a4a908 ("uaccess: add copy_struct_to_user helper")
Cc: Dmitry Safonov <0x7f454c46@gmail.com>
Cc: Dmitry Safonov <dima@arista.com>
Cc: Francesco Ruggeri <fruggeri@arista.com>
Cc: Salam Noureddine <noureddine@arista.com>
Cc: David Ahern <dsahern@kernel.org>
Cc: David S. Miller <davem@davemloft.net>
Cc: Michal Luczaj <mhal@rbox.co>
Cc: David Wei <dw@davidwei.uk>
Cc: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Cc: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
Cc: Marcel Holtmann <marcel@holtmann.org>
Cc: Xin Long <lucien.xin@gmail.com>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Kuniyuki Iwashima <kuniyu@google.com>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: Willem de Bruijn <willemb@google.com>
Cc: Neal Cardwell <ncardwell@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Simon Horman <horms@kernel.org>
Cc: Aleksa Sarai <cyphar@cyphar.com>
Cc: Christian Brauner <brauner@kernel.org>
CC: Kees Cook <keescook@chromium.org>
Cc: netdev@vger.kernel.org
Cc: linux-bluetooth@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Stefan Metzmacher <metze@samba.org>
---
include/linux/uaccess.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h
index 4fe63169d5a2..1234b5fa4761 100644
--- a/include/linux/uaccess.h
+++ b/include/linux/uaccess.h
@@ -505,7 +505,7 @@ copy_struct_to_user(void __user *dst, size_t usize, const void *src,
return -EFAULT;
}
if (ignored_trailing)
- *ignored_trailing = ksize < usize &&
+ *ignored_trailing = usize < ksize &&
memchr_inv(src + size, 0, rest) != NULL;
/* Copy the interoperable parts of the struct. */
if (copy_to_user(dst, src, size))
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 2/5] sockptr: fix usize check in copy_struct_from_sockptr() for user pointers
2026-04-07 16:03 [PATCH 0/5] uaccess/sockptr: copy_struct_ fixes and more helpers Stefan Metzmacher
2026-04-07 16:03 ` [PATCH 1/5] uaccess: fix ignored_trailing logic in copy_struct_to_user() Stefan Metzmacher
@ 2026-04-07 16:03 ` Stefan Metzmacher
2026-04-07 16:03 ` [PATCH 3/5] uaccess: add copy_struct_{from,to}_bounce_buffer() helpers Stefan Metzmacher
` (2 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Stefan Metzmacher @ 2026-04-07 16:03 UTC (permalink / raw)
To: linux-kernel
Cc: metze, Dmitry Safonov, Dmitry Safonov, Francesco Ruggeri,
Salam Noureddine, David Ahern, David S . Miller, Michal Luczaj,
David Wei, Luiz Augusto von Dentz, Luiz Augusto von Dentz,
Marcel Holtmann, Xin Long, Eric Dumazet, Kuniyuki Iwashima,
Paolo Abeni, Willem de Bruijn, Neal Cardwell, Jakub Kicinski,
Simon Horman, Aleksa Sarai, Christian Brauner, Kees Cook, netdev,
linux-bluetooth
copy_struct_from_user will never hit the check_zeroed_user() call
and will never return -E2BIG if new userspace passed new bits in a
larger structure than the current kernel structure.
As far as I can there are no critical/related uapi changes in
- include/net/bluetooth/bluetooth.h and net/bluetooth/sco.c
after the use of copy_struct_from_sockptr in v6.13-rc3
- include/uapi/linux/tcp.h and net/ipv4/tcp_ao.c
after the use of copy_struct_from_sockptr in v6.6-rc1
So that new callers will get the correct behavior from the start.
Fixes: 4954f17ddefc ("net/tcp: Introduce TCP_AO setsockopt()s")
Fixes: ef84703a911f ("net/tcp: Add TCP-AO getsockopt()s")
Fixes: faadfaba5e01 ("net/tcp: Add TCP_AO_REPAIR")
Fixes: 3e643e4efa1e ("Bluetooth: Improve setsockopt() handling of malformed user input")
Cc: Dmitry Safonov <0x7f454c46@gmail.com>
Cc: Dmitry Safonov <dima@arista.com>
Cc: Francesco Ruggeri <fruggeri@arista.com>
Cc: Salam Noureddine <noureddine@arista.com>
Cc: David Ahern <dsahern@kernel.org>
Cc: David S. Miller <davem@davemloft.net>
Cc: Michal Luczaj <mhal@rbox.co>
Cc: David Wei <dw@davidwei.uk>
Cc: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Cc: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
Cc: Marcel Holtmann <marcel@holtmann.org>
Cc: Xin Long <lucien.xin@gmail.com>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Kuniyuki Iwashima <kuniyu@google.com>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: Willem de Bruijn <willemb@google.com>
Cc: Neal Cardwell <ncardwell@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Simon Horman <horms@kernel.org>
Cc: Aleksa Sarai <cyphar@cyphar.com>
Cc: Christian Brauner <brauner@kernel.org>
CC: Kees Cook <keescook@chromium.org>
Cc: netdev@vger.kernel.org
Cc: linux-bluetooth@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Stefan Metzmacher <metze@samba.org>
---
include/linux/sockptr.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/sockptr.h b/include/linux/sockptr.h
index 3e6c8e9d67ae..ba88f4d78c1b 100644
--- a/include/linux/sockptr.h
+++ b/include/linux/sockptr.h
@@ -91,7 +91,7 @@ static inline int copy_struct_from_sockptr(void *dst, size_t ksize,
size_t rest = max(ksize, usize) - size;
if (!sockptr_is_kernel(src))
- return copy_struct_from_user(dst, ksize, src.user, size);
+ return copy_struct_from_user(dst, ksize, src.user, usize);
if (usize < ksize) {
memset(dst + size, 0, rest);
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 3/5] uaccess: add copy_struct_{from,to}_bounce_buffer() helpers
2026-04-07 16:03 [PATCH 0/5] uaccess/sockptr: copy_struct_ fixes and more helpers Stefan Metzmacher
2026-04-07 16:03 ` [PATCH 1/5] uaccess: fix ignored_trailing logic in copy_struct_to_user() Stefan Metzmacher
2026-04-07 16:03 ` [PATCH 2/5] sockptr: fix usize check in copy_struct_from_sockptr() for user pointers Stefan Metzmacher
@ 2026-04-07 16:03 ` Stefan Metzmacher
2026-04-07 18:25 ` David Laight
2026-04-07 16:03 ` [PATCH 4/5] sockptr: let copy_struct_from_sockptr() use copy_struct_from_bounce_buffer() Stefan Metzmacher
2026-04-07 16:03 ` [PATCH 5/5] sockptr: introduce copy_struct_to_sockptr() Stefan Metzmacher
4 siblings, 1 reply; 7+ messages in thread
From: Stefan Metzmacher @ 2026-04-07 16:03 UTC (permalink / raw)
To: linux-kernel
Cc: metze, Dmitry Safonov, Dmitry Safonov, Francesco Ruggeri,
Salam Noureddine, David Ahern, David S . Miller, Michal Luczaj,
David Wei, Luiz Augusto von Dentz, Luiz Augusto von Dentz,
Marcel Holtmann, Xin Long, Eric Dumazet, Kuniyuki Iwashima,
Paolo Abeni, Willem de Bruijn, Neal Cardwell, Jakub Kicinski,
Simon Horman, Aleksa Sarai, Christian Brauner, Kees Cook, netdev,
linux-bluetooth
These are similar to copy_struct_{from,to}_user() but operate
on kernel buffers instead of user buffers.
They can be used when there is a temporary bounce buffer used,
e.g. in msg_control or similar places.
It allows us to have the same logic to handle old vs. current
and current vs. new structures in the same compatible way.
copy_struct_from_sockptr() will also be able to
use copy_struct_from_bounce_buffer() for the kernel
case as follow us patch.
I'll use this in my IPPROTO_SMBDIRECT work,
but maybe it will also be useful for others...
IPPROTO_QUIC will likely also use it.
Cc: Dmitry Safonov <0x7f454c46@gmail.com>
Cc: Dmitry Safonov <dima@arista.com>
Cc: Francesco Ruggeri <fruggeri@arista.com>
Cc: Salam Noureddine <noureddine@arista.com>
Cc: David Ahern <dsahern@kernel.org>
Cc: David S. Miller <davem@davemloft.net>
Cc: Michal Luczaj <mhal@rbox.co>
Cc: David Wei <dw@davidwei.uk>
Cc: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Cc: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
Cc: Marcel Holtmann <marcel@holtmann.org>
Cc: Xin Long <lucien.xin@gmail.com>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Kuniyuki Iwashima <kuniyu@google.com>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: Willem de Bruijn <willemb@google.com>
Cc: Neal Cardwell <ncardwell@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Simon Horman <horms@kernel.org>
Cc: Aleksa Sarai <cyphar@cyphar.com>
Cc: Christian Brauner <brauner@kernel.org>
CC: Kees Cook <keescook@chromium.org>
Cc: netdev@vger.kernel.org
Cc: linux-bluetooth@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Stefan Metzmacher <metze@samba.org>
---
include/linux/uaccess.h | 63 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 63 insertions(+)
diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h
index 1234b5fa4761..a6cd4f48bb99 100644
--- a/include/linux/uaccess.h
+++ b/include/linux/uaccess.h
@@ -513,6 +513,69 @@ copy_struct_to_user(void __user *dst, size_t usize, const void *src,
return 0;
}
+static __always_inline void
+__copy_struct_generic_bounce_buffer(void *dst, size_t dstsize,
+ const void *src, size_t srcsize,
+ bool *ignored_trailing)
+{
+ size_t size = min(dstsize, srcsize);
+ size_t rest = max(dstsize, srcsize) - size;
+
+ /* Deal with trailing bytes. */
+ if (dstsize > srcsize)
+ memset(dst + size, 0, rest);
+ if (ignored_trailing)
+ *ignored_trailing = dstsize < srcsize &&
+ memchr_inv(src + size, 0, rest) != NULL;
+ /* Copy the interoperable parts of the struct. */
+ memcpy(dst, src, size);
+}
+
+/**
+ * This is like copy_struct_from_user(), but the
+ * src buffer was already copied into a kernel
+ * bounce buffer, so it will never return -EFAULT.
+ */
+static __always_inline __must_check int
+copy_struct_from_bounce_buffer(void *dst, size_t dstsize,
+ const void *src, size_t srcsize)
+{
+ bool ignored_trailing;
+
+ /* Double check if ksize is larger than a known object size. */
+ if (WARN_ON_ONCE(dstsize > __builtin_object_size(dst, 1)))
+ return -E2BIG;
+
+ __copy_struct_generic_bounce_buffer(dst, dstsize,
+ src, srcsize,
+ &ignored_trailing);
+ if (unlikely(ignored_trailing))
+ return -E2BIG;
+
+ return 0;
+}
+
+/**
+ * This is like copy_struct_to_user(), but the
+ * dst buffer is a kernel bounce buffer instead
+ * of a direct userspace buffer, so it will never return -EFAULT.
+ */
+static __always_inline __must_check int
+copy_struct_to_bounce_buffer(void *dst, size_t dstsize,
+ const void *src,
+ size_t srcsize,
+ bool *ignored_trailing)
+{
+ /* Double check if srcsize is larger than a known object size. */
+ if (WARN_ON_ONCE(srcsize > __builtin_object_size(src, 1)))
+ return -E2BIG;
+
+ __copy_struct_generic_bounce_buffer(dst, dstsize,
+ src, srcsize,
+ ignored_trailing);
+ return 0;
+}
+
bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size);
long copy_from_kernel_nofault(void *dst, const void *src, size_t size);
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH 3/5] uaccess: add copy_struct_{from,to}_bounce_buffer() helpers
2026-04-07 16:03 ` [PATCH 3/5] uaccess: add copy_struct_{from,to}_bounce_buffer() helpers Stefan Metzmacher
@ 2026-04-07 18:25 ` David Laight
0 siblings, 0 replies; 7+ messages in thread
From: David Laight @ 2026-04-07 18:25 UTC (permalink / raw)
To: Stefan Metzmacher
Cc: linux-kernel, Dmitry Safonov, Dmitry Safonov, Francesco Ruggeri,
Salam Noureddine, David Ahern, David S . Miller, Michal Luczaj,
David Wei, Luiz Augusto von Dentz, Luiz Augusto von Dentz,
Marcel Holtmann, Xin Long, Eric Dumazet, Kuniyuki Iwashima,
Paolo Abeni, Willem de Bruijn, Neal Cardwell, Jakub Kicinski,
Simon Horman, Aleksa Sarai, Christian Brauner, Kees Cook, netdev,
linux-bluetooth
On Tue, 7 Apr 2026 18:03:15 +0200
Stefan Metzmacher <metze@samba.org> wrote:
> These are similar to copy_struct_{from,to}_user() but operate
> on kernel buffers instead of user buffers.
>
> They can be used when there is a temporary bounce buffer used,
> e.g. in msg_control or similar places.
>
> It allows us to have the same logic to handle old vs. current
> and current vs. new structures in the same compatible way.
>
> copy_struct_from_sockptr() will also be able to
> use copy_struct_from_bounce_buffer() for the kernel
> case as follow us patch.
>
> I'll use this in my IPPROTO_SMBDIRECT work,
> but maybe it will also be useful for others...
> IPPROTO_QUIC will likely also use it.
>
> Cc: Dmitry Safonov <0x7f454c46@gmail.com>
> Cc: Dmitry Safonov <dima@arista.com>
> Cc: Francesco Ruggeri <fruggeri@arista.com>
> Cc: Salam Noureddine <noureddine@arista.com>
> Cc: David Ahern <dsahern@kernel.org>
> Cc: David S. Miller <davem@davemloft.net>
> Cc: Michal Luczaj <mhal@rbox.co>
> Cc: David Wei <dw@davidwei.uk>
> Cc: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
> Cc: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
> Cc: Marcel Holtmann <marcel@holtmann.org>
> Cc: Xin Long <lucien.xin@gmail.com>
> Cc: Eric Dumazet <edumazet@google.com>
> Cc: Kuniyuki Iwashima <kuniyu@google.com>
> Cc: Paolo Abeni <pabeni@redhat.com>
> Cc: Willem de Bruijn <willemb@google.com>
> Cc: Neal Cardwell <ncardwell@google.com>
> Cc: Jakub Kicinski <kuba@kernel.org>
> Cc: Simon Horman <horms@kernel.org>
> Cc: Aleksa Sarai <cyphar@cyphar.com>
> Cc: Christian Brauner <brauner@kernel.org>
> CC: Kees Cook <keescook@chromium.org>
> Cc: netdev@vger.kernel.org
> Cc: linux-bluetooth@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> Signed-off-by: Stefan Metzmacher <metze@samba.org>
> ---
> include/linux/uaccess.h | 63 +++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 63 insertions(+)
>
> diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h
> index 1234b5fa4761..a6cd4f48bb99 100644
> --- a/include/linux/uaccess.h
> +++ b/include/linux/uaccess.h
> @@ -513,6 +513,69 @@ copy_struct_to_user(void __user *dst, size_t usize, const void *src,
> return 0;
> }
>
> +static __always_inline void
> +__copy_struct_generic_bounce_buffer(void *dst, size_t dstsize,
> + const void *src, size_t srcsize,
> + bool *ignored_trailing)
> +{
> + size_t size = min(dstsize, srcsize);
> + size_t rest = max(dstsize, srcsize) - size;
> +
> + /* Deal with trailing bytes. */
> + if (dstsize > srcsize)
> + memset(dst + size, 0, rest);
> + if (ignored_trailing)
> + *ignored_trailing = dstsize < srcsize &&
> + memchr_inv(src + size, 0, rest) != NULL;
> + /* Copy the interoperable parts of the struct. */
> + memcpy(dst, src, size);
> +}
Return 'ignored_trailing' rather than pass by reference.
And this is probably too big to inline.
David
> +
> +/**
> + * This is like copy_struct_from_user(), but the
> + * src buffer was already copied into a kernel
> + * bounce buffer, so it will never return -EFAULT.
> + */
> +static __always_inline __must_check int
> +copy_struct_from_bounce_buffer(void *dst, size_t dstsize,
> + const void *src, size_t srcsize)
> +{
> + bool ignored_trailing;
> +
> + /* Double check if ksize is larger than a known object size. */
> + if (WARN_ON_ONCE(dstsize > __builtin_object_size(dst, 1)))
> + return -E2BIG;
> +
> + __copy_struct_generic_bounce_buffer(dst, dstsize,
> + src, srcsize,
> + &ignored_trailing);
> + if (unlikely(ignored_trailing))
> + return -E2BIG;
> +
> + return 0;
> +}
> +
> +/**
> + * This is like copy_struct_to_user(), but the
> + * dst buffer is a kernel bounce buffer instead
> + * of a direct userspace buffer, so it will never return -EFAULT.
> + */
> +static __always_inline __must_check int
> +copy_struct_to_bounce_buffer(void *dst, size_t dstsize,
> + const void *src,
> + size_t srcsize,
> + bool *ignored_trailing)
> +{
> + /* Double check if srcsize is larger than a known object size. */
> + if (WARN_ON_ONCE(srcsize > __builtin_object_size(src, 1)))
> + return -E2BIG;
> +
> + __copy_struct_generic_bounce_buffer(dst, dstsize,
> + src, srcsize,
> + ignored_trailing);
> + return 0;
> +}
> +
> bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size);
>
> long copy_from_kernel_nofault(void *dst, const void *src, size_t size);
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 4/5] sockptr: let copy_struct_from_sockptr() use copy_struct_from_bounce_buffer()
2026-04-07 16:03 [PATCH 0/5] uaccess/sockptr: copy_struct_ fixes and more helpers Stefan Metzmacher
` (2 preceding siblings ...)
2026-04-07 16:03 ` [PATCH 3/5] uaccess: add copy_struct_{from,to}_bounce_buffer() helpers Stefan Metzmacher
@ 2026-04-07 16:03 ` Stefan Metzmacher
2026-04-07 16:03 ` [PATCH 5/5] sockptr: introduce copy_struct_to_sockptr() Stefan Metzmacher
4 siblings, 0 replies; 7+ messages in thread
From: Stefan Metzmacher @ 2026-04-07 16:03 UTC (permalink / raw)
To: linux-kernel
Cc: metze, Dmitry Safonov, Dmitry Safonov, Francesco Ruggeri,
Salam Noureddine, David Ahern, David S . Miller, Michal Luczaj,
David Wei, Luiz Augusto von Dentz, Luiz Augusto von Dentz,
Marcel Holtmann, Xin Long, Eric Dumazet, Kuniyuki Iwashima,
Paolo Abeni, Willem de Bruijn, Neal Cardwell, Jakub Kicinski,
Simon Horman, Aleksa Sarai, Christian Brauner, Kees Cook, netdev,
linux-bluetooth
The world would be better without sockptr_t, but this at least
simplifies copy_struct_from_sockptr() to be just a dispatcher for
copy_struct_from_user() or copy_struct_from_bounce_buffer() without any
special logic on its own.
Cc: Dmitry Safonov <0x7f454c46@gmail.com>
Cc: Dmitry Safonov <dima@arista.com>
Cc: Francesco Ruggeri <fruggeri@arista.com>
Cc: Salam Noureddine <noureddine@arista.com>
Cc: David Ahern <dsahern@kernel.org>
Cc: David S. Miller <davem@davemloft.net>
Cc: Michal Luczaj <mhal@rbox.co>
Cc: David Wei <dw@davidwei.uk>
Cc: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Cc: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
Cc: Marcel Holtmann <marcel@holtmann.org>
Cc: Xin Long <lucien.xin@gmail.com>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Kuniyuki Iwashima <kuniyu@google.com>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: Willem de Bruijn <willemb@google.com>
Cc: Neal Cardwell <ncardwell@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Simon Horman <horms@kernel.org>
Cc: Aleksa Sarai <cyphar@cyphar.com>
Cc: Christian Brauner <brauner@kernel.org>
CC: Kees Cook <keescook@chromium.org>
Cc: netdev@vger.kernel.org
Cc: linux-bluetooth@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Stefan Metzmacher <metze@samba.org>
---
include/linux/sockptr.h | 16 +---------------
1 file changed, 1 insertion(+), 15 deletions(-)
diff --git a/include/linux/sockptr.h b/include/linux/sockptr.h
index ba88f4d78c1b..706a8526cf3c 100644
--- a/include/linux/sockptr.h
+++ b/include/linux/sockptr.h
@@ -87,24 +87,10 @@ static inline int copy_safe_from_sockptr(void *dst, size_t ksize,
static inline int copy_struct_from_sockptr(void *dst, size_t ksize,
sockptr_t src, size_t usize)
{
- size_t size = min(ksize, usize);
- size_t rest = max(ksize, usize) - size;
-
if (!sockptr_is_kernel(src))
return copy_struct_from_user(dst, ksize, src.user, usize);
- if (usize < ksize) {
- memset(dst + size, 0, rest);
- } else if (usize > ksize) {
- char *p = src.kernel;
-
- while (rest--) {
- if (*p++)
- return -E2BIG;
- }
- }
- memcpy(dst, src.kernel, size);
- return 0;
+ return copy_struct_from_bounce_buffer(dst, ksize, src.kernel, usize);
}
static inline int copy_to_sockptr_offset(sockptr_t dst, size_t offset,
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 5/5] sockptr: introduce copy_struct_to_sockptr()
2026-04-07 16:03 [PATCH 0/5] uaccess/sockptr: copy_struct_ fixes and more helpers Stefan Metzmacher
` (3 preceding siblings ...)
2026-04-07 16:03 ` [PATCH 4/5] sockptr: let copy_struct_from_sockptr() use copy_struct_from_bounce_buffer() Stefan Metzmacher
@ 2026-04-07 16:03 ` Stefan Metzmacher
4 siblings, 0 replies; 7+ messages in thread
From: Stefan Metzmacher @ 2026-04-07 16:03 UTC (permalink / raw)
To: linux-kernel
Cc: metze, Dmitry Safonov, Dmitry Safonov, Francesco Ruggeri,
Salam Noureddine, David Ahern, David S . Miller, Michal Luczaj,
David Wei, Luiz Augusto von Dentz, Luiz Augusto von Dentz,
Marcel Holtmann, Xin Long, Eric Dumazet, Kuniyuki Iwashima,
Paolo Abeni, Willem de Bruijn, Neal Cardwell, Jakub Kicinski,
Simon Horman, Aleksa Sarai, Christian Brauner, Kees Cook, netdev,
linux-bluetooth
We already have copy_struct_from_sockptr() as wrapper to
copy_struct_from_user() or copy_struct_from_bounce_buffer(),
so it's good to have copy_struct_to_sockptr()
as well matching the behavior of copy_struct_to_user()
or copy_struct_to_bounce_buffer().
The world would be better without sockptr_t, but having
copy_struct_to_sockptr() is better than open code it
in various places.
I'll use this in my IPPROTO_SMBDIRECT work,
but maybe it will also be useful for others...
IPPROTO_QUIC will likely also use it.
Cc: Dmitry Safonov <0x7f454c46@gmail.com>
Cc: Dmitry Safonov <dima@arista.com>
Cc: Francesco Ruggeri <fruggeri@arista.com>
Cc: Salam Noureddine <noureddine@arista.com>
Cc: David Ahern <dsahern@kernel.org>
Cc: David S. Miller <davem@davemloft.net>
Cc: Michal Luczaj <mhal@rbox.co>
Cc: David Wei <dw@davidwei.uk>
Cc: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Cc: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
Cc: Marcel Holtmann <marcel@holtmann.org>
Cc: Xin Long <lucien.xin@gmail.com>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Kuniyuki Iwashima <kuniyu@google.com>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: Willem de Bruijn <willemb@google.com>
Cc: Neal Cardwell <ncardwell@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Simon Horman <horms@kernel.org>
Cc: Aleksa Sarai <cyphar@cyphar.com>
Cc: Christian Brauner <brauner@kernel.org>
CC: Kees Cook <keescook@chromium.org>
Cc: netdev@vger.kernel.org
Cc: linux-bluetooth@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Stefan Metzmacher <metze@samba.org>
---
include/linux/sockptr.h | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/include/linux/sockptr.h b/include/linux/sockptr.h
index 706a8526cf3c..9c2429c1a570 100644
--- a/include/linux/sockptr.h
+++ b/include/linux/sockptr.h
@@ -107,6 +107,16 @@ static inline int copy_to_sockptr(sockptr_t dst, const void *src, size_t size)
return copy_to_sockptr_offset(dst, 0, src, size);
}
+static inline int
+copy_struct_to_sockptr(sockptr_t dst, size_t usize, const void *src,
+ size_t ksize, bool *ignored_trailing)
+{
+ if (!sockptr_is_kernel(dst))
+ return copy_struct_to_user(dst.user, usize, src, ksize, ignored_trailing);
+
+ return copy_struct_to_bounce_buffer(dst.kernel, usize, src, ksize, ignored_trailing);
+}
+
static inline void *memdup_sockptr_noprof(sockptr_t src, size_t len)
{
void *p = kmalloc_track_caller_noprof(len, GFP_USER | __GFP_NOWARN);
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread