CVE-2026-35512: Heap overflow in dynvc processing

Length checking for the EGFX dynamic virtual channel is inadequate,
allowing for heap overflows to be forced by a malicious client before
authentication.
This commit is contained in:
matt335672
2026-04-01 10:49:51 +01:00
parent 36fbebcb9d
commit 41a4af0a36
2 changed files with 16 additions and 4 deletions
+10 -1
View File
@@ -468,6 +468,15 @@ drdynvc_process_data_first(struct xrdp_channel *self,
"ChannelId %d, Length %d, Data (omitted from the log)", "ChannelId %d, Length %d, Data (omitted from the log)",
chan_id, total_bytes); chan_id, total_bytes);
// See [MS-RDPBCGR] 2.2.3
if (total_bytes < 1590 || bytes > total_bytes)
{
LOG(LOG_LEVEL_ERROR,
"Badly formed DYNVC_DATA_FIRST PDU received on dynamic channel %d",
chan_id);
return 1;
}
session = self->sec_layer->rdp_layer->session; session = self->sec_layer->rdp_layer->session;
if (chan_id > 255) if (chan_id > 255)
{ {
@@ -513,7 +522,7 @@ drdynvc_process_data(struct xrdp_channel *self,
session = self->sec_layer->rdp_layer->session; session = self->sec_layer->rdp_layer->session;
if (chan_id > 255) if (chan_id > 255)
{ {
LOG(LOG_LEVEL_ERROR, "Received message for an invalid " LOG(LOG_LEVEL_ERROR, "Received DYNVC_DATA PDU for an invalid "
"channel id. channel id %d", chan_id); "channel id. channel id %d", chan_id);
return 1; return 1;
} }
+6 -3
View File
@@ -968,10 +968,12 @@ xrdp_egfx_data_first(struct xrdp_process *id, int chan_id,
egfx = id->wm->mm->egfx; egfx = id->wm->mm->egfx;
if (egfx->s != NULL) if (egfx->s != NULL)
{ {
LOG(LOG_LEVEL_DEBUG, "xrdp_egfx_data_first: Error!" LOG(LOG_LEVEL_ERROR, "DYNVC_DATA_FIRST PDU received while"
" Stream is not working on initial data received!"); " another stream is active on channel %d", chan_id);
return 1;
} }
make_stream(egfx->s); make_stream(egfx->s);
// Caller has checked total_bytes is >= 0 and bytes is < total_bytes
init_stream(egfx->s, total_bytes); init_stream(egfx->s, total_bytes);
out_uint8a(egfx->s, data, bytes); out_uint8a(egfx->s, data, bytes);
return 0; return 0;
@@ -1024,7 +1026,8 @@ xrdp_egfx_data(struct xrdp_process *id, int chan_id, char *data, int bytes)
} }
if (!s_check_rem_out(egfx->s, bytes)) if (!s_check_rem_out(egfx->s, bytes))
{ {
LOG(LOG_LEVEL_DEBUG, "xrdp_egfx_data: error"); LOG(LOG_LEVEL_ERROR, "DYNVC_DATA PDU data overflow on channel %d",
chan_id);
return 1; return 1;
} }
out_uint8a(egfx->s, data, bytes); out_uint8a(egfx->s, data, bytes);