🇰🇷 한글 설명
Linux 커널 netfilter의 ip6t_rt 모듈에서 주소 수가 0인 규칙이 허용되어, 조작된 IPv6 패킷으로 루프 종료 조건이 우회되며 범위를 벗어난 메모리 읽기가 발생합니다. 이로 인해 커널 경고나 패닉이 유발될 수 있습니다. 수정은 규칙 검증 단계에서 주소 수 0을 거부하고 루프 종료 조건을 for문 헤더로 옮기는 것입니다.
💡 쉬운 설명
방화벽의 IPv6 라우팅 헤더 검사 기능에 결함이 있어, 특정 형태의 패킷을 보내면 리눅스 커널이 잘못된 메모리를 읽게 됩니다. 이 때문에 시스템이 비정상 종료되거나 불안정해질 수 있습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
netfilter: ip6t_rt: fix zero-address non-strict match out-of-bounds read
rt_mt6_check() permits rules to be configured with rtinfo->addrnr == 0
even when address matching (IP6T_RT_FST_MASK) is requested.
In the IP6T_RT_FST_NSTRICT path, rt_mt6() evaluates packet routing
addresses against rtinfo->addrs[i] and terminates backwards at the bottom
of the loop:
if (ipv6_addr_equal(ap, &rtinfo->addrs[i])) {
i++;
}
if (i == rtinfo->addrnr)
break;
When addrnr is 0, if the first packet address matches rtinfo->addrs[0],
i is incremented to 1. Because i is now strictly greater than addrnr (0),
the loop termination condition (i == rtinfo->addrnr) is bypassed and will
never be satisfied.
If a crafted IPv6 packet contains matching routing addresses, i will
advance past IP6T_RT_HOPS (16). The subsequent call to ipv6_addr_equal()
reads beyond struct ip6t_rt, triggering UBSAN/KASAN out-of-bounds warnings
or kernel panics.
Fix this by:
1. Rejecting rules in rt_mt6_check() where IP6T_RT_FST_MASK is set but
rtinfo->addrnr is zero.
2. In rt_mt6(), moving the termination condition (i < rtinfo->addrnr)
into the for-loop header condition and removing the backwards break
at the end of the loop body.
📍 영향받는 시스템
패치되지 않은 Linux 커널 (netfilter ip6t_rt 모듈을 사용하는 IPv6 방화벽 구성 시스템)
⚔️ 공격 벡터
원격지에서 라우팅 주소가 규칙과 일치하도록 조작된 IPv6 패킷을 전송하여 커널의 범위 외 메모리 읽기를 유발
🛡️ 대응 방법
배포판 벤더가 제공하는 최신 커널 보안 업데이트를 적용하고 재부팅하며, 필요 시 ip6t_rt 규칙 사용을 중단
🔧 검증 코드
출력된 커널 버전이 벤더의 수정 버전 이상인지 확인하고, ip6t_rt 모듈이 로드되어 있지 않다면 해당 기능이 사용되지 않아 위험이 낮음을 의미하며, 로드되어 있다면 패치 적용이 필요합니다.
uname -r && (lsmod | grep -E 'ip6t_rt|xt_rt') 2>/dev/null