inet: ping: use hlist_nulls rcu iterator during lookup
authorFlorian Westphal <fw@strlen.de>
Tue, 29 Nov 2022 14:06:44 +0000 (15:06 +0100)
committerPaolo Abeni <pabeni@redhat.com>
Thu, 1 Dec 2022 11:42:46 +0000 (12:42 +0100)
ping_lookup() does not acquire the table spinlock, so iteration should
use hlist_nulls_for_each_entry_rcu().

Spotted during code review.

Fixes: dbca1596bbb0 ("ping: convert to RCU lookups, get rid of rwlock")
Cc: Eric Dumazet <edumazet@google.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
Link: https://lore.kernel.org/r/20221129140644.28525-1-fw@strlen.de
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
.clang-format
include/net/ping.h
net/ipv4/ping.c

index 1247d54..8d01225 100644 (file)
@@ -535,6 +535,7 @@ ForEachMacros:
   - 'perf_hpp_list__for_each_sort_list_safe'
   - 'perf_pmu__for_each_hybrid_pmu'
   - 'ping_portaddr_for_each_entry'
+  - 'ping_portaddr_for_each_entry_rcu'
   - 'plist_for_each'
   - 'plist_for_each_continue'
   - 'plist_for_each_entry'
index e4ff391..9233ad3 100644 (file)
@@ -16,9 +16,6 @@
 #define PING_HTABLE_SIZE       64
 #define PING_HTABLE_MASK       (PING_HTABLE_SIZE-1)
 
-#define ping_portaddr_for_each_entry(__sk, node, list) \
-       hlist_nulls_for_each_entry(__sk, node, list, sk_nulls_node)
-
 /*
  * gid_t is either uint or ushort.  We want to pass it to
  * proc_dointvec_minmax(), so it must not be larger than MAX_INT
index bde333b..04b4ec0 100644 (file)
 #include <net/transp_v6.h>
 #endif
 
+#define ping_portaddr_for_each_entry(__sk, node, list) \
+       hlist_nulls_for_each_entry(__sk, node, list, sk_nulls_node)
+#define ping_portaddr_for_each_entry_rcu(__sk, node, list) \
+       hlist_nulls_for_each_entry_rcu(__sk, node, list, sk_nulls_node)
+
 struct ping_table {
        struct hlist_nulls_head hash[PING_HTABLE_SIZE];
        spinlock_t              lock;
@@ -192,7 +197,7 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident)
                return NULL;
        }
 
-       ping_portaddr_for_each_entry(sk, hnode, hslot) {
+       ping_portaddr_for_each_entry_rcu(sk, hnode, hslot) {
                isk = inet_sk(sk);
 
                pr_debug("iterate\n");