Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net: remove one stac/clac pair from move_addr_to_user()

Convert the get_user() and __put_user() code to the
fast masked_user_access_begin()/unsafe_{get|put}_user()
variant.

This patch increases the performance of an UDP recvfrom()
receiver (netserver) on 120 bytes messages by 7 %
on an AMD EPYC 7B12 64-Core Processor platform.

Presence of audit_sockaddr() makes difficult
to avoid the stac/clac pair in the copy_to_user() call,
this is left for a future patch.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20250925230929.3727873-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Eric Dumazet and committed by
Jakub Kicinski
1fb0e471 2b235765

+24 -11
+24 -11
net/socket.c
··· 276 276 static int move_addr_to_user(struct sockaddr_storage *kaddr, int klen, 277 277 void __user *uaddr, int __user *ulen) 278 278 { 279 - int err; 280 279 int len; 281 280 282 281 BUG_ON(klen > sizeof(struct sockaddr_storage)); 283 - err = get_user(len, ulen); 284 - if (err) 285 - return err; 282 + 283 + if (can_do_masked_user_access()) 284 + ulen = masked_user_access_begin(ulen); 285 + else if (!user_access_begin(ulen, 4)) 286 + return -EFAULT; 287 + 288 + unsafe_get_user(len, ulen, efault_end); 289 + 286 290 if (len > klen) 287 291 len = klen; 288 - if (len < 0) 289 - return -EINVAL; 292 + /* 293 + * "fromlen shall refer to the value before truncation.." 294 + * 1003.1g 295 + */ 296 + if (len >= 0) 297 + unsafe_put_user(klen, ulen, efault_end); 298 + 299 + user_access_end(); 300 + 290 301 if (len) { 302 + if (len < 0) 303 + return -EINVAL; 291 304 if (audit_sockaddr(klen, kaddr)) 292 305 return -ENOMEM; 293 306 if (copy_to_user(uaddr, kaddr, len)) 294 307 return -EFAULT; 295 308 } 296 - /* 297 - * "fromlen shall refer to the value before truncation.." 298 - * 1003.1g 299 - */ 300 - return __put_user(klen, ulen); 309 + return 0; 310 + 311 + efault_end: 312 + user_access_end(); 313 + return -EFAULT; 301 314 } 302 315 303 316 static struct kmem_cache *sock_inode_cachep __ro_after_init;