Skip to content

Commit eb1fb14

Browse files
Florian Westphalummakynes
authored andcommitted
netfilter: nft_compat: use call_rcu for nfnl_compat_get
Just use .call_rcu instead. We can drop the rcu read lock after obtaining a reference and re-acquire on return. Signed-off-by: Florian Westphal <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent 88491c1 commit eb1fb14

File tree

1 file changed

+18
-11
lines changed

1 file changed

+18
-11
lines changed

net/netfilter/nft_compat.c

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -611,10 +611,10 @@ nfnl_compat_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type,
611611
return -1;
612612
}
613613

614-
static int nfnl_compat_get(struct net *net, struct sock *nfnl,
615-
struct sk_buff *skb, const struct nlmsghdr *nlh,
616-
const struct nlattr * const tb[],
617-
struct netlink_ext_ack *extack)
614+
static int nfnl_compat_get_rcu(struct net *net, struct sock *nfnl,
615+
struct sk_buff *skb, const struct nlmsghdr *nlh,
616+
const struct nlattr * const tb[],
617+
struct netlink_ext_ack *extack)
618618
{
619619
int ret = 0, target;
620620
struct nfgenmsg *nfmsg;
@@ -653,16 +653,21 @@ static int nfnl_compat_get(struct net *net, struct sock *nfnl,
653653
return -EINVAL;
654654
}
655655

656+
if (!try_module_get(THIS_MODULE))
657+
return -EINVAL;
658+
659+
rcu_read_unlock();
656660
try_then_request_module(xt_find_revision(nfmsg->nfgen_family, name,
657661
rev, target, &ret),
658662
fmt, name);
659-
660663
if (ret < 0)
661-
return ret;
664+
goto out_put;
662665

663666
skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
664-
if (skb2 == NULL)
665-
return -ENOMEM;
667+
if (skb2 == NULL) {
668+
ret = -ENOMEM;
669+
goto out_put;
670+
}
666671

667672
/* include the best revision for this extension in the message */
668673
if (nfnl_compat_fill_info(skb2, NETLINK_CB(skb).portid,
@@ -672,14 +677,16 @@ static int nfnl_compat_get(struct net *net, struct sock *nfnl,
672677
nfmsg->nfgen_family,
673678
name, ret, target) <= 0) {
674679
kfree_skb(skb2);
675-
return -ENOSPC;
680+
goto out_put;
676681
}
677682

678683
ret = netlink_unicast(nfnl, skb2, NETLINK_CB(skb).portid,
679684
MSG_DONTWAIT);
680685
if (ret > 0)
681686
ret = 0;
682-
687+
out_put:
688+
rcu_read_lock();
689+
module_put(THIS_MODULE);
683690
return ret == -EAGAIN ? -ENOBUFS : ret;
684691
}
685692

@@ -691,7 +698,7 @@ static const struct nla_policy nfnl_compat_policy_get[NFTA_COMPAT_MAX+1] = {
691698
};
692699

693700
static const struct nfnl_callback nfnl_nft_compat_cb[NFNL_MSG_COMPAT_MAX] = {
694-
[NFNL_MSG_COMPAT_GET] = { .call = nfnl_compat_get,
701+
[NFNL_MSG_COMPAT_GET] = { .call_rcu = nfnl_compat_get_rcu,
695702
.attr_count = NFTA_COMPAT_MAX,
696703
.policy = nfnl_compat_policy_get },
697704
};

0 commit comments

Comments
 (0)