ipv4: Fix data-races around sysctl_fib_notify_on_flag_change.
authorKuniyuki Iwashima <kuniyu@amazon.com>
Fri, 22 Jul 2022 18:22:05 +0000 (11:22 -0700)
committerDavid S. Miller <davem@davemloft.net>
Mon, 25 Jul 2022 11:42:10 +0000 (12:42 +0100)
While reading sysctl_fib_notify_on_flag_change, it can be changed
concurrently.  Thus, we need to add READ_ONCE() to its readers.

Fixes: 680aea08e78c ("net: ipv4: Emit notification when fib hardware flags are changed")
Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv4/fib_trie.c

index 46e8a51..452ff17 100644 (file)
@@ -1042,6 +1042,7 @@ fib_find_matching_alias(struct net *net, const struct fib_rt_info *fri)
 
 void fib_alias_hw_flags_set(struct net *net, const struct fib_rt_info *fri)
 {
+       u8 fib_notify_on_flag_change;
        struct fib_alias *fa_match;
        struct sk_buff *skb;
        int err;
@@ -1063,14 +1064,16 @@ void fib_alias_hw_flags_set(struct net *net, const struct fib_rt_info *fri)
        WRITE_ONCE(fa_match->offload, fri->offload);
        WRITE_ONCE(fa_match->trap, fri->trap);
 
+       fib_notify_on_flag_change = READ_ONCE(net->ipv4.sysctl_fib_notify_on_flag_change);
+
        /* 2 means send notifications only if offload_failed was changed. */
-       if (net->ipv4.sysctl_fib_notify_on_flag_change == 2 &&
+       if (fib_notify_on_flag_change == 2 &&
            READ_ONCE(fa_match->offload_failed) == fri->offload_failed)
                goto out;
 
        WRITE_ONCE(fa_match->offload_failed, fri->offload_failed);
 
-       if (!net->ipv4.sysctl_fib_notify_on_flag_change)
+       if (!fib_notify_on_flag_change)
                goto out;
 
        skb = nlmsg_new(fib_nlmsg_size(fa_match->fa_info), GFP_ATOMIC);