flawopen.com/Teardowns/cve-2026-49878-android-wpa-supplicant-oob-write
CVE-2026-49878: запись за границы в Wi-Fi Android
В бюллетене Android за октябрь 2026 года эта ошибка удалённого выполнения кода в Wi-Fi получила высокий уровень. AOSP исправил два массива int, выделявшиеся по числу байтов, а не элементов. Запись указывает на необходимость системных привилегий.
Представьте полку для одной коробки на запись, но кладовщик выделяет лишь сантиметр на коробку. Коробки выходят за отведённое место. В CVE-2026-49878 wpa_supplicant выделял память по количеству целых чисел в байтах, а затем записывал целые значения. Патч Google выделяет каждому элементу нужный размер.
Ключевые понятия и термины
wpa_supplicant- Компонент Wi-Fi Android, управляющий беспроводной аутентификацией и взаимодействиями 802.11.
Ответ SCS- Кадр действия ответа Stream Classification Service. Обработчик принимает его только при ожидающем запросе и совпадающем dialog token.
Запись за границы (CWE-787)- Запись за пределами выделенной области памяти. Здесь память выделяется в байтах, а код индексирует элементы
int. os_zalloc / os_calloc- Функции выделения памяти wpa_supplicant. Патч передаёт число элементов и их размер, выделяя полный массив.
Уровень патча безопасности Android (SPL)- Дата установленного уровня обновлений. По данным Google, 2026-10-01 или новее закрывает проблемы бюллетеня; выпуск контролирует производитель.
Связи со стандартами
- Ссылка CWE для слабого места, описанного в этом руководстве: CWE-787
Анализ первопричины
В wpas_handle_robust_av_scs_recv_action scs_resp[0] и [1] — массивы int *. До исправления os_zalloc(num_active_scs) выделял только это число байтов. Код записывает целочисленные идентификаторы и статусы по индексам, поэтому требуется num_active_scs * sizeof(int) байтов. Проверки ожидающего запроса, совпадения dialog token, количества и длины кадра ограничивают ввод, но не исправляют единицы выделения. Патч AOSP заменяет оба вызова на os_calloc(num_active_scs, sizeof(int)). Из этой записи за границу нельзя заключать, что атакующий управляет выполнением кода.
Пошаговый сценарий атаки
Кадр ответа передаётся обработчику
Путь Wi-Fi направляет Robust AV SCS Response в уязвимый обработчик. Путь сетевой, но источники не подтверждают, что любой неаутентифицированный отправитель выполнит все условия.
Проверяются состояние запроса и ограничения
Обработчик требует ожидающий запрос и совпадающий токен, затем проверяет число. Вектор CISA-ADP в NVD: AV:N/AC:L/PR:H/UI:N; сохраняйте требование высоких привилегий.
Целые значения превышают байтовое выделение
Старый код выделяет один байт на запись, но записывает значения int. Ограничение числа не увеличивает выделенную память.
Октябрьский патч исправляет выделение
Изменение Google резервирует num_active_scs элементов размером sizeof(int) для обоих массивов. Не придумывайте payload и не утверждайте, что diff доказывает произвольное выполнение кода.
Исходный код: Уязвимый vs Защищённый вариант
Diff — это опубликованное AOSP изменение кода в коммите d131540379d631d7dcb09b0169e4462bc65abcca, а не реконструированный псевдокод. os_zalloc(n) трактует n как число байтов; os_calloc(count, size) выделяет и обнуляет указанное число элементов. Исправление обновляет оба массива и сохраняет очистку при ошибке выделения.
/* 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 действительно установлено.
Источники
- Бюллетень безопасности Android — октябрь 2026 (обновлён 8 октября)
- Исправление AOSP от Google — выделение массивов SCS по размеру элемента
- Diff патча AOSP — исправление выделения памяти CVE-2026-49878
- NVD — CVE-2026-49878; вектор CVSS и CWE-787 от CISA-ADP
- OSV — исправления веток Android для A-511544607
- Уязвимая версия исходного кода AOSP — robust_av.c