From 64fae9d82989ede6c92e230c594ab9335c05df8d Mon Sep 17 00:00:00 2001
From: Arne Schwabe <arne@rfc2549.org>
Date: Fri, 10 Apr 2026 16:59:53 +0200
Subject: [PATCH 2/2] Ensure that buffer of freed session are not used

In a race condition an old TLS session could still try to send a packet but
also get replaced by a new session. In this case, the buffer of the new
session is still referenced. Add the check_session_buf_not_used function
to mitigate this problem.

Also make the check if the to_link pointer is in one of the memory
regions a bit better even though this not make a difference with the
way we use these structs. But better safe than sorry.

A better solution to remove the TM_INITIAL state and handle reconnecting
session in their own complete tls_multi is a more involved fix that requires
a lot more refactoring.

CVE: 2026-40215
Reported-By: XlabAI Team of Tencent Xuanwu Lab (xlabai@tencent.com)
Reported-By: Guannan Wang (wgnbuaa@gmail.com
Reported-By: Zhanpeng Liu (pkugenuine@gmail.com)
Reported-By: Guancheng Li (lgcpku@gmail.com)
Signed-off-by: Arne Schwabe <arne@rfc2549.org>

Change-Id: I7c5fa2a7a2563b7a8955d386411f3ceffe5b092f
Private-URL: https://github.com/OpenVPN/openvpn-private-issues/issues/112
Acked-by: Gert Doering <gert@greenie.muc.de>
Signed-off-by: Gert Doering <gert@greenie.muc.de>
---
 src/openvpn/ssl.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c
index 5868d531..d332359c 100644
--- a/src/openvpn/ssl.c
+++ b/src/openvpn/ssl.c
@@ -3290,6 +3290,7 @@ tls_multi_process(struct tls_multi *multi, struct buffer *to_link,
                 if (i == TM_ACTIVE && ks_lame->state >= S_GENERATED_KEYS
                     && !multi->opt.single_session)
                 {
+                    check_session_buf_not_used(to_link, session);
                     move_session(multi, TM_LAME_DUCK, TM_ACTIVE, true);
                 }
                 else
@@ -3363,6 +3364,7 @@ tls_multi_process(struct tls_multi *multi, struct buffer *to_link,
      */
     if (TLS_AUTHENTICATED(multi, &multi->session[TM_INITIAL].key[KS_PRIMARY]))
     {
+        check_session_buf_not_used(to_link, &multi->session[TM_ACTIVE]);
         move_session(multi, TM_ACTIVE, TM_INITIAL, true);
         tas = tls_authentication_status(multi);
         msg(D_TLS_DEBUG_LOW,
-- 
2.53.0

