🇰🇷 한글 설명
Linux 커널의 ICMP 호스트 relookup 버그로, IPSec(xfrm) 활성화 시 ARP 링크 실패가 발생하면 ip_rt_bug가 트리거되는 문제이다. 로컬에서 생성된 ICMP 트래픽의 불필요한 xfrm relookup을 스킵하여 해결된다.
💡 쉬운 설명
Linux 시스템에서 IPSec 보안 기능과 ICMP(ping) 통신이 충돌하여 커널이 경고를 발생시키는 문제입니다. 로컬 호스트에서 생성된 ping 트래픽에 대해 불필요한 보안 검사를 건너뛰어 문제를 해결합니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
net: Fix icmp host relookup triggering ip_rt_bug
arp link failure may trigger ip_rt_bug while xfrm enabled, call trace is:
WARNING: CPU: 0 PID: 0 at net/ipv4/route.c:1241 ip_rt_bug+0x14/0x20
Modules linked in:
CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.12.0-rc6-00077-g2e1b3cc9d7f7
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996),
BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
RIP: 0010:ip_rt_bug+0x14/0x20
Call Trace:
<IRQ>
ip_send_skb+0x14/0x40
__icmp_send+0x42d/0x6a0
ipv4_link_failure+0xe2/0x1d0
arp_error_report+0x3c/0x50
neigh_invalidate+0x8d/0x100
neigh_timer_handler+0x2e1/0x330
call_timer_fn+0x21/0x120
__run_timer_base.part.0+0x1c9/0x270
run_timer_softirq+0x4c/0x80
handle_softirqs+0xac/0x280
irq_exit_rcu+0x62/0x80
sysvec_apic_timer_interrupt+0x77/0x90
The script below reproduces this scenario:
ip xfrm policy add src 0.0.0.0/0 dst 0.0.0.0/0 \
dir out priority 0 ptype main flag localok icmp
ip l a veth1 type veth
ip a a 192.168.141.111/24 dev veth0
ip l s veth0 up
ping 192.168.141.155 -c 1
icmp_route_lookup() create input routes for locally generated packets
while xfrm relookup ICMP traffic.Then it will set input route
(dst->out = ip_rt_bug) to skb for DESTUNREACH.
For ICMP err triggered by locally generated packets, dst->dev of output
route is loopback. Generally, xfrm relookup verification is not required
on loopback interfaces (net.ipv4.conf.lo.disable_xfrm = 1).
Skip icmp relookup for locally generated packets to fix it.
📍 영향받는 시스템
Linux kernel 6.12.0-rc6 이전 버전 (xfrm/IPSec 활성화된 시스템)
⚔️ 공격 벡터
로컬 시스템에서 xfrm 정책 설정 후 ICMP 트래픽 생성으로 커널 경고 및 성능 저하 유발
🛡️ 대응 방법
패치된 Linux 커널 버전(6.12.0-rc6 이후)으로 업그레이드 또는 불필요한 xfrm 정책 제거
🔧 검증 코드
패치된 버전(6.12 이상)이면 'Patched' 출력, 이전 버전이면 'Vulnerable' 출력
uname -r | grep -oE '6\.(1[2-9]|[2-9][0-9])|[7-9]\.[0-9]' && echo 'Patched' || echo 'Vulnerable'