🇰🇷 한글 설명
Zephyr USB 디바이스 스택의 CDC NCM 클래스 핸들러(usbd_cdc_ncm_cth)는 GET_NTB_PARAMETERS 및 GET_NTB_INPUT_SIZE 요청 처리 시 호스트가 지정한 wLength를 무시하고 고정 크기 구조체 전체를 복사합니다. 이로 인해 wLength가 응답 크기보다 작을 경우 할당된 버퍼 밖으로 최대 27바이트가 기록되는 버퍼 오버플로가 발생하며, 이는 USB 스택의 메모리 손상 및 서비스 거부를 초래할 수 있습니다.
💡 쉬운 설명
USB 장치가 호스트의 요청 길이를 확인하지 않고 정해진 크기만큼 데이터를 써서, 할당된 메모리 바깥을 침범합니다. 연결된 아무 호스트나 특수하게 만든 USB 요청으로 장치의 USB 기능을 망가뜨리거나 멈추게 할 수 있습니다.
🇺🇸 원문 (English)
The USB device-side CDC NCM class control-to-host handler usbd_cdc_ncm_cth in subsys/usb/device_next/class/usbd_cdc_ncm.c builds a fixed-size response for the GET_NTB_PARAMETERS (28-byte struct ntb_parameters) and GET_NTB_INPUT_SIZE (8-byte struct ntb_input_size) class requests and copies the whole structure into the control DATA IN buffer with net_buf_add_mem(buf, ..., sizeof(...)), ignoring the host-supplied wLength.
The control DATA IN buffer is allocated by the USB stack with a capacity of exactly wLength bytes (usbd_ep_ctrl_data_in_alloc -> udc_ctrl_data_alloc -> net_buf_alloc_len(&udc_ep_pool, wLength); no round-up is applied for the IN endpoint). Because net_buf_add_mem/net_buf_simple_add only bounds the copy with an __ASSERT_NO_MSG, which is compiled out in production builds, a host that issues one of these standard CDC NCM control requests with a wLength smaller than the response structure (e.g. wLength = 1) causes the handler to memcpy up to 27 bytes past the end of the allocated pool buffer.
The request fields come straight from the USB SETUP packet, so any host (or USB interposer) the Zephyr device enumerates against can trigger the overflow with no authentication once an image built with the device_next USB stack and the CDC NCM class is connected. The out-of-bounds write corrupts adjacent allocations and metadata in the shared udc_ep_pool, primarily causing memory corruption and denial of service of the USB stack; the overflow length is bounded (<= 27 bytes) and the written content is fixed device constants, and the bug reads nothing back so there is no information disclosure. The fix clamps the copy with MIN(sizeof(...), setup->wLength), matching the existing CDC ACM handler.
📍 영향받는 시스템
device_next USB 스택과 CDC NCM 클래스를 사용하는 Zephyr RTOS 빌드 이미지 (수정 버전 이전 Zephyr 릴리스)
⚔️ 공격 벡터
공격자는 USB 호스트 또는 USB 중간자 장치를 통해 wLength가 작은 CDC NCM 표준 제어 요청을 전송하여 버퍼 오버플로를 유발할 수 있으며, 인증이 필요하지 않습니다.
🛡️ 대응 방법
Zephyr를 패치된 버전으로 업데이트하거나, usbd_cdc_ncm.c의 해당 복사 구문을 MIN(sizeof(...), setup->wLength)로 제한하도록 수정하고, 취약한 device_next CDC NCM 클래스 사용을 중단합니다.
🔧 검증 코드
결과에 GET_NTB_PARAMETERS/GET_NTB_INPUT_SIZE 응답 복사 라인이 MIN() 없이 출력되면 취약한 상태이며, 출력이 없거나 모든 복사에 MIN()이 적용되어 있으면 패치가 적용된 것입니다.
grep -rn "net_buf_add_mem" $ZEPHYR_BASE/subsys/usb/device_next/class/usbd_cdc_ncm.c 2>/dev/null | grep -v MIN