netfilter pull request nf-26-03-10

-----BEGIN PGP SIGNATURE-----
 
 iQJdBAABCABHFiEEgKkgxbID4Gn1hq6fcJGo2a1f9gAFAmmwGJYbFIAAAAAABAAO
 bWFudTIsMi41KzEuMTEsMiwyDRxmd0BzdHJsZW4uZGUACgkQcJGo2a1f9gBpExAA
 vbIa7R1p88Lt4nBEu3eB4gHhN9f8n25jF/bpzU3MTjB9iyEnVAdflD2dBBScO6fl
 z0fMKSyBWcAJ0wxRbo114D7+xhuWMSOjzZhEX0cHqo5OCVmL/T314ufmxSKkCJM0
 r1fpy7eI95FL7EBv5gg7x95ksKyFYiFJxCOEnqzMcuMZEuM4IWhQ+4cSqeU1/8R0
 G3l0W/L3V5LibMtQ0YGcDNfuGFK2DJ+YgxmEOirVapWPTqojc6TiDkV2j2SAJHbL
 kkpW+M3J0xIL+pivHPQ1z4NhVQS1bKhNjqqCVOE80a0ifhsW0qXfjZEGWbfuKaTs
 LNc/lqrhjt681cVo/6ljYGdqIOlzXtUxfcU+nJLy26GMKHrP0C6iPpY87h11IvPZ
 q1UNvBbK0r7fPFDc3lY0+AwD6WHpLtB+JjuITXWkZu9/zdRUcixQmpzNnW82TNXA
 SKaX5KVopfvizozIlzuvPO/sahMumMsg6wIMmOZTKPhr7XMLmcHdOFLGSDB4tlhM
 AQ87TCcrK2VUBNbLZpgsQMVqcYKwbvTsXZWqHJCYKHRh4aOn7rO5dC5vZKNibMzW
 itthoLHOWJZLzqBR54u90Ri086SQLCG949neDUrbsA0i/svZkpl9HTm0aq9us430
 csDY/oSlXAULJG0YlrCraBnvPJSLKg0dqNq6HDzGwP8=
 =jtC+
 -----END PGP SIGNATURE-----

Merge tag 'nf-26-03-10' of https://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf

Florian Westphal says:

====================
netfilter: updates for net

Due to large volume of backlogged patches its unlikely I will make the
2nd planned PR this week, so several legit fixes will be pushed back
to next week.  Sorry for the inconvenience but I am out of ideas and
alternatives.

1) syzbot managed to add/remove devices to a flowtable, due to a bug in
   the flowtable netdevice notifier this gets us a double-add and
   eventually UaF when device is removed again (we only expect one
   entry, duplicate remains past net_device end-of-life).
   From Phil Sutter, bug added in 6.16.

2) Yiming Qian reports another nf_tables transaction handling bug:
   in some cases error unwind misses to undo certain set elements,
   resulting in refcount underflow and use-after-free, bug added in 6.4.

3) Jenny Guanni Qu found out-of-bounds read in pipapo set type.
   While the value is never used, it still rightfully triggers KASAN
   splats.  Bug exists since this set type was added in 5.6.

4) a few x_tables modules contain copypastry tcp option parsing code which
    can read 1 byte past the option area.  This bug is ancient, fix from
    David Dull.

5) nfnetlink_queue leaks kernel memory if userspace provides bad
   NFQA_VLAN/NFQA_L2HDR attributes.  From Hyunwoo Kim, bug stems from
   from 4.7 days.

6) nfnetlink_cthelper has incorrect loop restart logic which may result
   in reading one pointer past end of array. From 3.6 days, fix also from
   Hyunwoo Kim.

7) xt_IDLETIMER v0 extension must reject working with timers added
   by revision v1, else we get list corruption. Bug added in v5.7.
   From Yifan Wu, Juefei Pu and Yuan Tan via Xin Lu.

* tag 'nf-26-03-10' of https://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf:
  netfilter: xt_IDLETIMER: reject rev0 reuse of ALARM timer labels
  netfilter: nfnetlink_cthelper: fix OOB read in nfnl_cthelper_dump_table()
  netfilter: nfnetlink_queue: fix entry leak in bridge verdict error path
  netfilter: x_tables: guard option walkers against 1-byte tail reads
  netfilter: nft_set_pipapo: fix stack out-of-bounds read in pipapo_drop()
  netfilter: nf_tables: always walk all pending catchall elements
  netfilter: nf_tables: Fix for duplicate device in netdev hooks
