Skip to content

Commit 5ccecaf

Browse files
ummakynesgregkh
authored andcommitted
netfilter: nft_set_pipapo: release elements in clone from abort path
commit 9827a0e upstream. New elements that reside in the clone are not released in case that the transaction is aborted. [16302.231754] ------------[ cut here ]------------ [16302.231756] WARNING: CPU: 0 PID: 100509 at net/netfilter/nf_tables_api.c:1864 nf_tables_chain_destroy+0x26/0x127 [nf_tables] [...] [16302.231882] CPU: 0 PID: 100509 Comm: nft Tainted: G W 5.19.0-rc3+ torvalds#155 [...] [16302.231887] RIP: 0010:nf_tables_chain_destroy+0x26/0x127 [nf_tables] [16302.231899] Code: f3 fe ff ff 41 55 41 54 55 53 48 8b 6f 10 48 89 fb 48 c7 c7 82 96 d9 a0 8b 55 50 48 8b 75 58 e8 de f5 92 e0 83 7d 50 00 74 09 <0f> 0b 5b 5d 41 5c 41 5d c3 4c 8b 65 00 48 8b 7d 08 49 39 fc 74 05 [...] [16302.231917] Call Trace: [16302.231919] <TASK> [16302.231921] __nf_tables_abort.cold+0x23/0x28 [nf_tables] [16302.231934] nf_tables_abort+0x30/0x50 [nf_tables] [16302.231946] nfnetlink_rcv_batch+0x41a/0x840 [nfnetlink] [16302.231952] ? __nla_validate_parse+0x48/0x190 [16302.231959] nfnetlink_rcv+0x110/0x129 [nfnetlink] [16302.231963] netlink_unicast+0x211/0x340 [16302.231969] netlink_sendmsg+0x21e/0x460 Add nft_set_pipapo_match_destroy() helper function to release the elements in the lookup tables. Stefano Brivio says: "We additionally look for elements pointers in the cloned matching data if priv->dirty is set, because that means that cloned data might point to additional elements we did not commit to the working copy yet (such as the abort path case, but perhaps not limited to it)." Fixes: 3c4287f ("nf_tables: Add set type for arbitrary concatenation of ranges") Reviewed-by: Stefano Brivio <sbrivio@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 75e9009 commit 5ccecaf

File tree

1 file changed

+33
-15
lines changed

1 file changed

+33
-15
lines changed

net/netfilter/nft_set_pipapo.c

+33-15
Original file line numberDiff line numberDiff line change
@@ -2124,6 +2124,32 @@ static int nft_pipapo_init(const struct nft_set *set,
21242124
return err;
21252125
}
21262126

2127+
/**
2128+
* nft_set_pipapo_match_destroy() - Destroy elements from key mapping array
2129+
* @set: nftables API set representation
2130+
* @m: matching data pointing to key mapping array
2131+
*/
2132+
static void nft_set_pipapo_match_destroy(const struct nft_set *set,
2133+
struct nft_pipapo_match *m)
2134+
{
2135+
struct nft_pipapo_field *f;
2136+
int i, r;
2137+
2138+
for (i = 0, f = m->f; i < m->field_count - 1; i++, f++)
2139+
;
2140+
2141+
for (r = 0; r < f->rules; r++) {
2142+
struct nft_pipapo_elem *e;
2143+
2144+
if (r < f->rules - 1 && f->mt[r + 1].e == f->mt[r].e)
2145+
continue;
2146+
2147+
e = f->mt[r].e;
2148+
2149+
nft_set_elem_destroy(set, e, true);
2150+
}
2151+
}
2152+
21272153
/**
21282154
* nft_pipapo_destroy() - Free private data for set and all committed elements
21292155
* @set: nftables API set representation
@@ -2132,26 +2158,13 @@ static void nft_pipapo_destroy(const struct nft_set *set)
21322158
{
21332159
struct nft_pipapo *priv = nft_set_priv(set);
21342160
struct nft_pipapo_match *m;
2135-
struct nft_pipapo_field *f;
2136-
int i, r, cpu;
2161+
int cpu;
21372162

21382163
m = rcu_dereference_protected(priv->match, true);
21392164
if (m) {
21402165
rcu_barrier();
21412166

2142-
for (i = 0, f = m->f; i < m->field_count - 1; i++, f++)
2143-
;
2144-
2145-
for (r = 0; r < f->rules; r++) {
2146-
struct nft_pipapo_elem *e;
2147-
2148-
if (r < f->rules - 1 && f->mt[r + 1].e == f->mt[r].e)
2149-
continue;
2150-
2151-
e = f->mt[r].e;
2152-
2153-
nft_set_elem_destroy(set, e, true);
2154-
}
2167+
nft_set_pipapo_match_destroy(set, m);
21552168

21562169
#ifdef NFT_PIPAPO_ALIGN
21572170
free_percpu(m->scratch_aligned);
@@ -2165,6 +2178,11 @@ static void nft_pipapo_destroy(const struct nft_set *set)
21652178
}
21662179

21672180
if (priv->clone) {
2181+
m = priv->clone;
2182+
2183+
if (priv->dirty)
2184+
nft_set_pipapo_match_destroy(set, m);
2185+
21682186
#ifdef NFT_PIPAPO_ALIGN
21692187
free_percpu(priv->clone->scratch_aligned);
21702188
#endif

0 commit comments

Comments
 (0)