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

net: annotate data-races around sock->ops

IPV6_ADDRFORM socket option is evil, because it can change sock->ops
while other threads might read it. Same issue for sk->sk_family
being set to AF_INET.

Adding READ_ONCE() over sock->ops reads is needed for sockets
that might be impacted by IPV6_ADDRFORM.

Note that mptcp_is_tcpsk() can also overwrite sock->ops.

Adding annotations for all sk->sk_family reads will require
more patches :/

BUG: KCSAN: data-race in ____sys_sendmsg / do_ipv6_setsockopt

write to 0xffff888109f24ca0 of 8 bytes by task 4470 on cpu 0:
do_ipv6_setsockopt+0x2c5e/0x2ce0 net/ipv6/ipv6_sockglue.c:491
ipv6_setsockopt+0x57/0x130 net/ipv6/ipv6_sockglue.c:1012
udpv6_setsockopt+0x95/0xa0 net/ipv6/udp.c:1690
sock_common_setsockopt+0x61/0x70 net/core/sock.c:3663
__sys_setsockopt+0x1c3/0x230 net/socket.c:2273
__do_sys_setsockopt net/socket.c:2284 [inline]
__se_sys_setsockopt net/socket.c:2281 [inline]
__x64_sys_setsockopt+0x66/0x80 net/socket.c:2281
do_syscall_x64 arch/x86/entry/common.c:50 [inline]
do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80
entry_SYSCALL_64_after_hwframe+0x63/0xcd

read to 0xffff888109f24ca0 of 8 bytes by task 4469 on cpu 1:
sock_sendmsg_nosec net/socket.c:724 [inline]
sock_sendmsg net/socket.c:747 [inline]
____sys_sendmsg+0x349/0x4c0 net/socket.c:2503
___sys_sendmsg net/socket.c:2557 [inline]
__sys_sendmmsg+0x263/0x500 net/socket.c:2643
__do_sys_sendmmsg net/socket.c:2672 [inline]
__se_sys_sendmmsg net/socket.c:2669 [inline]
__x64_sys_sendmmsg+0x57/0x60 net/socket.c:2669
do_syscall_x64 arch/x86/entry/common.c:50 [inline]
do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80
entry_SYSCALL_64_after_hwframe+0x63/0xcd

value changed: 0xffffffff850e32b8 -> 0xffffffff850da890

Reported by Kernel Concurrency Sanitizer on:
CPU: 1 PID: 4469 Comm: syz-executor.1 Not tainted 6.4.0-rc5-syzkaller-00313-g4c605260bc60 #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/25/2023

Reported-by: syzbot <syzkaller@googlegroups.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Link: https://lore.kernel.org/r/20230808135809.2300241-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Eric Dumazet and committed by
Jakub Kicinski
1ded5e5a e05a53ab