====================

Link: https://patch.msgid.link/20260310132050.630-1-fw@strlen.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2026-03-11 19:12:59 -07:00
commit ead0540548
8 changed files with 23 additions and 14 deletions

View File

@ -829,7 +829,6 @@ static void nft_map_catchall_deactivate(const struct nft_ctx *ctx,
nft_set_elem_change_active(ctx->net, set, ext);
nft_setelem_data_deactivate(ctx->net, set, catchall->elem);
break;
}
}
@ -5873,7 +5872,6 @@ static void nft_map_catchall_activate(const struct nft_ctx *ctx,
nft_clear(ctx->net, ext);
nft_setelem_data_activate(ctx->net, set, catchall->elem);
break;
}
}
@ -9688,7 +9686,7 @@ static int nft_flowtable_event(unsigned long event, struct net_device *dev,
break;
case NETDEV_REGISTER:
/* NOP if not matching or already registered */
if (!match || (changename && ops))
if (!match || ops)
continue;
ops = kzalloc_obj(struct nf_hook_ops,

View File

@ -601,10 +601,10 @@ nfnl_cthelper_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
goto out;
}
}
}
if (cb->args[1]) {
cb->args[1] = 0;
goto restart;
if (cb->args[1]) {
cb->args[1] = 0;
goto restart;
}
}
out:
rcu_read_unlock();

View File

@ -1546,8 +1546,10 @@ static int nfqnl_recv_verdict(struct sk_buff *skb, const struct nfnl_info *info,
if (entry->state.pf == PF_BRIDGE) {
err = nfqa_parse_bridge(entry, nfqa);
if (err < 0)
if (err < 0) {
nfqnl_reinject(entry, NF_DROP);
return err;
}
}
if (nfqa[NFQA_PAYLOAD]) {

View File

@ -344,7 +344,7 @@ static int nft_netdev_event(unsigned long event, struct net_device *dev,
break;
case NETDEV_REGISTER:
/* NOP if not matching or already registered */
if (!match || (changename && ops))
if (!match || ops)
continue;
ops = kmemdup(&basechain->ops,

View File

@ -1640,6 +1640,7 @@ static void pipapo_drop(struct nft_pipapo_match *m,
int i;
nft_pipapo_for_each_field(f, i, m) {
bool last = i == m->field_count - 1;
int g;
for (g = 0; g < f->groups; g++) {
@ -1659,7 +1660,7 @@ static void pipapo_drop(struct nft_pipapo_match *m,
}
pipapo_unmap(f->mt, f->rules, rulemap[i].to, rulemap[i].n,
rulemap[i + 1].n, i == m->field_count - 1);
last ? 0 : rulemap[i + 1].n, last);
if (pipapo_resize(f, f->rules, f->rules - rulemap[i].n)) {
/* We can ignore this, a failure to shrink tables down
* doesn't make tables invalid.

View File

@ -318,6 +318,12 @@ static int idletimer_tg_checkentry(const struct xt_tgchk_param *par)
info->timer = __idletimer_tg_find_by_label(info->label);
if (info->timer) {
if (info->timer->timer_type & XT_IDLETIMER_ALARM) {
pr_debug("Adding/Replacing rule with same label and different timer type is not allowed\n");
mutex_unlock(&list_mutex);
return -EINVAL;
}
info->timer->refcnt++;
mod_timer(&info->timer->timer,
secs_to_jiffies(info->timeout) + jiffies);

View File

@ -62,10 +62,10 @@ dccp_find_option(u_int8_t option,
return true;
}
if (op[i] < 2)
if (op[i] < 2 || i == optlen - 1)
i++;
else
i += op[i+1]?:1;
i += op[i + 1] ? : 1;
}
spin_unlock_bh(&dccp_buflock);

View File

@ -59,8 +59,10 @@ tcp_find_option(u_int8_t option,
for (i = 0; i < optlen; ) {
if (op[i] == option) return !invert;
if (op[i] < 2) i++;
else i += op[i+1]?:1;
if (op[i] < 2 || i == optlen - 1)
i++;
else
i += op[i + 1] ? : 1;
}
return invert;