🇰🇷 한글 설명
ARM PL011 UART 드라이버의 수신 오류 인터럽트(프레이밍, 패리티, 브레이크, 오버런)가 UARTICR 레지스터로 명시적으로 클리어되지 않아, ISR 반환 후에도 인터럽트가 계속 대기 상태로 남습니다. 이로 인해 uart_irq_err_enable()을 사용하는 환경에서 인터럽트 폭주와 영구적인 응답 불능이 발생할 수 있습니다.
💡 쉬운 설명
시리얼 통신 장치가 오류 신호를 받았을 때 그 알림을 제대로 정리하지 못하는 결함입니다. 외부에서 잘못된 신호를 보내면 장치가 같은 알림을 끝없이 처리하다가 멈출 수 있습니다.
🇺🇸 원문 (English)
The ARM PL011 UART driver in drivers/serial/uart_pl011.c fails to acknowledge receive error interrupts. On the PL011, the framing, parity, break, and overrun error interrupts (PL011_IMSC_ERROR_MASK) are cleared only by writing the interrupt-clear register UARTICR; reading the data register clears the RX interrupt and the per-byte RSR status but not the error interrupt status in MIS. The interrupt service routine pl011_isr() acknowledged only the CTS modem-status interrupt and never wrote icr for the error bits, so an asserted error interrupt remains pending after the ISR returns.
When an application enables error-interrupt reporting via the public uart_irq_err_enable() API, an attacker who controls the serial peer can deterministically assert these error bits by injecting line errors on the RX line — a baud/stop-bit mismatch or mid-character break (framing/break error), a flipped parity bit (parity error), or FIFO flooding (overrun error). Because the error interrupt is never cleared, the interrupt line stays asserted and the CPU re-enters pl011_isr() immediately and indefinitely, producing an interrupt-storm livelock from which the core makes no forward progress.
The impact is an availability-only denial of service (permanent hang), reachable from an external or removable UART peer. Exploitation is gated by configuration: the error interrupt is off by default and no in-tree subsystem enables it, so only applications that explicitly call uart_irq_err_enable() on a PL011-based, interrupt-driven port are affected. The fix makes pl011_isr() acknowledge the pending error bits via uart->icr, breaking the loop, and additionally clears the latched RSR status in pl011_err_check().
📍 영향받는 시스템
uart_irq_err_enable()을 명시적으로 호출하는 PL011 기반 인터럽트 구동 UART 포트를 사용하는 Linux 커널 (수정 이전 버전)
⚔️ 공격 벡터
외부 또는 이동식 UART 장치 연결 상대가 RX 라인에 보드레이트/스톱비트 불일치, 브레이크, 패리티 비트 반전, FIFO 범람 등을 주입하여 오류 인터럽트를 반복 유발
🛡️ 대응 방법
커널을 pl011_isr()에서 오류 비트를 uart->icr로 확인 응답하고 pl011_err_check()에서 RSR 상태를 지우도록 수정된 버전으로 업데이트
🔧 검증 코드
커널 버전이 패치 적용 이전인지 확인하고, 소스에서 pl011_isr 내부에 오류 마스크에 대한 UARTICR 쓰기가 없으면 취약한 것으로 판단하며, 결과가 없으면 해당 드라이버가 설치되지 않은 환경입니다.
uname -r && grep -n 'PL011_IMSC_ERROR_MASK' /usr/src/linux/drivers/tty/serial/amba-pl011.c 2>/dev/null