FlawOpen

flawopen.com/Teardowns/cve-2026-49878-android-wpa-supplicant-oob-write

● CVE-2026-49878 · CVSS 7.2 · 높음
보안 연구 · FlawOpen

CVE-2026-49878: Android Wi-Fi 메모리 범위 밖 쓰기

Android 2026년 10월 보안 공지는 이 Wi-Fi 원격 코드 실행 취약점을 High로 분류합니다. AOSP는 바이트 수 기준으로 할당하던 두 int 배열을 수정했습니다. 기록에는 시스템 권한이 필요하다고 나옵니다.

💡 알기 쉬운 설명 (ELI5)

물건마다 상자 하나를 놓을 선반인데 담당자가 상자마다 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))로 바꿉니다. 이 범위 밖 쓰기만으로 공격자 제어 코드 실행을 추론하지 마세요.

단계별 공격 실행 흐름

단계 1

응답 프레임이 전달된다

Wi-Fi 경로가 Robust AV SCS Response를 해당 핸들러로 전달합니다. 네트워크 경로지만 임의의 미인증 송신자가 모든 조건을 만족한다는 점은 공개 자료에서 확인되지 않습니다.

단계 2

요청 상태와 경계를 확인한다

핸들러는 대기 요청과 일치 token을 요구하고 개수도 검사합니다. NVD의 CISA-ADP 벡터는 AV:N/AC:L/PR:H/UI:N입니다. 높은 권한 요구 조건을 유지하세요.

단계 3

정수 값이 바이트 할당량을 넘는다

이전 코드는 항목마다 1바이트를 할당하고 int 값을 씁니다. 개수 제한은 할당 바이트를 늘리지 않습니다.

단계 4

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;
}

엔지니어링 및 시스템 보안 강화 체크리스트

출처