flawopen.com/Teardowns/cve-2026-49878-android-wpa-supplicant-oob-write
CVE-2026-49878: Android Wi-Fi 메모리 범위 밖 쓰기
Android 2026년 10월 보안 공지는 이 Wi-Fi 원격 코드 실행 취약점을 High로 분류합니다. AOSP는 바이트 수 기준으로 할당하던 두 int 배열을 수정했습니다. 기록에는 시스템 권한이 필요하다고 나옵니다.
물건마다 상자 하나를 놓을 선반인데 담당자가 상자마다 1cm만 공간을 잡으면 상자가 선반 밖으로 나옵니다. CVE-2026-49878에서 wpa_supplicant는 정수 개수를 바이트 수로 계산해 할당한 뒤 온전한 정수를 기록했습니다. Google 패치는 요소마다 실제 크기만큼 공간을 할당합니다.
핵심 개념 및 용어
wpa_supplicant- 무선 인증과 관련 802.11 상호작용을 관리하는 Android Wi-Fi 구성 요소입니다.
SCS 응답- Stream Classification Service 응답 액션 프레임입니다. 요청이 대기 중이고 dialog token이 일치할 때만 처리됩니다.
범위 밖 쓰기 (CWE-787)- 예약된 메모리 영역을 넘어 쓰는 문제입니다. 여기서는 바이트로 할당하고
int요소 배열처럼 인덱싱합니다. os_zalloc / os_calloc- wpa_supplicant의 메모리 할당 함수입니다. 패치는 개수와 요소 크기를 전달해 전체 배열 공간을 확보합니다.
Android 보안 패치 수준 (SPL)- 설치된 보안 업데이트 수준을 나타내는 날짜입니다. Google은 2026-10-01 이상이 10월 공지 문제를 해결한다고 설명하며 배포는 제조사가 관리합니다.
프레임워크 매핑
- 이 가이드에서 설명하는 약점의 CWE 참조: CWE-787
근본 원인 분석 (Root Cause)
wpas_handle_robust_av_scs_recv_action에서 scs_resp[0]와 [1]은 int * 배열입니다. 수정 전 os_zalloc(num_active_scs)는 해당 개수만큼의 바이트만 할당했습니다. 코드는 인덱스 위치에 정수 ID와 상태를 기록하므로 num_active_scs * sizeof(int) 바이트가 필요합니다. 대기 중 요청, 일치하는 dialog token, 개수, 프레임 길이 검사는 입력을 제한하지만 할당 단위를 고치지는 않습니다. AOSP 패치는 두 호출을 os_calloc(num_active_scs, sizeof(int))로 바꿉니다. 이 범위 밖 쓰기만으로 공격자 제어 코드 실행을 추론하지 마세요.
단계별 공격 실행 흐름
응답 프레임이 전달된다
Wi-Fi 경로가 Robust AV SCS Response를 해당 핸들러로 전달합니다. 네트워크 경로지만 임의의 미인증 송신자가 모든 조건을 만족한다는 점은 공개 자료에서 확인되지 않습니다.
요청 상태와 경계를 확인한다
핸들러는 대기 요청과 일치 token을 요구하고 개수도 검사합니다. NVD의 CISA-ADP 벡터는 AV:N/AC:L/PR:H/UI:N입니다. 높은 권한 요구 조건을 유지하세요.
정수 값이 바이트 할당량을 넘는다
이전 코드는 항목마다 1바이트를 할당하고 int 값을 씁니다. 개수 제한은 할당 바이트를 늘리지 않습니다.
10월 패치가 할당 크기를 바로잡는다
Google 변경은 두 배열에 각각 sizeof(int) 크기의 num_active_scs 요소를 할당합니다. payload를 만들거나 diff가 임의 코드 실행을 증명한다고 주장하지 마세요.
소스 코드 비교: 취약한 구현 vs 보안 패치
이 diff는 AOSP가 commit d131540379d631d7dcb09b0169e4462bc65abcca에 공개한 코드 변경이며 재구성한 pseudocode가 아닙니다. os_zalloc(n)은 n을 byte 수로 보고, os_calloc(count, size)는 지정한 수의 요소를 할당하고 0으로 초기화합니다. 수정은 두 배열을 모두 바로잡고 할당 실패 시 기존 정리 동작을 유지합니다.
/* AOSP 수정 전: num_active_scs는 요소 개수이지만,
* os_zalloc에는 바이트 수로 전달됩니다. */
scs_resp[0] = (int *) os_zalloc(num_active_scs);
if (!scs_resp[0])
return;
scs_resp[1] = (int *) os_zalloc(num_active_scs);
if (!scs_resp[1]) {
os_free(scs_resp[0]);
return;
}
/* AOSP 수정: 각 항목마다 온전한 int 하나를 할당합니다. */
scs_resp[0] = os_calloc(num_active_scs, sizeof(int));
if (!scs_resp[0])
return;
scs_resp[1] = os_calloc(num_active_scs, sizeof(int));
if (!scs_resp[1]) {
os_free(scs_resp[0]);
return;
}
엔지니어링 및 시스템 보안 강화 체크리스트
- ✓Android 14–17에서 SPL 2026-10-01 이상인지 확인하고 제조사 배포 여부를 확인합니다.
- ✓Google Play system update로 구성 요소가 제공되면 Wi-Fi Mainline 업데이트 상태도 점검합니다.
- ✓C에서 타입 배열 크기는
element_count * sizeof(*pointer)로 계산하거나 검토된os_calloc을 사용합니다. - ✓두
scs_resp배열 모두 수정된 용량을 갖는지 확인합니다. - ✓프레임과 요청 상태 검사는 유지하되 올바른 바이트 계산을 대신한다고 여기지 않습니다.
- ✓AOSP 패치 공개만으로 기기가 수정됐다고 판단하지 말고 실제 OEM 또는 Google Play system 업데이트를 확인합니다.