]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/commitdiff
netfilter: nf_tables: take module reference when starting a batch
authorFlorian Westphal <fw@strlen.de>
Wed, 11 Jul 2018 11:45:12 +0000 (13:45 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Wed, 18 Jul 2018 09:26:46 +0000 (11:26 +0200)
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/linux/netfilter/nfnetlink.h
net/netfilter/nf_tables_api.c
net/netfilter/nfnetlink.c

index 3ecc3050be0ec29fc9716b3ad616a43131d36be3..4a520d3304a2fad7a47ddd366672c2fbb054ec1e 100644 (file)
@@ -29,6 +29,7 @@ struct nfnetlink_subsystem {
        __u8 subsys_id;                 /* nfnetlink subsystem ID */
        __u8 cb_count;                  /* number of callbacks */
        const struct nfnl_callback *cb; /* callback for individual types */
+       struct module *owner;
        int (*commit)(struct net *net, struct sk_buff *skb);
        int (*abort)(struct net *net, struct sk_buff *skb);
        void (*cleanup)(struct net *net);
index 594b395442d6b9755b77ff0daaf8a2d73576dcfb..c16c481fc52af0c5c1333447f2d4940f80ac199c 100644 (file)
@@ -6603,6 +6603,7 @@ static const struct nfnetlink_subsystem nf_tables_subsys = {
        .abort          = nf_tables_abort,
        .cleanup        = nf_tables_cleanup,
        .valid_genid    = nf_tables_valid_genid,
+       .owner          = THIS_MODULE,
 };
 
 int nft_chain_validate_dependency(const struct nft_chain *chain,
index 94f9bcaa0799f87b7e7799e9e4aa51f2b6e533b8..dd1d7bc23b0330ebd67457df8fa5f9f52bfde279 100644 (file)
@@ -337,7 +337,14 @@ replay:
                return kfree_skb(skb);
        }
 
+       if (!try_module_get(ss->owner)) {
+               nfnl_unlock(subsys_id);
+               netlink_ack(oskb, nlh, -EOPNOTSUPP, NULL);
+               return kfree_skb(skb);
+       }
+
        if (!ss->valid_genid(net, genid)) {
+               module_put(ss->owner);
                nfnl_unlock(subsys_id);
                netlink_ack(oskb, nlh, -ERESTART, NULL);
                return kfree_skb(skb);
@@ -472,6 +479,7 @@ done:
                nfnl_err_reset(&err_list);
                nfnl_unlock(subsys_id);
                kfree_skb(skb);
+               module_put(ss->owner);
                goto replay;
        } else if (status == NFNL_BATCH_DONE) {
                err = ss->commit(net, oskb);
@@ -491,6 +499,7 @@ done:
        nfnl_err_deliver(&err_list, oskb);
        nfnl_unlock(subsys_id);
        kfree_skb(skb);
+       module_put(ss->owner);
 }
 
 static const struct nla_policy nfnl_batch_policy[NFNL_BATCH_MAX + 1] = {