[하루한줄] CVE-2021-1969: Information leak in Qualcomm npu driver
URL
GHSL-2021-1031: Information leak in Qualcomm npu driver - CVE-2021-1969
Target
MSM Linux(Support Qualcomm chip)
테스트된 버전
- Samsung Galaxy A71: SM-A715F/DS
- AP: A715FXXU3ATJ2
- CP: A715FXXU3ATI5
- Kernel version 4.14.117-19828683
- build ID QP1A.190711.020.A715FXXU3ATJ2
Explain
퀄컴의 Neural Processing Unit, NPU를 지원하는 드라이버에서 커널 주소를 유출할 수 있는 Information disclosure 취약점의 세부 정보가 공개되었습니다.
아래 코드는 취약점이 발생하는 npu_receive_event
함수의 일부입니다. MSM_NPU_RECEIVE_EVENT
IOCTL이 호출되면 msm_npu_event
구조체가 유저랜드로 복사됩니다.
static int npu_receive_event(struct npu_client *client, unsigned long arg)
{
...
if (list_empty(&client->evt_list)) {
...
} else {
kevt = list_first_entry(&client->evt_list, struct npu_kevent, list);
list_del(&kevt->list);
npu_process_kevent(kevt);
/// copy to userland
ret = copy_to_user(argp, &kevt->evt, sizeof(struct msm_npu_event));
...
유저랜드로 복사되는 msm_npu_event
구조체는 아래 코드에서 각각의 필드가 초기화됩니다.
kevt.evt.type = **MSM_NPU_EVENT_TYPE_EXEC_V2_DONE;**
kevt.evt.u.exec_v2_done.network_hdl = exe_rsp_pkt->network_hdl;
kevt.evt.u.exec_v2_done.exec_result = exe_rsp_pkt->header.status;
kevt.evt.u.exec_v2_done.stats_buf_size = stats_size;
kevt.reserved[0] = (uint64_t)network->stats_buf;
kevt.reserved[1] = (uint64_t)network->stats_buf_u;
if (npu_queue_event(network->client, &kevt))
이 중 msm_npu_event_execute_v2_done
구조체는 20 bytes 크기이며 아래 msm_npu-event
구조체의 union 필드 u
에 정의되어 있습니다.
struct msm_npu_event {
uint32_t type;
union {
struct msm_npu_event_execute_done exec_done;
struct msm_npu_event_execute_v2_done exec_v2_done;
struct msm_npu_event_ssr ssr;
uint8_t data[128];
} u;
uint32_t reserved[4];
};
msm_npu_event_execute_v2_done
를 초기화하면 u
의 나머지 108 bytes (data[128] - sizeof(msm_npu_event_execute_v2_done)
) 및 32 bytes 크기의 reserved
필드는 초기화되지 않은 상태로 존재합니다. 따라서 npu_receive_event
함수에서 userland로 복사할 때 sizeof(struct msm_npu_event)
로 전체 msm_npu_event
크기만큼 복사하면서 초기화되지 않은 커널 데이터도 같이 복사되고, 이는 커널 주소 유출로 이어질 수 있습니다.
본 글은 CC BY-SA 4.0 라이선스로 배포됩니다. 공유 또는 변경 시 반드시 출처를 남겨주시기 바랍니다.