+118 -78
+1 -1
include/linux/net.h
··· 123 123 124 124 struct file *file; 125 125 struct sock *sk; 126 - const struct proto_ops *ops; 126 + const struct proto_ops *ops; /* Might change with IPV6_ADDRFORM or MPTCP. */ 127 127 128 128 struct socket_wq wq; 129 129 };
+2 -2
net/9p/trans_fd.c
··· 1019 1019 } 1020 1020 } 1021 1021 1022 - err = csocket->ops->connect(csocket, 1022 + err = READ_ONCE(csocket->ops)->connect(csocket, 1023 1023 (struct sockaddr *)&sin_server, 1024 1024 sizeof(struct sockaddr_in), 0); 1025 1025 if (err < 0) { ··· 1060 1060 1061 1061 return err; 1062 1062 } 1063 - err = csocket->ops->connect(csocket, (struct sockaddr *)&sun_server, 1063 + err = READ_ONCE(csocket->ops)->connect(csocket, (struct sockaddr *)&sun_server, 1064 1064 sizeof(struct sockaddr_un) - 1, 0); 1065 1065 if (err < 0) { 1066 1066 pr_err("%s (%d): problem connecting socket: %s: %d\n",
+2 -1
net/core/scm.c
··· 130 130 131 131 int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p) 132 132 { 133 + const struct proto_ops *ops = READ_ONCE(sock->ops); 133 134 struct cmsghdr *cmsg; 134 135 int err; 135 136 ··· 154 153 switch (cmsg->cmsg_type) 155 154 { 156 155 case SCM_RIGHTS: 157 - if (!sock->ops || sock->ops->family != PF_UNIX) 156 + if (!ops || ops->family != PF_UNIX) 158 157 goto error; 159 158 err=scm_fp_copy(cmsg, &p->fp); 160 159 if (err<0)
+6 -2
net/core/skmsg.c
··· 1198 1198 static void sk_psock_verdict_data_ready(struct sock *sk) 1199 1199 { 1200 1200 struct socket *sock = sk->sk_socket; 1201 + const struct proto_ops *ops; 1201 1202 int copied; 1202 1203 1203 1204 trace_sk_data_ready(sk); 1204 1205 1205 - if (unlikely(!sock || !sock->ops || !sock->ops->read_skb)) 1206 + if (unlikely(!sock)) 1206 1207 return; 1207 - copied = sock->ops->read_skb(sk, sk_psock_verdict_recv); 1208 + ops = READ_ONCE(sock->ops); 1209 + if (!ops || !ops->read_skb) 1210 + return; 1211 + copied = ops->read_skb(sk, sk_psock_verdict_recv); 1208 1212 if (copied >= 0) { 1209 1213 struct sk_psock *psock; 1210 1214
+17 -7
net/core/sock.c
··· 1277 1277 break; 1278 1278 1279 1279 case SO_RCVLOWAT: 1280 + { 1281 + int (*set_rcvlowat)(struct sock *sk, int val) = NULL; 1282 + 1280 1283 if (val < 0) 1281 1284 val = INT_MAX; 1282 - if (sock && sock->ops->set_rcvlowat) 1283 - ret = sock->ops->set_rcvlowat(sk, val); 1285 + if (sock) 1286 + set_rcvlowat = READ_ONCE(sock->ops)->set_rcvlowat; 1287 + if (set_rcvlowat) 1288 + ret = set_rcvlowat(sk, val); 1284 1289 else 1285 1290 WRITE_ONCE(sk->sk_rcvlowat, val ? : 1); 1286 1291 break; 1287 - 1292 + } 1288 1293 case SO_RCVTIMEO_OLD: 1289 1294 case SO_RCVTIMEO_NEW: 1290 1295 ret = sock_set_timeout(&sk->sk_rcvtimeo, optval, ··· 1384 1379 break; 1385 1380 1386 1381 case SO_PEEK_OFF: 1387 - if (sock->ops->set_peek_off) 1388 - ret = sock->ops->set_peek_off(sk, val); 1382 + { 1383 + int (*set_peek_off)(struct sock *sk, int val); 1384 + 1385 + set_peek_off = READ_ONCE(sock->ops)->set_peek_off; 1386 + if (set_peek_off) 1387 + ret = set_peek_off(sk, val); 1389 1388 else 1390 1389 ret = -EOPNOTSUPP; 1391 1390 break; 1391 + } 1392 1392 1393 1393 case SO_NOFCS: 1394 1394 sock_valbool_flag(sk, SOCK_NOFCS, valbool); ··· 1826 1816 { 1827 1817 struct sockaddr_storage address; 1828 1818 1829 - lv = sock->ops->getname(sock, (struct sockaddr *)&address, 2); 1819 + lv = READ_ONCE(sock->ops)->getname(sock, (struct sockaddr *)&address, 2); 1830 1820 if (lv < 0) 1831 1821 return -ENOTCONN; 1832 1822 if (lv < len) ··· 1868 1858 break; 1869 1859 1870 1860 case SO_PEEK_OFF: 1871 - if (!sock->ops->set_peek_off) 1861 + if (!READ_ONCE(sock->ops)->set_peek_off) 1872 1862 return -EOPNOTSUPP; 1873 1863 1874 1864 v.val = READ_ONCE(sk->sk_peek_off);
+4 -4
net/ipv6/ipv6_sockglue.c
··· 474 474 WRITE_ONCE(sk->sk_prot, &tcp_prot); 475 475 /* Paired with READ_ONCE() in tcp_(get|set)sockopt() */ 476 476 WRITE_ONCE(icsk->icsk_af_ops, &ipv4_specific); 477 - sk->sk_socket->ops = &inet_stream_ops; 478 - sk->sk_family = PF_INET; 477 + WRITE_ONCE(sk->sk_socket->ops, &inet_stream_ops); 478 + WRITE_ONCE(sk->sk_family, PF_INET); 479 479 tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); 480 480 } else { 481 481 struct proto *prot = &udp_prot; ··· 488 488 489 489 /* Paired with READ_ONCE(sk->sk_prot) in inet6_dgram_ops */ 490 490 WRITE_ONCE(sk->sk_prot, prot); 491 - sk->sk_socket->ops = &inet_dgram_ops; 492 - sk->sk_family = PF_INET; 491 + WRITE_ONCE(sk->sk_socket->ops, &inet_dgram_ops); 492 + WRITE_ONCE(sk->sk_family, PF_INET); 493 493 } 494 494 495 495 /* Disable all options not to allocate memory anymore,
+4 -4
net/mptcp/protocol.c
··· 67 67 * Hand the socket over to tcp so all further socket ops 68 68 * bypass mptcp. 69 69 */ 70 - sock->ops = &inet_stream_ops; 70 + WRITE_ONCE(sock->ops, &inet_stream_ops); 71 71 return true; 72 72 #if IS_ENABLED(CONFIG_MPTCP_IPV6) 73 73 } else if (unlikely(sk->sk_prot == &tcpv6_prot)) { 74 - sock->ops = &inet6_stream_ops; 74 + WRITE_ONCE(sock->ops, &inet6_stream_ops); 75 75 return true; 76 76 #endif 77 77 } ··· 3683 3683 goto unlock; 3684 3684 } 3685 3685 3686 - err = ssock->ops->bind(ssock, uaddr, addr_len); 3686 + err = READ_ONCE(ssock->ops)->bind(ssock, uaddr, addr_len); 3687 3687 if (!err) 3688 3688 mptcp_copy_inaddrs(sock->sk, ssock->sk); 3689 3689 ··· 3717 3717 inet_sk_state_store(sk, TCP_LISTEN); 3718 3718 sock_set_flag(sk, SOCK_RCU_FREE); 3719 3719 3720 - err = ssock->ops->listen(ssock, backlog); 3720 + err = READ_ONCE(ssock->ops)->listen(ssock, backlog); 3721 3721 inet_sk_state_store(sk, inet_sk_state_load(ssock->sk)); 3722 3722 if (!err) { 3723 3723 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
+80 -56
net/socket.c
··· 136 136 static void sock_show_fdinfo(struct seq_file *m, struct file *f) 137 137 { 138 138 struct socket *sock = f->private_data; 139 + const struct proto_ops *ops = READ_ONCE(sock->ops); 139 140 140 - if (sock->ops->show_fdinfo) 141 - sock->ops->show_fdinfo(m, sock); 141 + if (ops->show_fdinfo) 142 + ops->show_fdinfo(m, sock); 142 143 } 143 144 #else 144 145 #define sock_show_fdinfo NULL ··· 647 646 648 647 static void __sock_release(struct socket *sock, struct inode *inode) 649 648 { 650 - if (sock->ops) { 651 - struct module *owner = sock->ops->owner; 649 + const struct proto_ops *ops = READ_ONCE(sock->ops); 650 + 651 + if (ops) { 652 + struct module *owner = ops->owner; 652 653 653 654 if (inode) 654 655 inode_lock(inode); 655 - sock->ops->release(sock); 656 + ops->release(sock); 656 657 sock->sk = NULL; 657 658 if (inode) 658 659 inode_unlock(inode); ··· 725 722 726 723 static inline int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg) 727 724 { 728 - int ret = INDIRECT_CALL_INET(sock->ops->sendmsg, inet6_sendmsg, 725 + int ret = INDIRECT_CALL_INET(READ_ONCE(sock->ops)->sendmsg, inet6_sendmsg, 729 726 inet_sendmsg, sock, msg, 730 727 msg_data_left(msg)); 731 728 BUG_ON(ret == -EIOCBQUEUED); ··· 789 786 struct kvec *vec, size_t num, size_t size) 790 787 { 791 788 struct socket *sock = sk->sk_socket; 789 + const struct proto_ops *ops = READ_ONCE(sock->ops); 792 790 793 - if (!sock->ops->sendmsg_locked) 791 + if (!ops->sendmsg_locked) 794 792 return sock_no_sendmsg_locked(sk, msg, size); 795 793 796 794 iov_iter_kvec(&msg->msg_iter, ITER_SOURCE, vec, num, size); 797 795 798 - return sock->ops->sendmsg_locked(sk, msg, msg_data_left(msg)); 796 + return ops->sendmsg_locked(sk, msg, msg_data_left(msg)); 799 797 } 800 798 EXPORT_SYMBOL(kernel_sendmsg_locked); 801 799 ··· 1021 1017 static inline int sock_recvmsg_nosec(struct socket *sock, struct msghdr *msg, 1022 1018 int flags) 1023 1019 { 1024 - int ret = INDIRECT_CALL_INET(sock->ops->recvmsg, inet6_recvmsg, 1020 + int ret = INDIRECT_CALL_INET(READ_ONCE(sock->ops)->recvmsg, 1021 + inet6_recvmsg, 1025 1022 inet_recvmsg, sock, msg, 1026 1023 msg_data_left(msg), flags); 1027 1024 if (trace_sock_recv_length_enabled()) ··· 1077 1072 unsigned int flags) 1078 1073 { 1079 1074 struct socket *sock = file->private_data; 1075 + const struct proto_ops *ops; 1080 1076 1081 - if (unlikely(!sock->ops->splice_read)) 1077 + ops = READ_ONCE(sock->ops); 1078 + if (unlikely(!ops->splice_read)) 1082 1079 return copy_splice_read(file, ppos, pipe, len, flags); 1083 1080 1084 - return sock->ops->splice_read(sock, ppos, pipe, len, flags); 1081 + return ops->splice_read(sock, ppos, pipe, len, flags); 1085 1082 } 1086 1083 1087 1084 static void sock_splice_eof(struct file *file) 1088 1085 { 1089 1086 struct socket *sock = file->private_data; 1087 + const struct proto_ops *ops; 1090 1088 1091 - if (sock->ops->splice_eof) 1092 - sock->ops->splice_eof(sock); 1089 + ops = READ_ONCE(sock->ops); 1090 + if (ops->splice_eof) 1091 + ops->splice_eof(sock); 1093 1092 } 1094 1093 1095 1094 static ssize_t sock_read_iter(struct kiocb *iocb, struct iov_iter *to) ··· 1190 1181 static long sock_do_ioctl(struct net *net, struct socket *sock, 1191 1182 unsigned int cmd, unsigned long arg) 1192 1183 { 1184 + const struct proto_ops *ops = READ_ONCE(sock->ops); 1193 1185 struct ifreq ifr; 1194 1186 bool need_copyout; 1195 1187 int err; 1196 1188 void __user *argp = (void __user *)arg; 1197 1189 void __user *data; 1198 1190 1199 - err = sock->ops->ioctl(sock, cmd, arg); 1191 + err = ops->ioctl(sock, cmd, arg); 1200 1192 1201 1193 /* 1202 1194 * If this ioctl is unknown try to hand it down ··· 1226 1216 1227 1217 static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg) 1228 1218 { 1219 + const struct proto_ops *ops; 1229 1220 struct socket *sock; 1230 1221 struct sock *sk; 1231 1222 void __user *argp = (void __user *)arg; ··· 1234 1223 struct net *net; 1235 1224 1236 1225 sock = file->private_data; 1226 + ops = READ_ONCE(sock->ops); 1237 1227 sk = sock->sk; 1238 1228 net = sock_net(sk); 1239 1229 if (unlikely(cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15))) { ··· 1292 1280 break; 1293 1281 case SIOCGSTAMP_OLD: 1294 1282 case SIOCGSTAMPNS_OLD: 1295 - if (!sock->ops->gettstamp) { 1283 + if (!ops->gettstamp) { 1296 1284 err = -ENOIOCTLCMD; 1297 1285 break; 1298 1286 } 1299 - err = sock->ops->gettstamp(sock, argp, 1300 - cmd == SIOCGSTAMP_OLD, 1301 - !IS_ENABLED(CONFIG_64BIT)); 1287 + err = ops->gettstamp(sock, argp, 1288 + cmd == SIOCGSTAMP_OLD, 1289 + !IS_ENABLED(CONFIG_64BIT)); 1302 1290 break; 1303 1291 case SIOCGSTAMP_NEW: 1304 1292 case SIOCGSTAMPNS_NEW: 1305 - if (!sock->ops->gettstamp) { 1293 + if (!ops->gettstamp) { 1306 1294 err = -ENOIOCTLCMD; 1307 1295 break; 1308 1296 } 1309 - err = sock->ops->gettstamp(sock, argp, 1310 - cmd == SIOCGSTAMP_NEW, 1311 - false); 1297 + err = ops->gettstamp(sock, argp, 1298 + cmd == SIOCGSTAMP_NEW, 1299 + false); 1312 1300 break; 1313 1301 1314 1302 case SIOCGIFCONF: ··· 1369 1357 static __poll_t sock_poll(struct file *file, poll_table *wait) 1370 1358 { 1371 1359 struct socket *sock = file->private_data; 1360 + const struct proto_ops *ops = READ_ONCE(sock->ops); 1372 1361 __poll_t events = poll_requested_events(wait), flag = 0; 1373 1362 1374 - if (!sock->ops->poll) 1363 + if (!ops->poll) 1375 1364 return 0; 1376 1365 1377 1366 if (sk_can_busy_loop(sock->sk)) { ··· 1384 1371 flag = POLL_BUSY_LOOP; 1385 1372 } 1386 1373 1387 - return sock->ops->poll(file, sock, wait) | flag; 1374 + return ops->poll(file, sock, wait) | flag; 1388 1375 } 1389 1376 1390 1377 static int sock_mmap(struct file *file, struct vm_area_struct *vma) 1391 1378 { 1392 1379 struct socket *sock = file->private_data; 1393 1380 1394 - return sock->ops->mmap(file, sock, vma); 1381 + return READ_ONCE(sock->ops)->mmap(file, sock, vma); 1395 1382 } 1396 1383 1397 1384 static int sock_close(struct inode *inode, struct file *filp) ··· 1741 1728 goto out; 1742 1729 } 1743 1730 1744 - err = sock1->ops->socketpair(sock1, sock2); 1731 + err = READ_ONCE(sock1->ops)->socketpair(sock1, sock2); 1745 1732 if (unlikely(err < 0)) { 1746 1733 sock_release(sock2); 1747 1734 sock_release(sock1); ··· 1802 1789 (struct sockaddr *)&address, 1803 1790 addrlen); 1804 1791 if (!err) 1805 - err = sock->ops->bind(sock, 1792 + err = READ_ONCE(sock->ops)->bind(sock, 1806 1793 (struct sockaddr *) 1807 1794 &address, addrlen); 1808 1795 } ··· 1836 1823 1837 1824 err = security_socket_listen(sock, backlog); 1838 1825 if (!err) 1839 - err = sock->ops->listen(sock, backlog); 1826 + err = READ_ONCE(sock->ops)->listen(sock, backlog); 1840 1827 1841 1828 fput_light(sock->file, fput_needed); 1842 1829 } ··· 1856 1843 struct file *newfile; 1857 1844 int err, len; 1858 1845 struct sockaddr_storage address; 1846 + const struct proto_ops *ops; 1859 1847 1860 1848 sock = sock_from_file(file); 1861 1849 if (!sock) ··· 1865 1851 newsock = sock_alloc(); 1866 1852 if (!newsock) 1867 1853 return ERR_PTR(-ENFILE); 1854 + ops = READ_ONCE(sock->ops); 1868 1855 1869 1856 newsock->type = sock->type; 1870 - newsock->ops = sock->ops; 1857 + newsock->ops = ops; 1871 1858 1872 1859 /* 1873 1860 * We don't need try_module_get here, as the listening socket (sock) 1874 1861 * has the protocol module (sock->ops->owner) held. 1875 1862 */ 1876 - __module_get(newsock->ops->owner); 1863 + __module_get(ops->owner); 1877 1864 1878 1865 newfile = sock_alloc_file(newsock, flags, sock->sk->sk_prot_creator->name); 1879 1866 if (IS_ERR(newfile)) ··· 1884 1869 if (err) 1885 1870 goto out_fd; 1886 1871 1887 - err = sock->ops->accept(sock, newsock, sock->file->f_flags | file_flags, 1872 + err = ops->accept(sock, newsock, sock->file->f_flags | file_flags, 1888 1873 false); 1889 1874 if (err < 0) 1890 1875 goto out_fd; 1891 1876 1892 1877 if (upeer_sockaddr) { 1893 - len = newsock->ops->getname(newsock, 1894 - (struct sockaddr *)&address, 2); 1878 + len = ops->getname(newsock, (struct sockaddr *)&address, 2); 1895 1879 if (len < 0) { 1896 1880 err = -ECONNABORTED; 1897 1881 goto out_fd; ··· 2003 1989 if (err) 2004 1990 goto out; 2005 1991 2006 - err = sock->ops->connect(sock, (struct sockaddr *)address, addrlen, 2007 - sock->file->f_flags | file_flags); 1992 + err = READ_ONCE(sock->ops)->connect(sock, (struct sockaddr *)address, 1993 + addrlen, sock->file->f_flags | file_flags); 2008 1994 out: 2009 1995 return err; 2010 1996 } ··· 2053 2039 if (err) 2054 2040 goto out_put; 2055 2041 2056 - err = sock->ops->getname(sock, (struct sockaddr *)&address, 0); 2042 + err = READ_ONCE(sock->ops)->getname(sock, (struct sockaddr *)&address, 0); 2057 2043 if (err < 0) 2058 2044 goto out_put; 2059 2045 /* "err" is actually length in this case */ ··· 2085 2071 2086 2072 sock = sockfd_lookup_light(fd, &err, &fput_needed); 2087 2073 if (sock != NULL) { 2074 + const struct proto_ops *ops = READ_ONCE(sock->ops); 2075 + 2088 2076 err = security_socket_getpeername(sock); 2089 2077 if (err) { 2090 2078 fput_light(sock->file, fput_needed); 2091 2079 return err; 2092 2080 } 2093 2081 2094 - err = sock->ops->getname(sock, (struct sockaddr *)&address, 1); 2082 + err = ops->getname(sock, (struct sockaddr *)&address, 1); 2095 2083 if (err >= 0) 2096 2084 /* "err" is actually length in this case */ 2097 2085 err = move_addr_to_user(&address, err, usockaddr, ··· 2243 2227 int optlen) 2244 2228 { 2245 2229 sockptr_t optval = USER_SOCKPTR(user_optval); 2230 + const struct proto_ops *ops; 2246 2231 char *kernel_optval = NULL; 2247 2232 int err, fput_needed; 2248 2233 struct socket *sock; ··· 2272 2255 2273 2256 if (kernel_optval) 2274 2257 optval = KERNEL_SOCKPTR(kernel_optval); 2258 + ops = READ_ONCE(sock->ops); 2275 2259 if (level == SOL_SOCKET && !sock_use_custom_sol_socket(sock)) 2276 2260 err = sock_setsockopt(sock, level, optname, optval, optlen); 2277 - else if (unlikely(!sock->ops->setsockopt)) 2261 + else if (unlikely(!ops->setsockopt)) 2278 2262 err = -EOPNOTSUPP; 2279 2263 else 2280 - err = sock->ops->setsockopt(sock, level, optname, optval, 2264 + err = ops->setsockopt(sock, level, optname, optval, 2281 2265 optlen); 2282 2266 kfree(kernel_optval); 2283 2267 out_put: ··· 2303 2285 int __user *optlen) 2304 2286 { 2305 2287 int max_optlen __maybe_unused; 2288 + const struct proto_ops *ops; 2306 2289 int err, fput_needed; 2307 2290 struct socket *sock; 2308 2291 ··· 2318 2299 if (!in_compat_syscall()) 2319 2300 max_optlen = BPF_CGROUP_GETSOCKOPT_MAX_OPTLEN(optlen); 2320 2301 2302 + ops = READ_ONCE(sock->ops); 2321 2303 if (level == SOL_SOCKET) 2322 2304 err = sock_getsockopt(sock, level, optname, optval, optlen); 2323 - else if (unlikely(!sock->ops->getsockopt)) 2305 + else if (unlikely(!ops->getsockopt)) 2324 2306 err = -EOPNOTSUPP; 2325 2307 else 2326 - err = sock->ops->getsockopt(sock, level, optname, optval, 2308 + err = ops->getsockopt(sock, level, optname, optval, 2327 2309 optlen); 2328 2310 2329 2311 if (!in_compat_syscall()) ··· 2352 2332 2353 2333 err = security_socket_shutdown(sock, how); 2354 2334 if (!err) 2355 - err = sock->ops->shutdown(sock, how); 2335 + err = READ_ONCE(sock->ops)->shutdown(sock, how); 2356 2336 2357 2337 return err; 2358 2338 } ··· 3344 3324 void __user *argp = compat_ptr(arg); 3345 3325 struct sock *sk = sock->sk; 3346 3326 struct net *net = sock_net(sk); 3327 + const struct proto_ops *ops; 3347 3328 3348 3329 if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) 3349 3330 return sock_ioctl(file, cmd, (unsigned long)argp); ··· 3354 3333 return compat_siocwandev(net, argp); 3355 3334 case SIOCGSTAMP_OLD: 3356 3335 case SIOCGSTAMPNS_OLD: 3357 - if (!sock->ops->gettstamp) 3336 + ops = READ_ONCE(sock->ops); 3337 + if (!ops->gettstamp) 3358 3338 return -ENOIOCTLCMD; 3359 - return sock->ops->gettstamp(sock, argp, cmd == SIOCGSTAMP_OLD, 3360 - !COMPAT_USE_64BIT_TIME); 3339 + return ops->gettstamp(sock, argp, cmd == SIOCGSTAMP_OLD, 3340 + !COMPAT_USE_64BIT_TIME); 3361 3341 3362 3342 case SIOCETHTOOL: 3363 3343 case SIOCBONDSLAVEINFOQUERY: ··· 3439 3417 unsigned long arg) 3440 3418 { 3441 3419 struct socket *sock = file->private_data; 3420 + const struct proto_ops *ops = READ_ONCE(sock->ops); 3442 3421 int ret = -ENOIOCTLCMD; 3443 3422 struct sock *sk; 3444 3423 struct net *net; ··· 3447 3424 sk = sock->sk; 3448 3425 net = sock_net(sk); 3449 3426 3450 - if (sock->ops->compat_ioctl) 3451 - ret = sock->ops->compat_ioctl(sock, cmd, arg); 3427 + if (ops->compat_ioctl) 3428 + ret = ops->compat_ioctl(sock, cmd, arg); 3452 3429 3453 3430 if (ret == -ENOIOCTLCMD && 3454 3431 (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST)) ··· 3472 3449 3473 3450 int kernel_bind(struct socket *sock, struct sockaddr *addr, int addrlen) 3474 3451 { 3475 - return sock->ops->bind(sock, addr, addrlen); 3452 + return READ_ONCE(sock->ops)->bind(sock, addr, addrlen); 3476 3453 } 3477 3454 EXPORT_SYMBOL(kernel_bind); 3478 3455 ··· 3486 3463 3487 3464 int kernel_listen(struct socket *sock, int backlog) 3488 3465 { 3489 - return sock->ops->listen(sock, backlog); 3466 + return READ_ONCE(sock->ops)->listen(sock, backlog); 3490 3467 } 3491 3468 EXPORT_SYMBOL(kernel_listen); 3492 3469 ··· 3504 3481 int kernel_accept(struct socket *sock, struct socket **newsock, int flags) 3505 3482 { 3506 3483 struct sock *sk = sock->sk; 3484 + const struct proto_ops *ops = READ_ONCE(sock->ops); 3507 3485 int err; 3508 3486 3509 3487 err = sock_create_lite(sk->sk_family, sk->sk_type, sk->sk_protocol, ··· 3512 3488 if (err < 0) 3513 3489 goto done; 3514 3490 3515 - err = sock->ops->accept(sock, *newsock, flags, true); 3491 + err = ops->accept(sock, *newsock, flags, true); 3516 3492 if (err < 0) { 3517 3493 sock_release(*newsock); 3518 3494 *newsock = NULL; 3519 3495 goto done; 3520 3496 } 3521 3497 3522 - (*newsock)->ops = sock->ops; 3523 - __module_get((*newsock)->ops->owner); 3498 + (*newsock)->ops = ops; 3499 + __module_get(ops->owner); 3524 3500 3525 3501 done: 3526 3502 return err; ··· 3543 3519 int kernel_connect(struct socket *sock, struct sockaddr *addr, int addrlen, 3544 3520 int flags) 3545 3521 { 3546 - return sock->ops->connect(sock, addr, addrlen, flags); 3522 + return READ_ONCE(sock->ops)->connect(sock, addr, addrlen, flags); 3547 3523 } 3548 3524 EXPORT_SYMBOL(kernel_connect); 3549 3525 ··· 3558 3534 3559 3535 int kernel_getsockname(struct socket *sock, struct sockaddr *addr) 3560 3536 { 3561 - return sock->ops->getname(sock, addr, 0); 3537 + return READ_ONCE(sock->ops)->getname(sock, addr, 0); 3562 3538 } 3563 3539 EXPORT_SYMBOL(kernel_getsockname); 3564 3540 ··· 3573 3549 3574 3550 int kernel_getpeername(struct socket *sock, struct sockaddr *addr) 3575 3551 { 3576 - return sock->ops->getname(sock, addr, 1); 3552 + return READ_ONCE(sock->ops)->getname(sock, addr, 1); 3577 3553 } 3578 3554 EXPORT_SYMBOL(kernel_getpeername); 3579 3555 ··· 3587 3563 3588 3564 int kernel_sock_shutdown(struct socket *sock, enum sock_shutdown_cmd how) 3589 3565 { 3590 - return sock->ops->shutdown(sock, how); 3566 + return READ_ONCE(sock->ops)->shutdown(sock, how); 3591 3567 } 3592 3568 EXPORT_SYMBOL(kernel_sock_shutdown); 3593 3569
+2 -1
net/unix/scm.c
··· 29 29 /* Socket ? */ 30 30 if (S_ISSOCK(inode->i_mode) && !(filp->f_mode & FMODE_PATH)) { 31 31 struct socket *sock = SOCKET_I(inode); 32 + const struct proto_ops *ops = READ_ONCE(sock->ops); 32 33 struct sock *s = sock->sk; 33 34 34 35 /* PF_UNIX ? */ 35 - if (s && sock->ops && sock->ops->family == PF_UNIX) 36 + if (s && ops && ops->family == PF_UNIX) 36 37 u_sock = s; 37 38 } else { 38 39 /* Could be an io_uring instance */