[하루한줄] CVE-2021-30660: macOS 및 iOS의 커널 메모리 유출 취약점
URL
CVE-2021-30660 - XNU Kernel Memory Disclosure
Target
Explain
Apple사의 macOS 및 iOS의 XNU 시스템에서 커널 메모리를 유출할 수 있는 취약점이 발견되어 세부 정보가 공개되었습니다.
XNU의 syscall SYS_msgsnd_nocancel
의 핸들러인 sysv_msg.c/msgrcv_nocancel() 는 유저 공간의 메시지 크기를 msgsz
로 받습니다. 만약 유저 공간에서 요청된 크기가 초기에 커널에 전송된 크기 msghdr→msg_ts
보다 크면 아래와 같이 msghdr→msg_ts
로 자릅니다.
if (msgsz > msghdr->msg_ts) {
msgsz = msghdr->msg_ts;
}
이후 아래의 반복문을 돌며 커널 msgpool
의 데이터를 유저 공간으로 복사합니다.
1 // msg.h
2 #define MSGSSZ 8 /* Each segment must be 2^N long */
3
4 static int msginit(__unused void *dummy){
5 if (i != msginfo.msgssz) {
6 printf("msginfo.msgssz=%d (0x%x) not a small power of 2; resetting to %d\\n", msginfo.msgssz, msginfo.msgssz, MSGSSZ);
7 msginfo.msgssz = MSGSSZ;
8 }
9 ...
10
11 int msgsnd_nocancel(struct proc *p, struct msgsnd_nocancel_args *uap, int32_t *retval){
12 ...
13 for (len = 0; len < msgsz; len += msginfo.msgssz) {
14 size_t tlen;
15 /* compare input (size_t) value against restrict (int) value */
16 if (msgsz > (size_t)msginfo.msgssz) {
17 tlen = msginfo.msgssz;
18 } else {
19 tlen = msgsz;
20 }
21 if (next <= -1) {
22 panic("next too low #3");
23 }
24 if (next >= msginfo.msgseg) {
25 panic("next out of range #3");
26 }
27 SYSV_MSG_SUBSYS_UNLOCK();
28 eval = copyout(&msgpool[next * msginfo.msgssz], user_msgp, tlen);
29 ...
반복문의 증가 값인 msginfo.msgssz
는 msginit()
에서 #define MSGSSZ 8
로 선언된 MSGSSZ
로 초기화되어 특정 조건을 만족하면 8 bytes
단위로 커널 메모리를 유저 공간에 복사하는데, 이때 요청된 크기가 8의 배수가 아닐 경우 초기화되지 않은 1~7 bytes
크기의 커널 메모리가 유출될 수 있습니다.
9 bytes
크기의 SYS_msgsnd_nocancel
syscall을 보낼 경우 취약점은 다음과 같이 트리거 됩니다.
msghdr→msg_ts
와msgsz
가 9로 설정됩니다.- line 16의 조건문에 의해
tlen
이 8이 됩니다. 8 bytes
단위로 복사하는 반복문을 두 번 수행합니다.16 bytes
의 커널 메모리가 유저 공간으로 복사되어 초기화되지 않은7 bytes
크기의 커널 메모리가 유출됩니다.
본 글은 CC BY-SA 4.0 라이선스로 배포됩니다. 공유 또는 변경 시 반드시 출처를 남겨주시기 바랍니다.