]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
netfilter: nfnetlink: place subsys mutexes in distinct lockdep classes
authorFlorian Westphal <fw@strlen.de>
Fri, 2 Oct 2020 11:51:29 +0000 (13:51 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Sun, 4 Oct 2020 19:08:32 +0000 (21:08 +0200)
From time to time there are lockdep reports similar to this one:

 WARNING: possible circular locking dependency detected
 ------------------------------------------------------
 000000004f61aa56 (&table[i].mutex){+.+.}, at: nfnl_lock [nfnetlink]
 but task is already holding lock:
 [..] (&net->nft.commit_mutex){+.+.}, at: nf_tables_valid_genid [nf_tables]
 which lock already depends on the new lock.
 the existing dependency chain (in reverse order) is:
 -> #1 (&net->nft.commit_mutex){+.+.}:
 [..]
        nf_tables_valid_genid+0x18/0x60 [nf_tables]
        nfnetlink_rcv_batch+0x24c/0x620 [nfnetlink]
        nfnetlink_rcv+0x110/0x140 [nfnetlink]
        netlink_unicast+0x12c/0x1e0
 [..]
        sys_sendmsg+0x18/0x40
        linux_sparc_syscall+0x34/0x44
 -> #0 (&table[i].mutex){+.+.}:
 [..]
        nfnl_lock+0x24/0x40 [nfnetlink]
        ip_set_nfnl_get_byindex+0x19c/0x280 [ip_set]
        set_match_v1_checkentry+0x14/0xc0 [xt_set]
        xt_check_match+0x238/0x260 [x_tables]
        __nft_match_init+0x160/0x180 [nft_compat]
 [..]
        sys_sendmsg+0x18/0x40
        linux_sparc_syscall+0x34/0x44
 other info that might help us debug this:
  Possible unsafe locking scenario:
        CPU0                    CPU1
        ----                    ----
   lock(&net->nft.commit_mutex);
                                lock(&table[i].mutex);
                                lock(&net->nft.commit_mutex);
   lock(&table[i].mutex);

Lockdep considers this an ABBA deadlock because the different nfnl subsys
mutexes reside in the same lockdep class, but this is a false positive.

CPU1 table[i] refers to the nftables subsys mutex, whereas CPU1 locks
the ipset subsys mutex.

Yi Che reported a similar lockdep splat, this time between ipset and
ctnetlink subsys mutexes.

Time to place them in distinct classes to avoid these warnings.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
net/netfilter/nfnetlink.c

index 3a2e64e13b227ba9431253e3f8587cc9cd3a7cd6..2daa1f6ae344113b2031c4488595e9b9640dd9fe 100644 (file)
@@ -46,6 +46,23 @@ static struct {
        const struct nfnetlink_subsystem __rcu  *subsys;
 } table[NFNL_SUBSYS_COUNT];
 
+static struct lock_class_key nfnl_lockdep_keys[NFNL_SUBSYS_COUNT];
+
+static const char *const nfnl_lockdep_names[NFNL_SUBSYS_COUNT] = {
+       [NFNL_SUBSYS_NONE] = "nfnl_subsys_none",
+       [NFNL_SUBSYS_CTNETLINK] = "nfnl_subsys_ctnetlink",
+       [NFNL_SUBSYS_CTNETLINK_EXP] = "nfnl_subsys_ctnetlink_exp",
+       [NFNL_SUBSYS_QUEUE] = "nfnl_subsys_queue",
+       [NFNL_SUBSYS_ULOG] = "nfnl_subsys_ulog",
+       [NFNL_SUBSYS_OSF] = "nfnl_subsys_osf",
+       [NFNL_SUBSYS_IPSET] = "nfnl_subsys_ipset",
+       [NFNL_SUBSYS_ACCT] = "nfnl_subsys_acct",
+       [NFNL_SUBSYS_CTNETLINK_TIMEOUT] = "nfnl_subsys_cttimeout",
+       [NFNL_SUBSYS_CTHELPER] = "nfnl_subsys_cthelper",
+       [NFNL_SUBSYS_NFTABLES] = "nfnl_subsys_nftables",
+       [NFNL_SUBSYS_NFT_COMPAT] = "nfnl_subsys_nftcompat",
+};
+
 static const int nfnl_group2type[NFNLGRP_MAX+1] = {
        [NFNLGRP_CONNTRACK_NEW]         = NFNL_SUBSYS_CTNETLINK,
        [NFNLGRP_CONNTRACK_UPDATE]      = NFNL_SUBSYS_CTNETLINK,
@@ -632,7 +649,7 @@ static int __init nfnetlink_init(void)
                BUG_ON(nfnl_group2type[i] == NFNL_SUBSYS_NONE);
 
        for (i=0; i<NFNL_SUBSYS_COUNT; i++)
-               mutex_init(&table[i].mutex);
+               __mutex_init(&table[i].mutex, nfnl_lockdep_names[i], &nfnl_lockdep_keys[i]);
 
        return register_pernet_subsys(&nfnetlink_net_ops);
 }