summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Abeni <pabeni@redhat.com>2024-11-28 08:57:42 +0100
committerPaolo Abeni <pabeni@redhat.com>2024-11-28 08:57:42 +0100
commitd1524d040b12e5bee1ee1d04ce50122a1ea35258 (patch)
tree60dc45d6d52ff90178d5b51b5824531dd454d011
parent5dfd7d940094e1a1ec974d90f6d28162d372b56b (diff)
parent49b2b973325add467270e906d4d794aa6679b38b (diff)
Merge branch 'net-fix-some-callers-of-copy_from_sockptr'
Michal Luczaj says: ==================== net: Fix some callers of copy_from_sockptr() Some callers misinterpret copy_from_sockptr()'s return value. The function follows copy_from_user(), i.e. returns 0 for success, or the number of bytes not copied on error. Simply returning the result in a non-zero case isn't usually what was intended. Compile tested with CONFIG_LLC, CONFIG_AF_RXRPC, CONFIG_BT enabled. Last patch probably belongs more to net-next, if any. Here as an RFC. Suggested-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Michal Luczaj <mhal@rbox.co> ==================== Link: https://patch.msgid.link/20241119-sockptr-copy-fixes-v3-0-d752cac4be8e@rbox.co Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-rw-r--r--include/linux/sockptr.h2
-rw-r--r--net/llc/af_llc.c2
-rw-r--r--net/rxrpc/af_rxrpc.c7
3 files changed, 7 insertions, 4 deletions
diff --git a/include/linux/sockptr.h b/include/linux/sockptr.h
index 195debe2b1db..3e6c8e9d67ae 100644
--- a/include/linux/sockptr.h
+++ b/include/linux/sockptr.h
@@ -53,6 +53,8 @@ static inline int copy_from_sockptr_offset(void *dst, sockptr_t src,
/* Deprecated.
* This is unsafe, unless caller checked user provided optlen.
* Prefer copy_safe_from_sockptr() instead.
+ *
+ * Returns 0 for success, or number of bytes not copied on error.
*/
static inline int copy_from_sockptr(void *dst, sockptr_t src, size_t size)
{
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index 4eb52add7103..0259cde394ba 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -1098,7 +1098,7 @@ static int llc_ui_setsockopt(struct socket *sock, int level, int optname,
lock_sock(sk);
if (unlikely(level != SOL_LLC || optlen != sizeof(int)))
goto out;
- rc = copy_from_sockptr(&opt, optval, sizeof(opt));
+ rc = copy_safe_from_sockptr(&opt, sizeof(opt), optval, optlen);
if (rc)
goto out;
rc = -EINVAL;
diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c
index f4844683e120..9d8bd0b37e41 100644
--- a/net/rxrpc/af_rxrpc.c
+++ b/net/rxrpc/af_rxrpc.c
@@ -707,9 +707,10 @@ static int rxrpc_setsockopt(struct socket *sock, int level, int optname,
ret = -EISCONN;
if (rx->sk.sk_state != RXRPC_UNBOUND)
goto error;
- ret = copy_from_sockptr(&min_sec_level, optval,
- sizeof(unsigned int));
- if (ret < 0)
+ ret = copy_safe_from_sockptr(&min_sec_level,
+ sizeof(min_sec_level),
+ optval, optlen);
+ if (ret)
goto error;
ret = -EINVAL;
if (min_sec_level > RXRPC_SECURITY_MAX)