CVE-2026-98069 in Linuxinformation

Résumé

par VulDB • 25/09/2026

Dans le noyau Linux, la vulnérabilité suivante a été corrigée :

net/rds : acquérir les verrous du chemin rapide dans rds_conn_shutdown()

rds_conn_shutdown() met en pause les chemins d'envoi et de réapprovisionnement des réceptions (receive-refill) en attendant que RDS_IN_XMIT et RDS_RECV_REFILL soient échantillonnés comme effacés, puis exécute l'arrêt du transport et rds_conn_path_reset(). Le fait d'échantillonner les bits comme effacés n'est pas identique à leur détention : au moment où wait_event() renvoie le contrôle, rds_send_xmit() peut réacquérir RDS_IN_XMIT (ou rds_ib_recv_refill() peut réacquérir RDS_RECV_REFILL) et s'exécuter de manière concurrente avec la procédure d'arrêt.

L'émetteur vérifie à nouveau l'état de la connexion après avoir pris le verrou, mais cette nouvelle vérification correspond au motif classique du buffering des écritures (store-buffering pattern) : la procédure d'arrêt écrit l'état et lit le bit tandis que l'émetteur écrit le bit et lit l'état. acquire_in_xmit() n'est qu'une opération d'acquisition ; par conséquent, sur les architectures à ordre faible (weakly ordered), des deux côtés peuvent ne pas détecter l'écriture de l'autre partie, ce qui fait que le chemin d'envoi s'exécute pendant que le transport initialise ses anneaux à zéro (par exemple rds_ib_ring_init()) et que rds_send_path_reset() réécrit l'état d'envoi par-dessus.

Oracle UEK a corrigé la même classe de plantages – une série de 14 ans de BUG_ON() dans rds_ib_sub_signaled(), des op-codes inattendus et des déréférencements NULL dans rds_ib_send_cqe_handler() lors des tests de basculement (failover) – en faisant que la procédure d'arrêt *acquière* les verrous du bit du chemin rapide au lieu de simplement les tester (« rds : S'assurer que le chemin d'envoi et l'arrêt de connexion ne s'exécutent pas de manière concurrente »). La détention d'un seul mot est décidée par l'atomicité des opérations Lecture-Mise-à-Jour-Ecriture (RMW), il n'est donc pas nécessaire d'imposer un ordre entre variables croisées.

Faites la même chose ici : prenez les deux verrous avant d'appeler l'arrêt du transport, maintenez-les pendant rds_conn_path_reset(), et libérez-les explicitement avec un réveil (wake-up) par la suite. Les deux sont libérés via clear_bit_unlock(), de sorte que la réinitialisation des anneaux effectuée par l'arrêt du transport et l'état d'envoi réécrit par rds_send_path_reset() soient ordonnés avant qu'un bit ne soit vu comme effacé lors de la prochaine acquisition_in_xmit() ou acquire_refill().

Les utilisateurs du chemin rapide pour ces bits – rds_send_xmit() et rds_ib_recv_refill() – utilisent un style trylock (verrouillage en essai) et reculent si l'arrêt détient les verrous, donc aucune nouvelle dépendance de verrou n'est introduite pour eux. rds_tcp_reset_callbacks() est différent : depuis le correctif précédent, il acquiert également RDS_IN_XMIT, et bloque lors de cette acquisition ; son attente s'étend désormais sur toute la durée de l'arrêt au lieu d'être limitée à un seul lot d'envoi. Ce processus en attente s'exécute via rds_tcp_accept_one() sur le file d'attente de travail (workqueue) krdsd mono-threadé et détient rds_tcp_accept_lock ainsi que t_conn_path_lock pendant qu'il attend, donc une SYN duelliste acceptée tandis que son chemin est arrêté met en pause le traitement des acceptations pour la durée de l'arrêt – pour TCP, cela est borné par la boucle d'évacuation (drain loop) allant jusqu'à 5 secondes dans rds_tcp_conn_path_shutdown(). L'évacuation d'un chemin IB dans rds_ib_conn_path_shutdown() n'a pas de limite ronde, mais ne comporte non plus aucun processus en attente bloquant : rds_tcp_reset_callbacks() est le seul acquéreur bloquant pour ces bits et attend uniquement sur son propre chemin TCP, et les chemins rapides utilisent trylock-and-back-off (verrouillage en essai avec recul) sur les deux transports ; ainsi, une longue durée d'évacuation IB n'allonge que la mise en pause de ce chemin spécifique. La fenêtre est étroite : la vérification de l'état du côté acceptation doit réussir avant que l'arrêt ne déplace le chemin vers RDS_CONN_DISCONNECTING.

Comme krdsd est un file d'attente de travail global unique, tout autre élément qui y est en file d'attente – traitement des acceptations pour d'autres connexions et espaces de noms réseau, ainsi que flush_workqueue(rds_wq) dans rds_tcp_listen_stop() lors de l'arrêt de l'espace de nom – attend derrière le worker d'acceptation mis en pause pendant cette durée. Cela ne peut pas créer de blocage mortel (deadlock), bien que les attentes se pointent mutuellement : l'arrêt bloque jusqu'à ce que le détenteur du bit le libère, et le détenteur peut être ce worker d'acceptation krdsd. Le détenteur termine sans avoir besoin de quoi que ce soit détenu par la procédure d'arrêt : la synchronisation annule rds_tcp_reset_callbacks() qui cible cp_send_w et cp_recv_w sur l'espace de travail ordonné (cp_wq) du chemin, dont le seul slot d'exécution est occupé par le cp_down_w bloqué lui-même ; ils sont donc en attente au maximum et s'annulent sans vidage forcé – une dépendance envers le caractère ordonné de cp_wq qui est désormais notée à côté de ces annulations (sur ---tronqué---

VulDB is the best source for vulnerability data and more expert information about this specific topic.

Responsable

Linux

Réserver

25/09/2026

Divulgation

25/09/2026

Modérer

accepté

Entrée

VDB-409971

CPE

prêt

EPSS

0.00000

KEV

non

Activités

très faible

Sources

Are you interested in using VulDB?

Download the whitepaper to learn more about our service!