syzbot reported that udp->gro_enabled can be read locklessly.
Use one atomic bit from udp->udp_flags.
Fixes: e20cf8d3f1f7 ("udp: implement GRO for plain UDP sockets.")
Reported-by: syzbot <syzkaller@googlegroups.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
        UDP_FLAGS_CORK,         /* Cork is required */
        UDP_FLAGS_NO_CHECK6_TX, /* Send zero UDP6 checksums on TX? */
        UDP_FLAGS_NO_CHECK6_RX, /* Allow zero UDP6 checksums on RX? */
+       UDP_FLAGS_GRO_ENABLED,  /* Request GRO aggregation */
 };
 
 struct udp_sock {
                                           * different encapsulation layer set
                                           * this
                                           */
-                        gro_enabled:1, /* Request GRO aggregation */
                         accept_udp_l4:1,
                         accept_udp_fraglist:1;
 /* indicator bits used by pcflag: */
 
                                                      (struct sockaddr *)sin);
        }
 
-       if (udp_sk(sk)->gro_enabled)
+       if (udp_test_bit(GRO_ENABLED, sk))
                udp_cmsg_recv(msg, sk, skb);
 
        if (inet_cmsg_flags(inet))
                /* when enabling GRO, accept the related GSO packet type */
                if (valbool)
                        udp_tunnel_encap_enable(sk->sk_socket);
-               up->gro_enabled = valbool;
+               udp_assign_bit(GRO_ENABLED, sk, valbool);
                up->accept_udp_l4 = valbool;
                release_sock(sk);
                break;
                break;
 
        case UDP_GRO:
-               val = up->gro_enabled;
+               val = udp_test_bit(GRO_ENABLED, sk);
                break;
 
        /* The following two cannot be changed on UDP sockets, the return is
 
        NAPI_GRO_CB(skb)->is_flist = 0;
        if (!sk || !udp_sk(sk)->gro_receive) {
                if (skb->dev->features & NETIF_F_GRO_FRAGLIST)
-                       NAPI_GRO_CB(skb)->is_flist = sk ? !udp_sk(sk)->gro_enabled : 1;
+                       NAPI_GRO_CB(skb)->is_flist = sk ? !udp_test_bit(GRO_ENABLED, sk) : 1;
 
                if ((!sk && (skb->dev->features & NETIF_F_GRO_UDP_FWD)) ||
-                   (sk && udp_sk(sk)->gro_enabled) || NAPI_GRO_CB(skb)->is_flist)
+                   (sk && udp_test_bit(GRO_ENABLED, sk)) || NAPI_GRO_CB(skb)->is_flist)
                        return call_gro_receive(udp_gro_receive_segment, head, skb);
 
                /* no GRO, be sure flush the current packet */
 
                                                      (struct sockaddr *)sin6);
        }
 
-       if (udp_sk(sk)->gro_enabled)
+       if (udp_test_bit(GRO_ENABLED, sk))
                udp_cmsg_recv(msg, sk, skb);
 
        if (np->rxopt.all)