Commit ff73f834 authored by Kees Cook's avatar Kees Cook Committed by Jakub Kicinski

sock: Use unsafe_memcpy() for sock_copy()

While testing for places where zero-sized destinations were still showing
up in the kernel, sock_copy() and inet_reqsk_clone() were found, which
are using very specific memcpy() offsets for both avoiding a portion of
struct sock, and copying beyond the end of it (since struct sock is really
just a common header before the protocol-specific allocation). Instead
of trying to unravel this historical lack of container_of(), just switch
to unsafe_memcpy(), since that's effectively what was happening already
(memcpy() wasn't checking 0-sized destinations while the code base was
being converted away from fake flexible arrays).

Avoid the following false positive warning with future changes to
CONFIG_FORTIFY_SOURCE:

  memcpy: detected field-spanning write (size 3068) of destination "&nsk->__sk_common.skc_dontcopy_end" at net/core/sock.c:2057 (size 0)
Signed-off-by: default avatarKees Cook <keescook@chromium.org>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Link: https://lore.kernel.org/r/20240304212928.make.772-kees@kernel.orgSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 4166204d
...@@ -2053,8 +2053,9 @@ static void sock_copy(struct sock *nsk, const struct sock *osk) ...@@ -2053,8 +2053,9 @@ static void sock_copy(struct sock *nsk, const struct sock *osk)
memcpy(nsk, osk, offsetof(struct sock, sk_dontcopy_begin)); memcpy(nsk, osk, offsetof(struct sock, sk_dontcopy_begin));
memcpy(&nsk->sk_dontcopy_end, &osk->sk_dontcopy_end, unsafe_memcpy(&nsk->sk_dontcopy_end, &osk->sk_dontcopy_end,
prot->obj_size - offsetof(struct sock, sk_dontcopy_end)); prot->obj_size - offsetof(struct sock, sk_dontcopy_end),
/* alloc is larger than struct, see sk_prot_alloc() */);
#ifdef CONFIG_SECURITY_NETWORK #ifdef CONFIG_SECURITY_NETWORK
nsk->sk_security = sptr; nsk->sk_security = sptr;
......
...@@ -906,8 +906,9 @@ static struct request_sock *inet_reqsk_clone(struct request_sock *req, ...@@ -906,8 +906,9 @@ static struct request_sock *inet_reqsk_clone(struct request_sock *req,
memcpy(nreq_sk, req_sk, memcpy(nreq_sk, req_sk,
offsetof(struct sock, sk_dontcopy_begin)); offsetof(struct sock, sk_dontcopy_begin));
memcpy(&nreq_sk->sk_dontcopy_end, &req_sk->sk_dontcopy_end, unsafe_memcpy(&nreq_sk->sk_dontcopy_end, &req_sk->sk_dontcopy_end,
req->rsk_ops->obj_size - offsetof(struct sock, sk_dontcopy_end)); req->rsk_ops->obj_size - offsetof(struct sock, sk_dontcopy_end),
/* alloc is larger than struct, see above */);
sk_node_init(&nreq_sk->sk_node); sk_node_init(&nreq_sk->sk_node);
nreq_sk->sk_tx_queue_mapping = req_sk->sk_tx_queue_mapping; nreq_sk->sk_tx_queue_mapping = req_sk->sk_tx_queue_mapping;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment