@@ -429,6 +429,7 @@ static int sock_set_timeout(long *timeo_p, sockptr_t optval, int optlen,
429429{
430430 struct __kernel_sock_timeval tv ;
431431 int err = sock_copy_user_timeval (& tv , optval , optlen , old_timeval );
432+ long val ;
432433
433434 if (err )
434435 return err ;
@@ -439,19 +440,20 @@ static int sock_set_timeout(long *timeo_p, sockptr_t optval, int optlen,
439440 if (tv .tv_sec < 0 ) {
440441 static int warned __read_mostly ;
441442
442- * timeo_p = 0 ;
443+ WRITE_ONCE ( * timeo_p , 0 ) ;
443444 if (warned < 10 && net_ratelimit ()) {
444445 warned ++ ;
445446 pr_info ("%s: `%s' (pid %d) tries to set negative timeout\n" ,
446447 __func__ , current -> comm , task_pid_nr (current ));
447448 }
448449 return 0 ;
449450 }
450- * timeo_p = MAX_SCHEDULE_TIMEOUT ;
451- if (tv .tv_sec == 0 && tv .tv_usec == 0 )
452- return 0 ;
453- if (tv .tv_sec < (MAX_SCHEDULE_TIMEOUT / HZ - 1 ))
454- * timeo_p = tv .tv_sec * HZ + DIV_ROUND_UP ((unsigned long )tv .tv_usec , USEC_PER_SEC / HZ );
451+ val = MAX_SCHEDULE_TIMEOUT ;
452+ if ((tv .tv_sec || tv .tv_usec ) &&
453+ (tv .tv_sec < (MAX_SCHEDULE_TIMEOUT / HZ - 1 )))
454+ val = tv .tv_sec * HZ + DIV_ROUND_UP ((unsigned long )tv .tv_usec ,
455+ USEC_PER_SEC / HZ );
456+ WRITE_ONCE (* timeo_p , val );
455457 return 0 ;
456458}
457459
@@ -804,7 +806,7 @@ EXPORT_SYMBOL(sock_no_linger);
804806void sock_set_priority (struct sock * sk , u32 priority )
805807{
806808 lock_sock (sk );
807- sk -> sk_priority = priority ;
809+ WRITE_ONCE ( sk -> sk_priority , priority ) ;
808810 release_sock (sk );
809811}
810812EXPORT_SYMBOL (sock_set_priority );
@@ -813,9 +815,9 @@ void sock_set_sndtimeo(struct sock *sk, s64 secs)
813815{
814816 lock_sock (sk );
815817 if (secs && secs < MAX_SCHEDULE_TIMEOUT / HZ - 1 )
816- sk -> sk_sndtimeo = secs * HZ ;
818+ WRITE_ONCE ( sk -> sk_sndtimeo , secs * HZ ) ;
817819 else
818- sk -> sk_sndtimeo = MAX_SCHEDULE_TIMEOUT ;
820+ WRITE_ONCE ( sk -> sk_sndtimeo , MAX_SCHEDULE_TIMEOUT ) ;
819821 release_sock (sk );
820822}
821823EXPORT_SYMBOL (sock_set_sndtimeo );
@@ -988,7 +990,7 @@ EXPORT_SYMBOL(sock_set_rcvbuf);
988990static void __sock_set_mark (struct sock * sk , u32 val )
989991{
990992 if (val != sk -> sk_mark ) {
991- sk -> sk_mark = val ;
993+ WRITE_ONCE ( sk -> sk_mark , val ) ;
992994 sk_dst_reset (sk );
993995 }
994996}
@@ -1007,7 +1009,7 @@ static void sock_release_reserved_memory(struct sock *sk, int bytes)
10071009 bytes = round_down (bytes , PAGE_SIZE );
10081010
10091011 WARN_ON (bytes > sk -> sk_reserved_mem );
1010- sk -> sk_reserved_mem -= bytes ;
1012+ WRITE_ONCE ( sk -> sk_reserved_mem , sk -> sk_reserved_mem - bytes ) ;
10111013 sk_mem_reclaim (sk );
10121014}
10131015
@@ -1044,7 +1046,8 @@ static int sock_reserve_memory(struct sock *sk, int bytes)
10441046 }
10451047 sk -> sk_forward_alloc += pages << PAGE_SHIFT ;
10461048
1047- sk -> sk_reserved_mem += pages << PAGE_SHIFT ;
1049+ WRITE_ONCE (sk -> sk_reserved_mem ,
1050+ sk -> sk_reserved_mem + (pages << PAGE_SHIFT ));
10481051
10491052 return 0 ;
10501053}
@@ -1213,7 +1216,7 @@ int sk_setsockopt(struct sock *sk, int level, int optname,
12131216 if ((val >= 0 && val <= 6 ) ||
12141217 sockopt_ns_capable (sock_net (sk )-> user_ns , CAP_NET_RAW ) ||
12151218 sockopt_ns_capable (sock_net (sk )-> user_ns , CAP_NET_ADMIN ))
1216- sk -> sk_priority = val ;
1219+ WRITE_ONCE ( sk -> sk_priority , val ) ;
12171220 else
12181221 ret = - EPERM ;
12191222 break ;
@@ -1438,7 +1441,8 @@ int sk_setsockopt(struct sock *sk, int level, int optname,
14381441 cmpxchg (& sk -> sk_pacing_status ,
14391442 SK_PACING_NONE ,
14401443 SK_PACING_NEEDED );
1441- sk -> sk_max_pacing_rate = ulval ;
1444+ /* Pairs with READ_ONCE() from sk_getsockopt() */
1445+ WRITE_ONCE (sk -> sk_max_pacing_rate , ulval );
14421446 sk -> sk_pacing_rate = min (sk -> sk_pacing_rate , ulval );
14431447 break ;
14441448 }
@@ -1533,7 +1537,9 @@ int sk_setsockopt(struct sock *sk, int level, int optname,
15331537 }
15341538 if ((u8 )val == SOCK_TXREHASH_DEFAULT )
15351539 val = READ_ONCE (sock_net (sk )-> core .sysctl_txrehash );
1536- /* Paired with READ_ONCE() in tcp_rtx_synack() */
1540+ /* Paired with READ_ONCE() in tcp_rtx_synack()
1541+ * and sk_getsockopt().
1542+ */
15371543 WRITE_ONCE (sk -> sk_txrehash , (u8 )val );
15381544 break ;
15391545
@@ -1633,11 +1639,11 @@ int sk_getsockopt(struct sock *sk, int level, int optname,
16331639 break ;
16341640
16351641 case SO_SNDBUF :
1636- v .val = sk -> sk_sndbuf ;
1642+ v .val = READ_ONCE ( sk -> sk_sndbuf ) ;
16371643 break ;
16381644
16391645 case SO_RCVBUF :
1640- v .val = sk -> sk_rcvbuf ;
1646+ v .val = READ_ONCE ( sk -> sk_rcvbuf ) ;
16411647 break ;
16421648
16431649 case SO_REUSEADDR :
@@ -1679,7 +1685,7 @@ int sk_getsockopt(struct sock *sk, int level, int optname,
16791685 break ;
16801686
16811687 case SO_PRIORITY :
1682- v .val = sk -> sk_priority ;
1688+ v .val = READ_ONCE ( sk -> sk_priority ) ;
16831689 break ;
16841690
16851691 case SO_LINGER :
@@ -1717,16 +1723,18 @@ int sk_getsockopt(struct sock *sk, int level, int optname,
17171723
17181724 case SO_RCVTIMEO_OLD :
17191725 case SO_RCVTIMEO_NEW :
1720- lv = sock_get_timeout (sk -> sk_rcvtimeo , & v , SO_RCVTIMEO_OLD == optname );
1726+ lv = sock_get_timeout (READ_ONCE (sk -> sk_rcvtimeo ), & v ,
1727+ SO_RCVTIMEO_OLD == optname );
17211728 break ;
17221729
17231730 case SO_SNDTIMEO_OLD :
17241731 case SO_SNDTIMEO_NEW :
1725- lv = sock_get_timeout (sk -> sk_sndtimeo , & v , SO_SNDTIMEO_OLD == optname );
1732+ lv = sock_get_timeout (READ_ONCE (sk -> sk_sndtimeo ), & v ,
1733+ SO_SNDTIMEO_OLD == optname );
17261734 break ;
17271735
17281736 case SO_RCVLOWAT :
1729- v .val = sk -> sk_rcvlowat ;
1737+ v .val = READ_ONCE ( sk -> sk_rcvlowat ) ;
17301738 break ;
17311739
17321740 case SO_SNDLOWAT :
@@ -1843,7 +1851,7 @@ int sk_getsockopt(struct sock *sk, int level, int optname,
18431851 optval , optlen , len );
18441852
18451853 case SO_MARK :
1846- v .val = sk -> sk_mark ;
1854+ v .val = READ_ONCE ( sk -> sk_mark ) ;
18471855 break ;
18481856
18491857 case SO_RCVMARK :
@@ -1862,7 +1870,7 @@ int sk_getsockopt(struct sock *sk, int level, int optname,
18621870 if (!sock -> ops -> set_peek_off )
18631871 return - EOPNOTSUPP ;
18641872
1865- v .val = sk -> sk_peek_off ;
1873+ v .val = READ_ONCE ( sk -> sk_peek_off ) ;
18661874 break ;
18671875 case SO_NOFCS :
18681876 v .val = sock_flag (sk , SOCK_NOFCS );
@@ -1892,20 +1900,22 @@ int sk_getsockopt(struct sock *sk, int level, int optname,
18921900
18931901#ifdef CONFIG_NET_RX_BUSY_POLL
18941902 case SO_BUSY_POLL :
1895- v .val = sk -> sk_ll_usec ;
1903+ v .val = READ_ONCE ( sk -> sk_ll_usec ) ;
18961904 break ;
18971905 case SO_PREFER_BUSY_POLL :
18981906 v .val = READ_ONCE (sk -> sk_prefer_busy_poll );
18991907 break ;
19001908#endif
19011909
19021910 case SO_MAX_PACING_RATE :
1911+ /* The READ_ONCE() pair with the WRITE_ONCE() in sk_setsockopt() */
19031912 if (sizeof (v .ulval ) != sizeof (v .val ) && len >= sizeof (v .ulval )) {
19041913 lv = sizeof (v .ulval );
1905- v .ulval = sk -> sk_max_pacing_rate ;
1914+ v .ulval = READ_ONCE ( sk -> sk_max_pacing_rate ) ;
19061915 } else {
19071916 /* 32bit version */
1908- v .val = min_t (unsigned long , sk -> sk_max_pacing_rate , ~0U );
1917+ v .val = min_t (unsigned long , ~0U ,
1918+ READ_ONCE (sk -> sk_max_pacing_rate ));
19091919 }
19101920 break ;
19111921
@@ -1973,11 +1983,12 @@ int sk_getsockopt(struct sock *sk, int level, int optname,
19731983 break ;
19741984
19751985 case SO_RESERVE_MEM :
1976- v .val = sk -> sk_reserved_mem ;
1986+ v .val = READ_ONCE ( sk -> sk_reserved_mem ) ;
19771987 break ;
19781988
19791989 case SO_TXREHASH :
1980- v .val = sk -> sk_txrehash ;
1990+ /* Paired with WRITE_ONCE() in sk_setsockopt() */
1991+ v .val = READ_ONCE (sk -> sk_txrehash );
19811992 break ;
19821993
19831994 default :
@@ -3168,7 +3179,7 @@ EXPORT_SYMBOL(__sk_mem_reclaim);
31683179
31693180int sk_set_peek_off (struct sock * sk , int val )
31703181{
3171- sk -> sk_peek_off = val ;
3182+ WRITE_ONCE ( sk -> sk_peek_off , val ) ;
31723183 return 0 ;
31733184}
31743185EXPORT_SYMBOL_GPL (sk_set_peek_off );
0 commit comments