flawopen.com/Teardowns/cve-2026-49878-android-wpa-supplicant-oob-write
CVE-2026-49878:Android Wi-Fi の範囲外書き込み
Android 2026年10月のセキュリティ情報は、このWi-Fiのリモートコード実行の脆弱性をHighと評価しています。AOSPはバイト数で確保していた2つのint配列を修正しました。記録上、システム権限が必要です。
棚には品目ごとに箱を置く必要があるのに、担当者が箱1個につき1センチ分しか場所を確保しなければ、箱は棚からはみ出します。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の変更は両配列に 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 1 個分を割り当てる。 */
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更新の適用を確認します。