From: Subash Abhinov Kasiviswanathan <subas...@codeaurora.org>
Date: Tue, 21 Mar 2017 21:20:10 -0600

> @@ -329,7 +329,7 @@ static int ip_rcv_finish(struct net *net, struct sock 
> *sk, struct sk_buff *skb)
>               int protocol = iph->protocol;
>  
>               ipprot = rcu_dereference(inet_protos[protocol]);
> -             if (ipprot && ipprot->early_demux) {
> +             if (ipprot && READ_ONCE(ipprot->early_demux)) {
>                       ipprot->early_demux(skb);

I think you need to use a local variable for the function pointer in conjunction
with READ_ONCE() for this to work properly:

        if (ipprot && (func = READ_ONCE(ipprot->early_demux))) {
                func(skb);
                ...

> diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
> index aacfb4b..30d18cb 100644
> --- a/net/ipv6/ip6_input.c
> +++ b/net/ipv6/ip6_input.c
> @@ -60,7 +60,7 @@ int ip6_rcv_finish(struct net *net, struct sock *sk, struct 
> sk_buff *skb)
>               const struct inet6_protocol *ipprot;
>  
>               ipprot = rcu_dereference(inet6_protos[ipv6_hdr(skb)->nexthdr]);
> -             if (ipprot && ipprot->early_demux)
> +             if (ipprot && READ_ONCE(ipprot->early_demux))
>                       ipprot->early_demux(skb);
>       }
>       if (!skb_valid_dst(skb))

Likewise.

Reply via email to