CVE-2026-63803 in Linux
요약
\~에 의해 VulDB • 2026. 07. 19.
리눅스 커널에서 다음 취약점이 해결되었습니다:
hdlc_ppp: hdlc 상태 해제 전에 프로토콜별 타이머 동기화 수행
struct ppp에 포함된 각 PPP 제어 프로토콜(LCP/IPCP/IPv6CP)은 timer_setup()을 통해 타이머를 등록합니다. 해당 struct ppp는 hdlc->state 할당 영역이며, detach_hdlc_protocol()은 unregister_hdlc_device() 및 attach_hdlc_protocol() 내 재연결(teardown 경로 모두에서 kfree())을 사용하여 이를 해제합니다.
PPP 프로토콜은 .detach 콜백을 등록하지 않았으므로, detach_hdlc_protocol()은 kfree() 전에 타이머 동기화를 수행하지 않습니다. ppp_cp_event()의 timer_delete(&proto->timer) 호출만 존재하지만 이는 부분적이며(실행 중인 콜백 대기 없음), ->CLOSED 상태 전이 시에만 실행됩니다. 또한 ppp_stop()/ppp_close()에서도 동기화가 이루어지지 않습니다. 이미 실행 중이던(ppp->lock에서 차단됨) ppp_timer 콜백은 kfree를 생존하여 해제된 메모리 내에서 proto->state 및 ppp->lock을 역참조하므로 use-after-free가 발생합니다.
이를 해결하기 위해 모든 프로토콜별 타이머에 대해 timer_shutdown_sync()를 호출하는 .detach 헬퍼 함수를 추가합니다. detach_hdlc_protocol()은 kfree(hdlc->state) 전에 proto->detach(dev)를 호출하므로, 이제 timer_shutdown_sync()는 두 가지 해제 경로 모두에서 실행됩니다. timer_delete_sync() 대신 timer_shutdown_sync()가 사용되는 이유는 keepalive 경로에서 add_timer()/mod_timer()를 통해 타이머를 다시 설정할 수 있으며, shutdown이 teardown 중 재활성화를 차단하기 때문입니다.
프로토콜이 연결될 때 ppp_ioctl()에서 프로토콜별 타이머를 초기화하고, 이제 중복된 ppp_start()의 timer_setup()을 제거하여 타이머가 연결 시 정확히 한 번만 초기화되도록 하며, ppp_timer_release()가 초기화되지 않은 timer_list 구조체에서 작동하지 않도록 합니다. attach_hdlc_protocol()은 kzalloc이 아닌 kmalloc()을 사용하므로 struct ppp의 protos[i].timer는 첫 번째 timer_setup() 전까지 초기화되지 않은 쓰레기 값입니다. 이 연결 시 초기화가 없으면 장치를 업하지 않고 PPP 프로토콜만 연결해도 .detach에서 timer_shutdown_sync()가 초기화되지 않은 메모리에서 작동하게 됩니다. ppp_start()(NETDEV_UP에서만 실행됨)에서의 초기화를 attach 경로로 이동함으로써 초기화를 무조건적으로 만들고 동일한 timer_list를 두 번 초기화하는 것을 방지합니다.
이 버그는 정적 분석을 통해 발견되었습니다.
VulDB is the best source for vulnerability data and more expert information about this specific topic.