Skip to content

Commit f24d8ab

Browse files
ummakynesgregkh
authored andcommitted
netfilter: nft_set_pipapo: walk over current view on netlink dump
commit 29b359c upstream. The generation mask can be updated while netlink dump is in progress. The pipapo set backend walk iterator cannot rely on it to infer what view of the datastructure is to be used. Add notation to specify if user wants to read/update the set. Based on patch from Florian Westphal. Fixes: 2b84e21 ("netfilter: nft_set_pipapo: .walk does not deal with generations") Signed-off-by: Pablo Neira Ayuso <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 94d6fe6 commit f24d8ab

File tree

3 files changed

+21
-2
lines changed

3 files changed

+21
-2
lines changed

include/net/netfilter/nf_tables.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,9 +297,22 @@ struct nft_set_elem {
297297
void *priv;
298298
};
299299

300+
/**
301+
* enum nft_iter_type - nftables set iterator type
302+
*
303+
* @NFT_ITER_READ: read-only iteration over set elements
304+
* @NFT_ITER_UPDATE: iteration under mutex to update set element state
305+
*/
306+
enum nft_iter_type {
307+
NFT_ITER_UNSPEC,
308+
NFT_ITER_READ,
309+
NFT_ITER_UPDATE,
310+
};
311+
300312
struct nft_set;
301313
struct nft_set_iter {
302314
u8 genmask;
315+
enum nft_iter_type type:8;
303316
unsigned int count;
304317
unsigned int skip;
305318
int err;

net/netfilter/nf_tables_api.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,7 @@ static void nft_map_deactivate(const struct nft_ctx *ctx, struct nft_set *set)
628628
{
629629
struct nft_set_iter iter = {
630630
.genmask = nft_genmask_next(ctx->net),
631+
.type = NFT_ITER_UPDATE,
631632
.fn = nft_mapelem_deactivate,
632633
};
633634

@@ -5392,6 +5393,7 @@ int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set,
53925393
}
53935394

53945395
iter.genmask = nft_genmask_next(ctx->net);
5396+
iter.type = NFT_ITER_UPDATE;
53955397
iter.skip = 0;
53965398
iter.count = 0;
53975399
iter.err = 0;
@@ -5467,6 +5469,7 @@ static void nft_map_activate(const struct nft_ctx *ctx, struct nft_set *set)
54675469
{
54685470
struct nft_set_iter iter = {
54695471
.genmask = nft_genmask_next(ctx->net),
5472+
.type = NFT_ITER_UPDATE,
54705473
.fn = nft_mapelem_activate,
54715474
};
54725475

@@ -5845,6 +5848,7 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
58455848
args.skb = skb;
58465849
args.reset = reset;
58475850
args.iter.genmask = nft_genmask_cur(net);
5851+
args.iter.type = NFT_ITER_READ;
58485852
args.iter.skip = cb->args[0];
58495853
args.iter.count = 0;
58505854
args.iter.err = 0;
@@ -7246,6 +7250,7 @@ static int nft_set_flush(struct nft_ctx *ctx, struct nft_set *set, u8 genmask)
72467250
{
72477251
struct nft_set_iter iter = {
72487252
.genmask = genmask,
7253+
.type = NFT_ITER_UPDATE,
72497254
.fn = nft_setelem_flush,
72507255
};
72517256

net/netfilter/nft_set_pipapo.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2037,13 +2037,14 @@ static void nft_pipapo_walk(const struct nft_ctx *ctx, struct nft_set *set,
20372037
struct nft_set_iter *iter)
20382038
{
20392039
struct nft_pipapo *priv = nft_set_priv(set);
2040-
struct net *net = read_pnet(&set->net);
20412040
const struct nft_pipapo_match *m;
20422041
const struct nft_pipapo_field *f;
20432042
int i, r;
20442043

2044+
WARN_ON_ONCE(iter->type == NFT_ITER_UNSPEC);
2045+
20452046
rcu_read_lock();
2046-
if (iter->genmask == nft_genmask_cur(net))
2047+
if (iter->type == NFT_ITER_READ)
20472048
m = rcu_dereference(priv->match);
20482049
else
20492050
m = priv->clone;

0 commit comments

Comments
 (0)