🇰🇷 한글 설명
Linux 커널의 IPv6 seg6 모듈에서 IPIP 역캡슐화 시 IPv4 제어 블록(IPCB)을 제대로 초기화하지 않아 발생하는 취약점입니다. 이로 인해 IPv6 확장 헤더의 데이터가 IPv4 옵션 데이터로 오인되어 메모리 경계를 벗어나는 쓰기(slab-out-of-bounds) 오류가 발생할 수 있습니다.
💡 쉬운 설명
IPv6 패킷을 IPv4로 변환하는 과정에서 이전 데이터가 남아 있어, 공격자가 조작한 데이터가 시스템 메모리의 잘못된 영역에 기록될 수 있는 문제입니다. 이로 인해 시스템이 충돌하거나 보안 문제가 발생할 수 있습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
ipv6: seg6: clear IPv4 control block on IPIP decapsulation
End.DX4 and End.DT4 decapsulate an IPv4 packet through
decap_and_validate() and send it directly to IPv4 routing. The inner
packet therefore bypasses ip_rcv_core(), which normally clears IPCB
before IPv4 interprets skb->cb.
The skb instead retains IP6CB data from the outer packet. IP6CB and
IPCB use the same skb->cb storage, so IP6CB(skb)->lastopt overlaps
IPCB(skb)->opt.optlen and srr, while IP6CB(skb)->nhoff overlaps rr and
ts.
The sender can make the stale optlen byte nonzero with a valid outer
extension-header chain. The reproducers put an eight-byte Destination
Options header immediately after the 40-byte IPv6 header and before the
Segment Routing Header. ipv6_destopt_rcv() records the sender-controlled
Destination Options offset in both lastopt and nhoff, setting them to
40. On the reproduced little-endian x86-64 kernel, IPv4 therefore sees
optlen = 40 and rr = 40.
Both tcp_v4_save_options() and __ip_options_echo() skip option copying
when optlen is zero. Here optlen is 40, so the TCP SYN path allocates
room for 40 bytes of option data and calls __ip_options_echo(). The
stale rr value makes that function read inner packet byte 41 as the
Record Route option length. The reproducers set that sender-controlled
byte to 255, so __ip_options_echo() copies 255 bytes into the 40-byte
option-data area.
Separate End.DX4 and End.DT4 reproducers on the unpatched v7.2-rc5
kernel both produced:
BUG: KASAN: slab-out-of-bounds in __ip_options_echo()
Write of size 255
The relevant End.DX4 call path is:
__ip_options_echo
tcp_v4_route_req
tcp_conn_request
tcp_v4_conn_request
tcp_rcv_state_process
tcp_v4_do_rcv
tcp_v4_rcv
ip_protocol_deliver_rcu
ip_local_deliver_finish
ip_local_deliver
input_action_end_dx4_finish
input_action_end_dx4
The relevant End.DT4 call path is:
__ip_options_echo
tcp_v4_route_req
tcp_conn_request
tcp_v4_conn_request
tcp_rcv_state_process
tcp_v4_do_rcv
tcp_v4_rcv
ip_protocol_deliver_rcu
ip_local_deliver_finish
ip_local_deliver
input_action_end_dt4
tcp_v4_save_options() is inlined into the tcp_v4_route_req() path, so
it does not appear as a separate frame.
When decap_and_validate() handles IPPROTO_IPIP, save the ingress
interface from IP6CB, clear IPCB, and restore the saved value. Doing
this in the common decapsulation path covers End.DX4, End.DT4, and
End.DT46's IPv4 arm.
Use IP6CB(skb)->iif rather than skb->skb_iif. These actions run after
l3mdev processing, which can replace skb_iif with the L3 master;
IP6CB iif still records the receiving interface set at IPv6 ingress.
📍 영향받는 시스템
Linux kernel (v7.2-rc5 및 관련 버전 포함)
⚔️ 공격 벡터
특수하게 조작된 IPv6 확장 헤더를 포함한 IPIP 패킷을 전송하여 메모리 오버플로우 유도
🛡️ 대응 방법
Linux 커널을 최신 보안 패치가 적용된 버전으로 업데이트하여 역캡슐화 시 IPCB를 초기화하도록 수정
🔧 검증 코드
현재 실행 중인 커널 버전을 확인하여 취약점이 해결된 패치 버전인지 확인합니다.