From 4e60e85129ae142720ae1fd12c535317a64906b2 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 19 Oct 2026 19:23:33 -1000 Subject: [PATCH] net: use put_user() for msghdr results written back to user space ____sys_recvmsg() writes msg_flags and msg_controllen back with __put_user(), and the compat sendmmsg()/recvmmsg() loops write msg_len the same way. None of these has an access_ok() of its own: they rely on the earlier copy_from_user() of the message header having checked the range. For the compat msg_len that is not even true, since msg_len lives after the compat_msghdr that was copied. It is only safe because compat pointers are 32-bit. The native mmsg paths already use put_user(). Use put_user() everywhere. On x86 that adds a couple of instructions to check the address, on a path that has to enable and disable user access for each write anyway. This is part of getting rid of __get_user() and __put_user() entirely. Signed-off-by: Linus Torvalds --- net/socket.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/net/socket.c b/net/socket.c index c05d86e63abf..fe09cca00805 100644 --- a/net/socket.c +++ b/net/socket.c @@ -2850,7 +2850,7 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, &msg_sys, flags, &used_address, MSG_EOR); if (err < 0) break; - err = __put_user(err, &compat_entry->msg_len); + err = put_user(err, &compat_entry->msg_len); ++compat_entry; } else { err = ___sys_sendmsg(sock, @@ -2943,16 +2943,16 @@ static int ____sys_recvmsg(struct socket *sock, struct msghdr *msg_sys, if (err < 0) goto out; } - err = __put_user((msg_sys->msg_flags & ~MSG_CMSG_COMPAT), - COMPAT_FLAGS(msg)); + err = put_user((msg_sys->msg_flags & ~MSG_CMSG_COMPAT), + COMPAT_FLAGS(msg)); if (err) goto out; if (MSG_CMSG_COMPAT & flags) - err = __put_user((unsigned long)msg_sys->msg_control - cmsg_ptr, - &msg_compat->msg_controllen); + err = put_user((unsigned long)msg_sys->msg_control - cmsg_ptr, + &msg_compat->msg_controllen); else - err = __put_user((unsigned long)msg_sys->msg_control - cmsg_ptr, - &msg->msg_controllen); + err = put_user((unsigned long)msg_sys->msg_control - cmsg_ptr, + &msg->msg_controllen); if (err) goto out; err = len; @@ -3064,7 +3064,7 @@ static int do_recvmmsg(int fd, struct mmsghdr __user *mmsg, datagrams); if (err < 0) break; - err = __put_user(err, &compat_entry->msg_len); + err = put_user(err, &compat_entry->msg_len); ++compat_entry; } else { err = ___sys_recvmsg(sock,