Skip to content

Commit 280e3a8

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf
Pablo Neira Ayuso says: ==================== Netfilter fixes for net The following patchset contains Netfilter fixes for net: 1) Insufficient validation of element datatype and length in nft_setelem_parse_data(). At least commit 7d74026 updates maximum element data area up to 64 bytes when only 16 bytes where supported at the time. Support for larger element size came later in fdb9c40 though. Picking this older commit as Fixes: tag to be safe than sorry. 2) Memleak in pipapo destroy path, reproducible when transaction in aborted. This is already triggering in the existing netfilter test infrastructure since more recent new tests are covering this path. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 3d5a2a3 + 9827a0e commit 280e3a8

File tree

2 files changed

+41
-16
lines changed

2 files changed

+41
-16
lines changed

net/netfilter/nf_tables_api.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5213,13 +5213,20 @@ static int nft_setelem_parse_data(struct nft_ctx *ctx, struct nft_set *set,
52135213
struct nft_data *data,
52145214
struct nlattr *attr)
52155215
{
5216+
u32 dtype;
52165217
int err;
52175218

52185219
err = nft_data_init(ctx, data, NFT_DATA_VALUE_MAXLEN, desc, attr);
52195220
if (err < 0)
52205221
return err;
52215222

5222-
if (desc->type != NFT_DATA_VERDICT && desc->len != set->dlen) {
5223+
if (set->dtype == NFT_DATA_VERDICT)
5224+
dtype = NFT_DATA_VERDICT;
5225+
else
5226+
dtype = NFT_DATA_VALUE;
5227+
5228+
if (dtype != desc->type ||
5229+
set->dlen != desc->len) {
52235230
nft_data_release(data, desc->type);
52245231
return -EINVAL;
52255232
}

net/netfilter/nft_set_pipapo.c

Lines changed: 33 additions & 15 deletions
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)