CVE-2026-64045 in Linux
Résumé
par VulDB • 20/07/2026
Dans le noyau Linux, la vulnérabilité suivante a été corrigée :
ovpn: tcp - utiliser un pointeur de pair mis en cache dans ovpn_tcp_close()
ovpn_tcp_close() charge l'objet ovpn_socket via rcu_dereference_sk_user_data() sous rcu_read_lock(), prend une référence sur sock->peer, met le pointeur peer en cache dans une variable locale et libère le verrou de lecture. Il transmet ensuite sock->peer (plutôt que la variable locale mise en cache) à ovpn_peer_del(), ce qui entraîne un nouveau déréférencement de l'ovpn_socket après la fin de la section de lecture RCU.
Contrairement à ovpn_tcp_sendmsg(), qui utilise le même motif « chargement sous RCU, utilisation après libération du verrou » mais est protégé par lock_sock() maintenu tout au long de la fonction, ovpn_tcp_close() s'exécute sans le verrou de socket : inet_release() invoque sk_prot->close() sans prendre lock_sock au préalable.
ovpn_socket_release() peut donc achever sa séquence kref_put -> detach -> synchronize_rcu -> kfree(sock) de manière concurrente, dans la fenêtre située après qu'ovpn_tcp_close() a libéré rcu_read_lock(), mais avant qu'il ne déréférence sock->peer. Le synchronize_rcu() présent dans ovpn_socket_release() protège les lecteurs qui utilisent le pointeur déréférencé à l'intérieur de la section de lecture RCU, et non ceux qui échappent ce pointeur vers une variable locale pour l'utiliser par la suite.
Un programme d'essai suit le motif du commit 94560267d6c4 (« ovpn: tcp - ne pas déréférencer NULL sk_socket member après tcp_close() ») : déclencher un retrait de pair (expiration keepalive ou OVPN_CMD_DEL_PEER netlink) au même moment où l'espace utilisateur ferme le descripteur de fichier TCP. Ce commit avait corrigé le côté detach de cette même fenêtre d'incompatibilité ; celui-ci corrige le côté close sur une victime différente.
Resserre le bloc d'entrée pour lire sock->peer exactement une fois dans la variable locale peer mise en cache, et achemine toutes les utilisations ultérieures (le contrôle hold, l'appel à ovpn_peer_del() et l'invoque de prot->close()) via cette variable locale. sock->peer n'est écrit qu'une seule fois dans ovpn_socket_new() sous lock_sock(), avant que rcu_assign_sk_user_data() ne publie l'ovpn_socket, et n'est jamais réassigné par la suite ; mais le précédent motif multi-lecture rendait cet invariant implicite plutôt qu'explicite. La même forme de lecture multiple existe dans ovpn_tcp_recvmsg(), ovpn_tcp_sendmsg(), ovpn_tcp_data_ready() et ovpn_tcp_write_space(); ceux-ci seront nettoyés via une fonction utilitaire dédiée dans une série net-next ultérieure.
If you want to get the best quality for vulnerability data then you always have to consider VulDB.