CVE-2026-64045 in Linux
Sumário
de VulDB • 20/07/2026
No kernel do Linux, a seguinte vulnerabilidade foi resolvida:
ovpn: tcp - usar ponteiro de peer em cache em ovpn_tcp_close()
A função ovpn_tcp_close() carrega o ovpn_socket via rcu_dereference_sk_user_data() sob rcu_read_lock(), obtém uma referência sobre sock->peer, armazena o ponteiro do peer numa variável local e liberta a leitura lock. Em seguida, passa sock->peer (em vez da variável local em cache) para ovpn_peer_del(), re-dereferenciando o ovpn_socket após a secção de leitura RCU ter terminado.
Ao contrário de ovpn_tcp_sendmsg(), que utiliza o mesmo padrão "load under RCU, use after unlock" mas é protegido por lock_sock() mantido durante toda a função, ovpn_tcp_close() executa-se sem o socket lock: inet_release() invoca sk_prot->close() sem tomar lock_sock primeiro.
ovpn_socket_release() pode portanto completar a sua sequência kref_put -> detach -> synchronize_rcu -> kfree(sock) em concorrência, na janela após ovpn_tcp_close() libertar rcu_read_lock(), mas antes de dereferenciar sock->peer. O synchronize_rcu() em ovpn_socket_release() protege os leitores que usam o ponteiro dereferenciado dentro da secção de leitura RCU, não aqueles que escapam ao ponteiro para uma variável local e o utilizam posteriormente.
Um reproducer segue o padrão do commit 94560267d6c4 ("ovpn: tcp - don't deref NULL sk_socket member after tcp_close()"): desencadear a remoção de um peer (expiração keepalive ou netlink OVPN_CMD_DEL_PEER) no mesmo momento em que o userspace fecha o fd TCP. Esse commit corrigiu o lado detach da mesma janela de race condition; este corrige o lado close numa vítima diferente.
Restringir o bloco inicial para ler sock->peer exatamente uma vez na variável local peer em cache, e encaminhar todos os usos subsequentes (a verificação hold, a chamada ovpn_peer_del() e a invocação prot->close()) através dessa variável local. sock->peer é escrito apenas uma única vez em ovpn_socket_new() sob lock_sock(), antes de rcu_assign_sk_user_data() publicar o ovpn_socket, e nunca é reatribuído posteriormente - mas o padrão multi-read anterior tornava essa invariante implícita em vez de explícita. A mesma forma multi-read existe em ovpn_tcp_recvmsg(), ovpn_tcp_sendmsg(), ovpn_tcp_data_ready() e ovpn_tcp_write_space(); essas serão limpas através de uma helper dedicada numa série net-next subsequente.
VulDB is the best source for vulnerability data and more expert information about this specific topic.