🇰🇷 한글 설명
MQTT-SN 클라이언트의 keepalive 핸들러에서 PINGREQ 재시도 실패 시 게이트웨이 레코드를 삭제하는 과정 중 NULL 포인터 역참조 오류가 발생합니다. 이로 인해 커널 패닉이 발생하거나 메모리 할당자(slab free list)가 손상되어 시스템 가용성이 저해될 수 있습니다.
💡 쉬운 설명
연결된 게이트웨이가 응답을 하지 않을 때 시스템이 잘못된 메모리 주소를 참조하여 프로그램이 강제로 종료되거나 시스템이 멈출 수 있는 문제입니다. 공격자가 의도적으로 응답을 끊음으로써 대상 기기를 마비시킬 수 있습니다.
🇺🇸 원문 (English)
The MQTT-SN client keepalive handler process_ping() in subsys/net/lib/mqtt_sn/mqtt_sn.c removes the gateway record after PINGREQ retries are exhausted. It invoked SYS_SLIST_PEEK_HEAD_CONTAINER(&client->gateways, gw, next) but discarded the result. That macro is a pure expression that does not assign to gw, so gw retained its NULL initializer regardless of the list contents.
The code then dereferences the NULL gw (gw->gw_id) and passes it to mqtt_sn_gw_destroy(), reaching k_mem_slab_free(&gateways, NULL). With CONFIG_MEM_SLAB_POINTER_VALIDATE enabled this triggers k_panic(); in the default configuration it performs a write through the NULL pointer ((char )mem = slab->free_list;) and corrupts the slab free list. The outcome is a crash/kernel panic or, on targets where address 0 is writable, silent memory-allocator corruption.
The vulnerable branch runs whenever the connected MQTT-SN gateway fails to answer keepalive PINGREQs for the configured number of retries. This condition is controlled by the remote peer: a malicious or compromised gateway, or an on-path/adjacent attacker that advertises itself as a gateway and then stops responding (or blackholes the real gateway's PINGRESPs), forces the client into the defect. MQTT-SN runs over UDP and no authentication is required.
The impact is a remotely triggerable denial of service (availability) of the affected MQTT-SN client; there is no attacker-controlled data written. The sibling remover process_advertise() uses SYS_SLIST_FOR_EACH_CONTAINER_SAFE and is not affected. The fix assigns the macro's return value to gw.
📍 영향받는 시스템
MQTT-SN 프로토콜을 사용하는 클라이언트 라이브러리 (subsys/net/lib/mqtt_sn/mqtt_sn.c 포함 시스템)
⚔️ 공격 벡터
악의적인 게이트웨이가 PINGREQ에 응답하지 않거나 네트워크 중간에서 패킷을 차단하여 클라이언트의 재시도를 유도함
🛡️ 대응 방법
process_ping() 함수 내에서 SYS_SLIST_PEEK_HEAD_CONTAINER의 반환 값을 gw 변수에 올바르게 할당하도록 소스 코드를 수정
🔧 검증 코드
명령어 결과에서 반환 값을 변수에 할당하지 않고 사용하는 코드가 발견되면 취약한 상태임
grep -r "SYS_SLIST_PEEK_HEAD_CONTAINER(&client->gateways, gw, next)" subsys/net/lib/mqtt_sn/mqtt_sn.c
📊 CVSS Vector String
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
💻 영향받는 소프트웨어
Windows iSCSI Target Service