From a4bb702aa62e4fad91ca99142de075265555ec18 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Tue, 13 May 2025 10:34:08 +0200
Subject: [PATCH] transport: Initialize function pointers after resource
 allocation

The transport instance is freed when an error occurs.
If the TransportDisconnect function pointer is initialized it
causes SIGSEGV during free.

CVE: CVE-2025-4478
---
 libfreerdp/core/transport.c | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c
index d199c31be4a5..2ca146f65133 100644
--- a/libfreerdp/core/transport.c
+++ b/libfreerdp/core/transport.c
@@ -1646,20 +1646,6 @@ rdpTransport* transport_new(rdpContext* context)
 	if (!transport->log)
 		goto fail;
 
-	// transport->io.DataHandler = transport_data_handler;
-	transport->io.TCPConnect = freerdp_tcp_default_connect;
-	transport->io.TLSConnect = transport_default_connect_tls;
-	transport->io.TLSAccept = transport_default_accept_tls;
-	transport->io.TransportAttach = transport_default_attach;
-	transport->io.TransportDisconnect = transport_default_disconnect;
-	transport->io.ReadPdu = transport_default_read_pdu;
-	transport->io.WritePdu = transport_default_write;
-	transport->io.ReadBytes = transport_read_layer;
-	transport->io.GetPublicKey = transport_default_get_public_key;
-	transport->io.SetBlockingMode = transport_default_set_blocking_mode;
-	transport->io.ConnectLayer = transport_default_connect_layer;
-	transport->io.AttachLayer = transport_default_attach_layer;
-
 	transport->context = context;
 	transport->ReceivePool = StreamPool_New(TRUE, BUFFER_SIZE);
 
@@ -1698,6 +1684,20 @@ rdpTransport* transport_new(rdpContext* context)
 	if (!InitializeCriticalSectionAndSpinCount(&(transport->WriteLock), 4000))
 		goto fail;
 
+	// transport->io.DataHandler = transport_data_handler;
+	transport->io.TCPConnect = freerdp_tcp_default_connect;
+	transport->io.TLSConnect = transport_default_connect_tls;
+	transport->io.TLSAccept = transport_default_accept_tls;
+	transport->io.TransportAttach = transport_default_attach;
+	transport->io.TransportDisconnect = transport_default_disconnect;
+	transport->io.ReadPdu = transport_default_read_pdu;
+	transport->io.WritePdu = transport_default_write;
+	transport->io.ReadBytes = transport_read_layer;
+	transport->io.GetPublicKey = transport_default_get_public_key;
+	transport->io.SetBlockingMode = transport_default_set_blocking_mode;
+	transport->io.ConnectLayer = transport_default_connect_layer;
+	transport->io.AttachLayer = transport_default_attach_layer;
+
 	return transport;
 fail:
 	WINPR_PRAGMA_DIAG_PUSH
