🇰🇷 한글 설명
Zephyr RTOS의 I3C 서브시스템에서 CONFIG_USERSPACE 빌드 시 i3c_do_ccc()의 시스템콜 검증기가 대상별(per-target) 데이터 버퍼 포인터를 검사하지 않아, 사용자 모드 스레드가 임의의 커널 주소를 지정할 수 있습니다. 이로 인해 커널 메모리 쓰기 및 정보 노출이 발생하여 권한 상승이 가능합니다.
💡 쉬운 설명
일반 사용자 권한의 프로그램이 I3C 장치 통신 기능을 악용해 운영체제 핵심 영역의 메모리를 읽거나 변조할 수 있습니다. 이를 통해 격리 보호 기능을 우회하여 시스템 전체 권한을 얻을 수 있습니다.
🇺🇸 원문 (English)
The system-call verifier for i3c_do_ccc() in drivers/i3c/i3c_handlers.c validated the outer struct i3c_ccc_payload, the broadcast ccc.data buffer and the targets.payloads[] array, but did not validate the per-target data buffers those array elements point at. Each struct i3c_ccc_target_payload carries its own data pointer and data_len, and neither was passed through K_SYSCALL_MEMORY() before the payload was handed to z_impl_i3c_do_ccc() and on to the controller driver. The verifier also operated on the caller's live structure rather than a snapshot, so validated fields could be changed by a second user thread between the check and the driver's use — unlike the sibling z_vrfy_i3c_transfer(), which has always copied its message array first.
The defect is only present in CONFIG_USERSPACE builds, where drivers/i3c/i3c_handlers.c is compiled. An unprivileged user-mode thread that has been granted access to the I3C controller device object — the ordinary way an application lets a user thread talk to I3C peripherals — can issue a direct CCC whose target payload data pointer names an arbitrary kernel address. Controller drivers dereference that pointer directly (for example drivers/i3c/i3c_mcux.c, drivers/i3c/i3c_cdns.c, drivers/i3c/i3c_stm32.c, drivers/i3c/i3c_npcx.c), using rnw to decide direction.
A read CCC therefore causes the kernel-mode driver to write bus-received bytes into an attacker-chosen kernel address for an attacker-chosen length, and a write CCC transmits kernel memory out onto the I3C bus. The result is an out-of-bounds kernel write plus a kernel memory disclosure, i.e. escalation from a user-mode thread to supervisor privilege, defeating the isolation CONFIG_USERSPACE is meant to provide.
The fix introduces copy_ccc_and_do(), which snapshots the payload, copies the target array into kernel memory with k_usermode_alloc_from_copy() (bounding num_targets to fewer than 32), validates each per-target buffer with K_SYSCALL_MEMORY() according to rnw, and copies the driver-written num_xfer and err fields back to the caller.
📍 영향받는 시스템
CONFIG_USERSPACE가 활성화된 Zephyr RTOS 및 I3C 드라이버를 사용하는 임베디드 장치 (패치 적용 이전 버전)
⚔️ 공격 벡터
사용자 모드 스레드가 I3C 컨트롤러 장치 객체에 접근하여 조작된 CCC 페이로드의 데이터 포인터로 임의 커널 주소를 지정해 읽기/쓰기 CCC를 발행
🛡️ 대응 방법
Zephyr 최신 버전으로 업데이트하여 copy_ccc_and_do() 수정 사항이 포함된 패치를 적용
🔧 검증 코드
명령 결과에 copy_ccc_and_do 함수 정의가 출력되면 패치가 적용된 것이고, 아무 결과도 없거나 경로 오류가 나오면 패치가 적용되지 않은 것으로 판단하여 업데이트가 필요합니다.
grep -rn 'copy_ccc_and_do' $(west topdir 2>/dev/null || echo .)/zephyr/drivers/i3c/i3c_handlers.c 2>/dev/null || echo 'Zephyr 소스 경로를 확인하세요'