mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-04 04:04:19 +00:00
netfilter: nf_tables: avoid false-positive lockdep splats with sets
Same as previous patch. All set handling functions here can be called with transaction mutex held (but not the rcu read lock). The transaction mutex prevents concurrent add/delete, so this is fine. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
9adbb4198b
commit
8f5f3786db
@ -3986,7 +3986,8 @@ int nft_set_catchall_validate(const struct nft_ctx *ctx, struct nft_set *set)
|
||||
struct nft_set_ext *ext;
|
||||
int ret = 0;
|
||||
|
||||
list_for_each_entry_rcu(catchall, &set->catchall_list, list) {
|
||||
list_for_each_entry_rcu(catchall, &set->catchall_list, list,
|
||||
lockdep_commit_lock_is_held(ctx->net)) {
|
||||
ext = nft_set_elem_ext(set, catchall->elem);
|
||||
if (!nft_set_elem_active(ext, dummy_iter.genmask))
|
||||
continue;
|
||||
@ -4459,7 +4460,8 @@ static const struct nla_policy nft_set_desc_policy[NFTA_SET_DESC_MAX + 1] = {
|
||||
[NFTA_SET_DESC_CONCAT] = NLA_POLICY_NESTED_ARRAY(nft_concat_policy),
|
||||
};
|
||||
|
||||
static struct nft_set *nft_set_lookup(const struct nft_table *table,
|
||||
static struct nft_set *nft_set_lookup(const struct net *net,
|
||||
const struct nft_table *table,
|
||||
const struct nlattr *nla, u8 genmask)
|
||||
{
|
||||
struct nft_set *set;
|
||||
@ -4467,7 +4469,8 @@ static struct nft_set *nft_set_lookup(const struct nft_table *table,
|
||||
if (nla == NULL)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
list_for_each_entry_rcu(set, &table->sets, list) {
|
||||
list_for_each_entry_rcu(set, &table->sets, list,
|
||||
lockdep_commit_lock_is_held(net)) {
|
||||
if (!nla_strcmp(nla, set->name) &&
|
||||
nft_active_genmask(set, genmask))
|
||||
return set;
|
||||
@ -4517,7 +4520,7 @@ struct nft_set *nft_set_lookup_global(const struct net *net,
|
||||
{
|
||||
struct nft_set *set;
|
||||
|
||||
set = nft_set_lookup(table, nla_set_name, genmask);
|
||||
set = nft_set_lookup(net, table, nla_set_name, genmask);
|
||||
if (IS_ERR(set)) {
|
||||
if (!nla_set_id)
|
||||
return set;
|
||||
@ -4893,7 +4896,7 @@ static int nf_tables_getset(struct sk_buff *skb, const struct nfnl_info *info,
|
||||
if (!nla[NFTA_SET_TABLE])
|
||||
return -EINVAL;
|
||||
|
||||
set = nft_set_lookup(table, nla[NFTA_SET_NAME], genmask);
|
||||
set = nft_set_lookup(net, table, nla[NFTA_SET_NAME], genmask);
|
||||
if (IS_ERR(set)) {
|
||||
NL_SET_BAD_ATTR(extack, nla[NFTA_SET_NAME]);
|
||||
return PTR_ERR(set);
|
||||
@ -5229,7 +5232,7 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
|
||||
|
||||
nft_ctx_init(&ctx, net, skb, info->nlh, family, table, NULL, nla);
|
||||
|
||||
set = nft_set_lookup(table, nla[NFTA_SET_NAME], genmask);
|
||||
set = nft_set_lookup(net, table, nla[NFTA_SET_NAME], genmask);
|
||||
if (IS_ERR(set)) {
|
||||
if (PTR_ERR(set) != -ENOENT) {
|
||||
NL_SET_BAD_ATTR(extack, nla[NFTA_SET_NAME]);
|
||||
@ -5431,7 +5434,7 @@ static int nf_tables_delset(struct sk_buff *skb, const struct nfnl_info *info,
|
||||
set = nft_set_lookup_byhandle(table, attr, genmask);
|
||||
} else {
|
||||
attr = nla[NFTA_SET_NAME];
|
||||
set = nft_set_lookup(table, attr, genmask);
|
||||
set = nft_set_lookup(net, table, attr, genmask);
|
||||
}
|
||||
|
||||
if (IS_ERR(set)) {
|
||||
@ -5495,7 +5498,8 @@ static int nft_set_catchall_bind_check(const struct nft_ctx *ctx,
|
||||
struct nft_set_ext *ext;
|
||||
int ret = 0;
|
||||
|
||||
list_for_each_entry_rcu(catchall, &set->catchall_list, list) {
|
||||
list_for_each_entry_rcu(catchall, &set->catchall_list, list,
|
||||
lockdep_commit_lock_is_held(ctx->net)) {
|
||||
ext = nft_set_elem_ext(set, catchall->elem);
|
||||
if (!nft_set_elem_active(ext, genmask))
|
||||
continue;
|
||||
@ -6261,7 +6265,7 @@ static int nft_set_dump_ctx_init(struct nft_set_dump_ctx *dump_ctx,
|
||||
return PTR_ERR(table);
|
||||
}
|
||||
|
||||
set = nft_set_lookup(table, nla[NFTA_SET_ELEM_LIST_SET], genmask);
|
||||
set = nft_set_lookup(net, table, nla[NFTA_SET_ELEM_LIST_SET], genmask);
|
||||
if (IS_ERR(set)) {
|
||||
NL_SET_BAD_ATTR(extack, nla[NFTA_SET_ELEM_LIST_SET]);
|
||||
return PTR_ERR(set);
|
||||
@ -7493,7 +7497,8 @@ static int nft_set_catchall_flush(const struct nft_ctx *ctx,
|
||||
struct nft_set_ext *ext;
|
||||
int ret = 0;
|
||||
|
||||
list_for_each_entry_rcu(catchall, &set->catchall_list, list) {
|
||||
list_for_each_entry_rcu(catchall, &set->catchall_list, list,
|
||||
lockdep_commit_lock_is_held(ctx->net)) {
|
||||
ext = nft_set_elem_ext(set, catchall->elem);
|
||||
if (!nft_set_elem_active(ext, genmask))
|
||||
continue;
|
||||
@ -7543,7 +7548,7 @@ static int nf_tables_delsetelem(struct sk_buff *skb,
|
||||
return PTR_ERR(table);
|
||||
}
|
||||
|
||||
set = nft_set_lookup(table, nla[NFTA_SET_ELEM_LIST_SET], genmask);
|
||||
set = nft_set_lookup(net, table, nla[NFTA_SET_ELEM_LIST_SET], genmask);
|
||||
if (IS_ERR(set)) {
|
||||
NL_SET_BAD_ATTR(extack, nla[NFTA_SET_ELEM_LIST_SET]);
|
||||
return PTR_ERR(set);
|
||||
|
Loading…
Reference in New Issue
Block a user