sctp_rcv() reads sk->sk_bound_dev_if twice while the socket is not locked. Another cpu could change this field under us.
Unified · Split
| @@ -92,6 +92,7 @@ int sctp_rcv(struct sk_buff *skb) · 91 unmodified lines | ||
| 92 | 92 | struct sctp_chunk *chunk; |
| 93 | 93 | union sctp_addr src; |
| 94 | 94 | union sctp_addr dest; |
| 95 | + int bound_dev_if; | |
| 95 | 96 | int family; |
| 96 | 97 | struct sctp_af *af; |
| 97 | 98 | struct net *net = dev_net(skb->dev); |
| @@ -169,7 +170,8 @@ int sctp_rcv(struct sk_buff *skb) · 71 unmodified lines | ||
| 169 | 170 | * If a frame arrives on an interface and the receiving socket is |
| 170 | 171 | * bound to another interface, via SO_BINDTODEVICE, treat it as OOTB |
| 171 | 172 | */ |
| 172 | − if (sk->sk_bound_dev_if && (sk->sk_bound_dev_if != af->skb_iif(skb))) { | |
| 173 | + bound_dev_if = READ_ONCE(sk->sk_bound_dev_if); | |
| 174 | + if (bound_dev_if && (bound_dev_if != af->skb_iif(skb))) { | |
| 173 | 175 | if (transport) { |
| 174 | 176 | sctp_transport_put(transport); |
| 175 | 177 | asoc = NULL; |