net/tcp_sigpool: Use kref_get_unless_zero()
authorDmitry Safonov <dima@arista.com>
Fri, 22 Dec 2023 01:13:59 +0000 (01:13 +0000)
committerDavid S. Miller <davem@davemloft.net>
Mon, 1 Jan 2024 14:42:05 +0000 (14:42 +0000)
The freeing and re-allocation of algorithm are protected by cpool_mutex,
so it doesn't fix an actual use-after-free, but avoids a deserved
refcount_warn_saturate() warning.

A trivial fix for the racy behavior.

Fixes: 8c73b26315aa ("net/tcp: Prepare tcp_md5sig_pool for TCP-AO")
Suggested-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Dmitry Safonov <dima@arista.com>
Tested-by: Bagas Sanjaya <bagasdotme@gmail.com>
Reported-by: syzbot <syzkaller@googlegroups.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv4/tcp_sigpool.c

index 55b310a722c7d5c91480640271e180f2a7e95e58..8512cb09ebc097d567dd907ad17c4ae38ddb5768 100644 (file)
@@ -162,9 +162,8 @@ int tcp_sigpool_alloc_ahash(const char *alg, size_t scratch_size)
                if (strcmp(cpool[i].alg, alg))
                        continue;
 
-               if (kref_read(&cpool[i].kref) > 0)
-                       kref_get(&cpool[i].kref);
-               else
+               /* pairs with tcp_sigpool_release() */
+               if (!kref_get_unless_zero(&cpool[i].kref))
                        kref_init(&cpool[i].kref);
                ret = i;
                goto out;