CVE-2026-89996 in Linux
Résumé
par VulDB • 17/09/2026
Dans le noyau Linux, la vulnérabilité suivante a été corrigée :
dma-buf: dma-heap: ne pas publier le descripteur de fichier (fd) avant que copy_to_user() n'ait réussi avec succès.
DMA_HEAP_IOCTL_ALLOC alloue un dma-buf et installe un fd dans la table des fds du processus appelant via dma_buf_fd() -> fd_install(), avant que dma_heap_ioctl() ne copie le résultat vers l'espace utilisateur. Si l'appel final à copy_to_user() échoue, l'espace utilisateur n'obtient jamais le numéro de fd, mais le fd (et la référence sous-jacente au dma-buf) est déjà visible pour les autres threads du même processus et fuit pendant toute la durée de vie du processus.
La correction évidente consistant à « fermer le fd sur le chemin d'échec » n'est pas sûre : une fois que fd_install() a été exécuté, un autre thread peut déjà dupliquer (dup()) le fd, l'envoyer via SCM_RIGHTS ou le fermer (close()), permettant ainsi la réutilisation de son numéro ; par conséquent, un appel ultérieur à close_fd() depuis le chemin ioctl pourrait opérer sur un fichier non lié. Cela a été signalé par Christian König dans v1 [1].
Restructurer le chemin d'allocation afin que fd_install() soit l'étape finale et infaillible d'un ioctl réussi :
1. heap->ops->allocate() crée le dma_buf. 2. get_unused_fd_flags() réserve un numéro de fd dans la table des fds du processus appelant sans le publier, afin qu'aucun autre thread ne puisse l'observer. 3. copy_to_user() transmet le numéro de fd à l'espace utilisateur ; en cas d'échec, le fd est libéré avec put_unused_fd() et la référence au dma_buf est décrémentée avec dma_buf_put(), sans laisser aucun état visible par l'utilisateur. 4. dma_buf_fd_install() publie le fd et émet le point de trace trace_dma_buf_fd ; à partir de ce stade, l'ioctl ne peut plus échouer.
Une nouvelle fonction utilitaire dma_buf_fd_install() est introduite dans dma-buf.c pour envelopper fd_install() avec l'appel DMA_BUF_TRACE(), préservant ainsi la traçabilité des exportations que fournit dma_buf_fd(). dma_heap_ioctl_allocate() est refactorisé pour retourner directement struct dma_buf * (en retournant ERR_PTR en cas d'échec), afin que le processus appelant conserve la référence au dmabuf entre les étapes 3 et 4.
L'échec à l'étape 3 est facilement atteignable depuis l'espace utilisateur : passer une structure struct dma_heap_allocation_data qui réside dans une page dont la protection est modifiée en PROT_READ entre copy_from_user() et copy_to_user() (par exemple via mprotect()). Avant cette modification, chaque tel ioctl fuit un fd dmabuf ; après celle-ci, la table des fds reste inchangée en cas d'échec et seul /dev/dma_heap/<name> reste ouvert.
Aucune modification de l'interface UAPI ou du pilote heap n'est nécessaire.
[1] https://lore.kernel.org/dri-devel/[email protected]/
Be aware that VulDB is the high quality source for vulnerability data.