@@ -71,25 +71,25 @@ static void inet_diag_unlock_handler(const struct inet_diag_handler *handler)
7171
7272void inet_diag_msg_common_fill (struct inet_diag_msg * r , struct sock * sk )
7373{
74- r -> idiag_family = sk -> sk_family ;
74+ r -> idiag_family = READ_ONCE ( sk -> sk_family ) ;
7575
76- r -> id .idiag_sport = htons (sk -> sk_num );
77- r -> id .idiag_dport = sk -> sk_dport ;
78- r -> id .idiag_if = sk -> sk_bound_dev_if ;
76+ r -> id .idiag_sport = htons (READ_ONCE ( sk -> sk_num ) );
77+ r -> id .idiag_dport = READ_ONCE ( sk -> sk_dport ) ;
78+ r -> id .idiag_if = READ_ONCE ( sk -> sk_bound_dev_if ) ;
7979 sock_diag_save_cookie (sk , r -> id .idiag_cookie );
8080
8181#if IS_ENABLED (CONFIG_IPV6 )
82- if (sk -> sk_family == AF_INET6 ) {
83- * (struct in6_addr * )r -> id .idiag_src = sk -> sk_v6_rcv_saddr ;
84- * (struct in6_addr * )r -> id .idiag_dst = sk -> sk_v6_daddr ;
82+ if (r -> idiag_family == AF_INET6 ) {
83+ data_race ( * (struct in6_addr * )r -> id .idiag_src = sk -> sk_v6_rcv_saddr ) ;
84+ data_race ( * (struct in6_addr * )r -> id .idiag_dst = sk -> sk_v6_daddr ) ;
8585 } else
8686#endif
8787 {
8888 memset (& r -> id .idiag_src , 0 , sizeof (r -> id .idiag_src ));
8989 memset (& r -> id .idiag_dst , 0 , sizeof (r -> id .idiag_dst ));
9090
91- r -> id .idiag_src [0 ] = sk -> sk_rcv_saddr ;
92- r -> id .idiag_dst [0 ] = sk -> sk_daddr ;
91+ r -> id .idiag_src [0 ] = READ_ONCE ( sk -> sk_rcv_saddr ) ;
92+ r -> id .idiag_dst [0 ] = READ_ONCE ( sk -> sk_daddr ) ;
9393 }
9494}
9595EXPORT_SYMBOL_GPL (inet_diag_msg_common_fill );
@@ -580,7 +580,7 @@ static void entry_fill_addrs(struct inet_diag_entry *entry,
580580 const struct sock * sk )
581581{
582582#if IS_ENABLED (CONFIG_IPV6 )
583- if (sk -> sk_family == AF_INET6 ) {
583+ if (entry -> family == AF_INET6 ) {
584584 entry -> saddr = sk -> sk_v6_rcv_saddr .s6_addr32 ;
585585 entry -> daddr = sk -> sk_v6_daddr .s6_addr32 ;
586586 } else
@@ -591,31 +591,36 @@ static void entry_fill_addrs(struct inet_diag_entry *entry,
591591 }
592592}
593593
594- int inet_diag_bc_sk (const struct nlattr * bc , struct sock * sk )
594+ int inet_diag_bc_sk (const struct inet_diag_dump_data * cb_data , struct sock * sk )
595595{
596- struct inet_sock * inet = inet_sk (sk );
596+ const struct nlattr * bc = cb_data -> inet_diag_nla_bc ;
597+ const struct inet_sock * inet = inet_sk (sk );
597598 struct inet_diag_entry entry ;
598599
599600 if (!bc )
600601 return 1 ;
601602
602- entry .family = sk -> sk_family ;
603+ entry .family = READ_ONCE ( sk -> sk_family ) ;
603604 entry_fill_addrs (& entry , sk );
604- entry .sport = inet -> inet_num ;
605- entry .dport = ntohs (inet -> inet_dport );
606- entry .ifindex = sk -> sk_bound_dev_if ;
607- entry .userlocks = sk_fullsock (sk ) ? sk -> sk_userlocks : 0 ;
608- if (sk_fullsock (sk ))
609- entry .mark = READ_ONCE (sk -> sk_mark );
610- else if (sk -> sk_state == TCP_NEW_SYN_RECV )
611- entry .mark = inet_rsk (inet_reqsk (sk ))-> ir_mark ;
612- else if (sk -> sk_state == TCP_TIME_WAIT )
613- entry .mark = inet_twsk (sk )-> tw_mark ;
614- else
615- entry .mark = 0 ;
605+ entry .sport = READ_ONCE (inet -> inet_num );
606+ entry .dport = ntohs (READ_ONCE (inet -> inet_dport ));
607+ entry .ifindex = READ_ONCE (sk -> sk_bound_dev_if );
608+ if (cb_data -> userlocks_needed )
609+ entry .userlocks = sk_fullsock (sk ) ? READ_ONCE (sk -> sk_userlocks ) : 0 ;
610+ if (cb_data -> mark_needed ) {
611+ if (sk_fullsock (sk ))
612+ entry .mark = READ_ONCE (sk -> sk_mark );
613+ else if (sk -> sk_state == TCP_NEW_SYN_RECV )
614+ entry .mark = inet_rsk (inet_reqsk (sk ))-> ir_mark ;
615+ else if (sk -> sk_state == TCP_TIME_WAIT )
616+ entry .mark = inet_twsk (sk )-> tw_mark ;
617+ else
618+ entry .mark = 0 ;
619+ }
616620#ifdef CONFIG_SOCK_CGROUP_DATA
617- entry .cgroup_id = sk_fullsock (sk ) ?
618- cgroup_id (sock_cgroup_ptr (& sk -> sk_cgrp_data )) : 0 ;
621+ if (cb_data -> cgroup_needed )
622+ entry .cgroup_id = sk_fullsock (sk ) ?
623+ cgroup_id (sock_cgroup_ptr (& sk -> sk_cgrp_data )) : 0 ;
619624#endif
620625
621626 return inet_diag_bc_run (bc , & entry );
@@ -715,16 +720,21 @@ static bool valid_cgroupcond(const struct inet_diag_bc_op *op, int len,
715720}
716721#endif
717722
718- static int inet_diag_bc_audit (const struct nlattr * attr ,
723+ static int inet_diag_bc_audit (struct inet_diag_dump_data * cb_data ,
719724 const struct sk_buff * skb )
720725{
721- bool net_admin = netlink_net_capable ( skb , CAP_NET_ADMIN ) ;
726+ const struct nlattr * attr = cb_data -> inet_diag_nla_bc ;
722727 const void * bytecode , * bc ;
723728 int bytecode_len , len ;
729+ bool net_admin ;
724730
725- if (!attr || nla_len (attr ) < sizeof (struct inet_diag_bc_op ))
731+ if (!attr )
732+ return 0 ;
733+
734+ if (nla_len (attr ) < sizeof (struct inet_diag_bc_op ))
726735 return - EINVAL ;
727736
737+ net_admin = netlink_net_capable (skb , CAP_NET_ADMIN );
728738 bytecode = bc = nla_data (attr );
729739 len = bytecode_len = nla_len (attr );
730740
@@ -756,14 +766,18 @@ static int inet_diag_bc_audit(const struct nlattr *attr,
756766 return - EPERM ;
757767 if (!valid_markcond (bc , len , & min_len ))
758768 return - EINVAL ;
769+ cb_data -> mark_needed = true;
759770 break ;
760771#ifdef CONFIG_SOCK_CGROUP_DATA
761772 case INET_DIAG_BC_CGROUP_COND :
762773 if (!valid_cgroupcond (bc , len , & min_len ))
763774 return - EINVAL ;
775+ cb_data -> cgroup_needed = true;
764776 break ;
765777#endif
766778 case INET_DIAG_BC_AUTO :
779+ cb_data -> userlocks_needed = true;
780+ fallthrough ;
767781 case INET_DIAG_BC_JMP :
768782 case INET_DIAG_BC_NOP :
769783 break ;
@@ -840,13 +854,10 @@ static int __inet_diag_dump_start(struct netlink_callback *cb, int hdrlen)
840854 kfree (cb_data );
841855 return err ;
842856 }
843- nla = cb_data -> inet_diag_nla_bc ;
844- if (nla ) {
845- err = inet_diag_bc_audit (nla , skb );
846- if (err ) {
847- kfree (cb_data );
848- return err ;
849- }
857+ err = inet_diag_bc_audit (cb_data , skb );
858+ if (err ) {
859+ kfree (cb_data );
860+ return err ;
850861 }
851862
852863 nla = cb_data -> inet_diag_nla_bpf_stgs ;
0 commit comments