Skip to content

Commit a1bd2a3

Browse files
ummakynesgregkh
authored andcommitted
netfilter: nf_tables: fix memleak in map from abort path
[ Upstream commit 86a1471 ] The delete set command does not rely on the transaction object for element removal, therefore, a combination of delete element + delete set from the abort path could result in restoring twice the refcount of the mapping. Check for inactive element in the next generation for the delete element command in the abort path, skip restoring state if next generation bit has been already cleared. This is similar to the activate logic using the set walk iterator. [ 6170.286929] ------------[ cut here ]------------ [ 6170.286939] WARNING: CPU: 6 PID: 790302 at net/netfilter/nf_tables_api.c:2086 nf_tables_chain_destroy+0x1f7/0x220 [nf_tables] [ 6170.287071] Modules linked in: [...] [ 6170.287633] CPU: 6 PID: 790302 Comm: kworker/6:2 Not tainted 6.9.0-rc3+ raspberrypi#365 [ 6170.287768] RIP: 0010:nf_tables_chain_destroy+0x1f7/0x220 [nf_tables] [ 6170.287886] Code: df 48 8d 7d 58 e8 69 2e 3b df 48 8b 7d 58 e8 80 1b 37 df 48 8d 7d 68 e8 57 2e 3b df 48 8b 7d 68 e8 6e 1b 37 df 48 89 ef eb c4 <0f> 0b 48 83 c4 08 5b 5d 41 5c 41 5d 41 5e 41 5f c3 cc cc cc cc 0f [ 6170.287895] RSP: 0018:ffff888134b8fd08 EFLAGS: 00010202 [ 6170.287904] RAX: 0000000000000001 RBX: ffff888125bffb28 RCX: dffffc0000000000 [ 6170.287912] RDX: 0000000000000003 RSI: ffffffffa20298ab RDI: ffff88811ebe4750 [ 6170.287919] RBP: ffff88811ebe4700 R08: ffff88838e812650 R09: fffffbfff0623a55 [ 6170.287926] R10: ffffffff8311d2af R11: 0000000000000001 R12: ffff888125bffb10 [ 6170.287933] R13: ffff888125bffb10 R14: dead000000000122 R15: dead000000000100 [ 6170.287940] FS: 0000000000000000(0000) GS:ffff888390b00000(0000) knlGS:0000000000000000 [ 6170.287948] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 6170.287955] CR2: 00007fd31fc00710 CR3: 0000000133f60004 CR4: 00000000001706f0 [ 6170.287962] Call Trace: [ 6170.287967] <TASK> [ 6170.287973] ? __warn+0x9f/0x1a0 [ 6170.287986] ? nf_tables_chain_destroy+0x1f7/0x220 [nf_tables] [ 6170.288092] ? report_bug+0x1b1/0x1e0 [ 6170.287986] ? nf_tables_chain_destroy+0x1f7/0x220 [nf_tables] [ 6170.288092] ? report_bug+0x1b1/0x1e0 [ 6170.288104] ? handle_bug+0x3c/0x70 [ 6170.288112] ? exc_invalid_op+0x17/0x40 [ 6170.288120] ? asm_exc_invalid_op+0x1a/0x20 [ 6170.288132] ? nf_tables_chain_destroy+0x2b/0x220 [nf_tables] [ 6170.288243] ? nf_tables_chain_destroy+0x1f7/0x220 [nf_tables] [ 6170.288366] ? nf_tables_chain_destroy+0x2b/0x220 [nf_tables] [ 6170.288483] nf_tables_trans_destroy_work+0x588/0x590 [nf_tables] Fixes: 5910544 ("netfilter: nf_tables: revisit chain/object refcounting from elements") Signed-off-by: Pablo Neira Ayuso <[email protected]> (cherry picked from commit 86a1471) [Vegard: CVE-2024-27011; fixed conflicts due to missing commits 0e1ea65 ("netfilter: nf_tables: shrink memory consumption of set elements") and 9dad402 ("netfilter: nf_tables: expose opaque set element as struct nft_elem_priv") so we pass the correct types and values to nft_setelem_active_next() + nft_set_elem_ext()] Signed-off-by: Vegard Nossum <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent b907789 commit a1bd2a3

File tree

1 file changed

+14
-2
lines changed

1 file changed

+14
-2
lines changed

net/netfilter/nf_tables_api.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7061,6 +7061,16 @@ void nft_data_hold(const struct nft_data *data, enum nft_data_types type)
70617061
}
70627062
}
70637063

7064+
static int nft_setelem_active_next(const struct net *net,
7065+
const struct nft_set *set,
7066+
struct nft_set_elem *elem)
7067+
{
7068+
const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
7069+
u8 genmask = nft_genmask_next(net);
7070+
7071+
return nft_set_elem_active(ext, genmask);
7072+
}
7073+
70647074
static void nft_setelem_data_activate(const struct net *net,
70657075
const struct nft_set *set,
70667076
struct nft_set_elem *elem)
@@ -10538,8 +10548,10 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)
1053810548
case NFT_MSG_DESTROYSETELEM:
1053910549
te = (struct nft_trans_elem *)trans->data;
1054010550

10541-
nft_setelem_data_activate(net, te->set, &te->elem);
10542-
nft_setelem_activate(net, te->set, &te->elem);
10551+
if (!nft_setelem_active_next(net, te->set, &te->elem)) {
10552+
nft_setelem_data_activate(net, te->set, &te->elem);
10553+
nft_setelem_activate(net, te->set, &te->elem);
10554+
}
1054310555
if (!nft_setelem_is_catchall(te->set, &te->elem))
1054410556
te->set->ndeact--;
1054510557

0 commit comments

Comments
 (0)