[하루한줄] CVE-2022-0435: 리눅스 커널의 원격 Stack Buffer Overflow 취약점
URL
CVE-2022-0435: A Remote Stack Overflow in The Linux Kernel
Target
- Linux Kernel 4.8 ~ 5.17-rc3
Explain
지난 11월 공개된 TIPC 취약점 [하루한줄] CVE-2021-43267: Remote Linux Kernel Heap Overflow | TIPC Module Allows Arbitrary Code Execution 에 이어 TIPC 모듈의 기능 중 모니터링 프레임워크에서 원격에서 Stack Buffer Overflow를 트리거할 수 있는 취약점의 세부 정보가 공개되었습니다.
TIPC의 모니터링 프레임워크는 동일한 도메인의 인접 노드를 모니터링하기 위해 tipc_peer
구조체에서 참조하는 tipc_mon_domain
구조체를 사용합니다. 구조체 필드는 아래와 같으며 memeber 수와 같은 TIPC 토폴로지를 정의하는 데 사용되는 도메인 레코드를 나타냅니다.
#define MAX_MON_DOMAIN 64
struct tipc_mon_domain {
u16 len;
u16 gen;
u16 ack_gen;
u16 member_cnt;
u64 up_map;
u32 members[MAX_MON_DOMAIN];
};
해당 구조체의 members
필드는 최대 MAX_MON_DOMAIN
, 64개의 도메인 멤버를 추적할 수 있도록 정의되어 있습니다.
TIPC에서 노드 간 메시지는 헤더 필드 LINK_PROTOCOL
(TIPC message user)와 STATE_MSG
(message type)를 통해 나뉘는데, STATE_MSG
내에 도메인 레코드가 포함된 경우 피어의 도메인 레코드를 업데이트하는 tipc_mon_rcv
함수에 취약점이 존재합니다.
void tipc_mon_rcv(struct net *net, void *data, u16 dlen, u32 addr,
struct tipc_mon_state *state, int bearer_id)
{
...
struct tipc_mon_domain *arrv_dom = data;
struct tipc_mon_domain dom_bef;
...
// new_member_cnt에 대한 최대값 검사가 존재하지 않음
if (dlen < dom_rec_len(arrv_dom, 0))
return;
if (dlen != dom_rec_len(arrv_dom, new_member_cnt))
return;
if (dlen < new_dlen || arrv_dlen != new_dlen)
return;
...
/* Cache current domain record for later use */
dom_bef.member_cnt = 0;
dom = peer->domain;
if (dom)
memcpy(&dom_bef, dom, dom->len);
/* Transform and store received domain record */
if (!dom || (dom->len < new_dlen)) {
kfree(dom);
dom = kmalloc(new_dlen, GFP_ATOMIC);
peer->domain = dom;
if (!dom)
goto exit;
}
...
tipc_mon_domain
구조체를 지역 변수로 할당한 뒤 헤더의 정의된 STATE_MSG
길이인 dlen
이 충분히 큰지 등을 검사하는 루틴이 존재합니다.그러나 해당 검사 과정에서 new_member_cnt
의 최대 크기로 정의되어 있는 #define MAX_MON_DOMAIN 64
보다 작은지 확인하는 검사가 존재하지 않습니다.
dom = {
len = 1072,
gen = 3,
ack_gen = 3,
member_cnt = 264;
up_map = 0xffffffffffffffff;
u32 members[264] = 0x1337...
};
따라서 해커가 위와 같이 임의의 member_cnt
및 Members[]
필드가 있는 tipc_mon_domain
를 보내면 memcpy(&dom_bef, dom, dom->len);
에서 스택에 272 bytes 크기로 할당한 tipc_mon_domain
구조체에 len
필드 값인 1072 bytes를 복사하게되고 stack buffer overflow가 트리거됩니다.
취약점은 new_member_cnt
에 대한 최대 크기 검사를 추가하는 것으로 패치되었습니다.
/* Sanity check received domain record */
+ if (new_member_cnt > MAX_MON_DOMAIN)
+ return;
if (dlen < dom_rec_len(arrv_dom, 0))
return;
if (dlen != dom_rec_len(arrv_dom, new_member_cnt))
본 글은 CC BY-SA 4.0 라이선스로 배포됩니다. 공유 또는 변경 시 반드시 출처를 남겨주시기 바랍니다.