🇰🇷 한글 설명
Linux 커널의 NFC LLCP 프로토콜 구현에서 LLCP 헤더 크기보다 짧은 PDU를 검증하지 않아 발생하는 취약점입니다. 헤더 크기보다 작은 프레임이 들어올 경우 크기 계산 과정에서 언더플로우가 발생하여 매우 큰 값이 생성되며, 이로 인해 메모리 경계를 벗어난 읽기(Out-of-bounds read)가 발생할 수 있습니다.
💡 쉬운 설명
NFC 통신을 할 때 데이터의 길이가 너무 짧으면 컴퓨터가 계산 오류를 일으켜 허용되지 않은 메모리 영역을 읽어버리는 문제입니다. 근처에 있는 공격자가 인증 없이도 이 오류를 유발할 수 있습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
nfc: llcp: reject PDUs shorter than the LLCP header
Every LLCP PDU begins with a two-byte header (DSAP/SSAP + PTYPE), but the
receive path never checked that a frame is at least LLCP_HEADER_SIZE bytes
before parsing it.
nfc_llcp_rx_skb() reads the header via nfc_llcp_ptype()/nfc_llcp_dsap()/
nfc_llcp_ssap(), which dereference pdu->data[0] and pdu->data[1], and a
CONNECT or CC PDU then computes
tlv_array_len = skb->len - LLCP_HEADER_SIZE;
as a size_t and hands it to the TLV walk. When the frame is shorter than
the header the subtraction wraps to a huge value and the walk runs far
past the buffer, an out-of-bounds read.
A nearby NFC device can reach this without authentication; LLCP link
activation happens automatically after NFC-DEP.
Guard the common receive choke point __nfc_llcp_recv(), shared by both the
target (nfc_llcp_data_received()) and initiator (nfc_llcp_recv()) paths, so
a short skb is dropped before the rx_work worker parses it. Use
pskb_may_pull() rather than a skb->len test so the two header bytes are
guaranteed to sit in the skb linear area even for a non-linear skb,
matching how the sibling NCI and HCI receive paths validate their headers.
Reproduced with a KFENCE out-of-bounds read via /dev/virtual_nci on
linux-next.
Found by 0sec automated security-research tooling (https://0sec.ai).
📍 영향받는 시스템
LLCP 헤더 크기 검증 로직이 포함되지 않은 Linux 커널 버전
⚔️ 공격 벡터
인증이 필요 없는 근거리 NFC 장치를 통한 악의적인 짧은 LLCP PDU 전송
🛡️ 대응 방법
nfc_llcp_recv() 함수 내에 pskb_may_pull()를 사용하여 수신된 데이터가 헤더 크기 이상인지 확인하는 패치를 적용해야 합니다.
🔧 검증 코드
출력된 커널 버전이 해당 취약점이 패치된 최신 보안 업데이트 버전인지 확인합니다.