aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2014-01-09 13:42:36 -0500
committerPablo Neira Ayuso <pablo@netfilter.org>2014-01-09 14:17:14 -0500
commit93b0806f006b8b3ecb7a6183fcad21e88f39904f (patch)
tree14877bc234ea4ebbb3f36fa1d0f0b91d4f74c9eb /net/netfilter
parent88ce65a71c39901494eb2f1393856bff8ba0158d (diff)
netfilter: nf_tables: replay request after dropping locks to load chain type
To avoid races, we need to replay to request after dropping the nfnl_mutex to auto-load the chain type module. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/netfilter')
-rw-r--r--net/netfilter/nf_tables_api.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index d913fb0ab0aa..7d6a2264ae0a 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -147,16 +147,20 @@ nf_tables_chain_type_lookup(const struct nft_af_info *afi,
147 struct nf_chain_type *type; 147 struct nf_chain_type *type;
148 148
149 type = __nf_tables_chain_type_lookup(afi->family, nla); 149 type = __nf_tables_chain_type_lookup(afi->family, nla);
150 if (type != NULL)
151 return type;
150#ifdef CONFIG_MODULES 152#ifdef CONFIG_MODULES
151 if (type == NULL && autoload) { 153 if (autoload) {
152 nfnl_unlock(NFNL_SUBSYS_NFTABLES); 154 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
153 request_module("nft-chain-%u-%*.s", afi->family, 155 request_module("nft-chain-%u-%*.s", afi->family,
154 nla_len(nla)-1, (const char *)nla_data(nla)); 156 nla_len(nla)-1, (const char *)nla_data(nla));
155 nfnl_lock(NFNL_SUBSYS_NFTABLES); 157 nfnl_lock(NFNL_SUBSYS_NFTABLES);
156 type = __nf_tables_chain_type_lookup(afi->family, nla); 158 type = __nf_tables_chain_type_lookup(afi->family, nla);
159 if (type != NULL)
160 return ERR_PTR(-EAGAIN);
157 } 161 }
158#endif 162#endif
159 return type; 163 return ERR_PTR(-ENOENT);
160} 164}
161 165
162static const struct nla_policy nft_table_policy[NFTA_TABLE_MAX + 1] = { 166static const struct nla_policy nft_table_policy[NFTA_TABLE_MAX + 1] = {
@@ -906,8 +910,8 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
906 type = nf_tables_chain_type_lookup(afi, 910 type = nf_tables_chain_type_lookup(afi,
907 nla[NFTA_CHAIN_TYPE], 911 nla[NFTA_CHAIN_TYPE],
908 create); 912 create);
909 if (type == NULL) 913 if (IS_ERR(type))
910 return -ENOENT; 914 return PTR_ERR(type);
911 } 915 }
912 916
913 err = nla_parse_nested(ha, NFTA_HOOK_MAX, nla[NFTA_CHAIN_HOOK], 917 err = nla_parse_nested(ha, NFTA_HOOK_MAX, nla[NFTA_CHAIN_HOOK],