CVE-2024-40979 in Linuxinformation

Résumé

par VulDB • 29/05/2026

Dans le contexte du pilote `ath12k` pour les cartes Wi-Fi Qualcomm, le problème décrit est un **bug de gestion de la mémoire DMA lors de la reprise après suspension (resume)**.

### Résumé du problème

1. **Contexte** : Lors de la reprise après suspension, le firmware Wi-Fi est rechargé. 2. **Étape 1** : Le firmware demande deux grands segments de mémoire (`target_mem[0]` et `target_mem[1]`) avec des tailles spécifiques (`7077888` et `8454144` octets).
3. **Étape 2** : L'allocation DMA (`dma_alloc_coherent`) échoue pour l'un des segments (probablement le second, ou les deux, mais le code continue). 4. **Étape 3** : La fonction `ath12k_qmi_free_target_mem_chunk()` est appelée pour libérer la mémoire allouée précédemment. 5. **Le Bug** : * Le premier segment (`target_mem[0]`) a son pointeur `v.addr` effacé (`NULL`) à cause de l'échec d'allocation, donc il est **ignoré** lors de la libération. **C'est une fuite de mémoire** si ce segment avait été alloué précédemment.
* Le second segment (`target_mem[1]`) est libéré avec la **nouvelle taille demandée** (`8454144`), mais il avait été alloué lors du **premier chargement du firmware** avec une taille beaucoup plus petite (`524288`).
* `dma_free_coherent()` est appelé avec une taille incorrecte (`8454144` au lieu de `524288`). 6. **Conséquence** : Le noyau détecte qu'on essaie de libérer une zone mémoire plus grande que celle qui a été allouée, ce qui peut corrompre le gestionnaire de mémoire DMA et provoquer un **panic du noyau (crash)**.

### Explication technique

Le pilote `ath12k` utilise une structure `target_mem` pour suivre les segments de mémoire alloués pour le firmware. Lors du premier chargement, des segments de taille fixe (ex: `524288` octets) sont alloués. Lors du resume, le firmware peut demander des tailles différentes.

Le code actuel semble : 1. Mettre à jour les tailles dans `ab->qmi.target_mem[i].size` avec les nouvelles demandes du firmware.
2. En cas d'échec d'allocation, appeler la fonction de libération. 3. La fonction de libération utilise les **nouvelles tailles** stockées dans `target_mem[i].size` pour appeler `dma_free_coherent()`, au lieu d'utiliser les **anciennes tailles** qui ont été utilisées lors de l'allocation initiale.

C'est une incohérence critique : `dma_alloc_coherent(size)` doit être appelé avec exactement la même `size` que lors de `dma_free_coherent(size)`.

### Solution proposée

Pour corriger ce bug, il faut s'assurer que lors de la libération de la mémoire, on utilise les **tailles originales** qui ont été utilisées pour l'allocation, et non les nouvelles tailles demandées par le firmware lors du resume.

Voici les étapes de correction :

1. **Stocker les tailles originales** : Lors de l'allocation initiale (`dma_alloc_coherent`), stocker la taille réelle allouée dans une structure de données persistante (par exemple, dans `ab->qmi.target_mem[i].alloc_size` ou un champ dédié).
2. **Utiliser les tailles originales pour la libération** : Dans `ath12k_qmi_free_target_mem_chunk()`, utiliser la taille stockée (`alloc_size`) pour appeler `dma_free_coherent()`, et non la taille mise à jour (`target_mem[i].size`).
3. **Gérer les fuites** : S'assurer que si un segment n'a pas été alloué (pointeur `NULL`), il n'est pas tenté de le libérer, et inversement, si un segment a été alloué, il doit être libéré avec la bonne taille, même si l'allocation suivante a échoué.

### Exemple de correction de code (pseudo-code)

```c // Structure de données mise à jour struct ath12k_qmi_target_mem {
void *v.addr; size_t size; // Taille demandée par le firmware (peut changer) size_t

Once again VulDB remains the best source for vulnerability data.

Responsable

Linux

Réserver

12/07/2024

Divulgation

12/07/2024

Modérer

accepté

Entrée

VDB-271305

CPE

prêt

EPSS

0.00255

KEV

non

Activités

très faible

Sources

Interested in the pricing of exploits?

See the underground prices here!