From 9a610fc2f297613790bc91086b183ca81d06e6f5 Mon Sep 17 00:00:00 2001
From: matt335672 <30179339+matt335672@users.noreply.github.com>
Date: Mon, 15 Jun 2026 11:52:25 +0100
Subject: [PATCH] CVE-2026-54538: Pre-auth infinite loop in
 TS_SHARECONTROLHEADER

(cherry picked from commit 2394084bf46a8716ceeb66d1feccb65055d707dd)
---
 libxrdp/xrdp_rdp.c | 31 +++++++++++++++++--------------
 1 file changed, 17 insertions(+), 14 deletions(-)

--- a/libxrdp/xrdp_rdp.c
+++ b/libxrdp/xrdp_rdp.c
@@ -533,23 +533,26 @@ xrdp_rdp_recv(struct xrdp_rdp *self, str
     {
         s->next_packet = 0;
         *code = 0;
-        LOG(LOG_LEVEL_ERROR, "xrdp_rdp_recv: out code 0 (skip data) "
-            "bad RDP packet");
-        return 0;
+        LOG(LOG_LEVEL_ERROR, "xrdp_rdp_recv: out code 0 bad RDP packet");
+        return 1;
     }
-    else
+    in_uint16_le(s, len);      /* totalLength */
+    in_uint16_le(s, pdu_code); /* pduType */
+    in_uint8s(s, 2);           /* pduSource */
+    // Length must be at least the size of TS_SHARECONTROLHEADER, and
+    // cannot fall beyond the end of the PDU
+    if (len < 6 || !s_check_rem(s, len - 6))
     {
-        in_uint16_le(s, len);      /* totalLength */
-        in_uint16_le(s, pdu_code); /* pduType */
-        *code = pdu_code & 0xf;
-        in_uint8s(s, 2);           /* pduSource */
-        s->next_packet += len;
-        LOG_DEVEL(LOG_LEVEL_TRACE, "Received header [MS-RDPBCGR] TS_SHARECONTROLHEADER "
-                  "totalLength %d, pduType.type %s (%d), pduType.PDUVersion %d, "
-                  "pduSource (ignored)", len, PDUTYPE_TO_STR(*code), *code,
-                  ((pdu_code & 0xfff0) >> 4));
-        return 0;
+        LOG(LOG_LEVEL_ERROR, "bad TS_SHARECONTROLHEADER length 0x%04X", len);
+        return 1;
     }
+    *code = pdu_code & 0xf;
+    s->next_packet += len;
+    LOG_DEVEL(LOG_LEVEL_TRACE, "Received header [MS-RDPBCGR] TS_SHARECONTROLHEADER "
+              "totalLength %d, pduType.type %s (%d), pduType.PDUVersion %d, "
+              "pduSource (ignored)", len, PDUTYPE_TO_STR(*code), *code,
+              ((pdu_code & 0xfff0) >> 4));
+    return 0;
 }
 
 /*****************************************************************************/
