@@ -611,10 +611,10 @@ nfnl_compat_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type,
611
611
return -1 ;
612
612
}
613
613
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 )
618
618
{
619
619
int ret = 0 , target ;
620
620
struct nfgenmsg * nfmsg ;
@@ -653,16 +653,21 @@ static int nfnl_compat_get(struct net *net, struct sock *nfnl,
653
653
return - EINVAL ;
654
654
}
655
655
656
+ if (!try_module_get (THIS_MODULE ))
657
+ return - EINVAL ;
658
+
659
+ rcu_read_unlock ();
656
660
try_then_request_module (xt_find_revision (nfmsg -> nfgen_family , name ,
657
661
rev , target , & ret ),
658
662
fmt , name );
659
-
660
663
if (ret < 0 )
661
- return ret ;
664
+ goto out_put ;
662
665
663
666
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
+ }
666
671
667
672
/* include the best revision for this extension in the message */
668
673
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,
672
677
nfmsg -> nfgen_family ,
673
678
name , ret , target ) <= 0 ) {
674
679
kfree_skb (skb2 );
675
- return - ENOSPC ;
680
+ goto out_put ;
676
681
}
677
682
678
683
ret = netlink_unicast (nfnl , skb2 , NETLINK_CB (skb ).portid ,
679
684
MSG_DONTWAIT );
680
685
if (ret > 0 )
681
686
ret = 0 ;
682
-
687
+ out_put :
688
+ rcu_read_lock ();
689
+ module_put (THIS_MODULE );
683
690
return ret == - EAGAIN ? - ENOBUFS : ret ;
684
691
}
685
692
@@ -691,7 +698,7 @@ static const struct nla_policy nfnl_compat_policy_get[NFTA_COMPAT_MAX+1] = {
691
698
};
692
699
693
700
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 ,
695
702
.attr_count = NFTA_COMPAT_MAX ,
696
703
.policy = nfnl_compat_policy_get },
697
704
};
0 commit comments