drdynvc: Change channel processing to use streams

The channel processor in xrdp_channel.c for dynamic streams uses
a data pointer and a length for passing PDUs or PDU fragments. We
replace this with a standard stream pointer, so that the usual
facilities can be used for checking length violcations.
This commit is contained in:
matt335672
2026-08-07 11:43:19 +01:00
parent e4b0621229
commit f745c9152d
5 changed files with 46 additions and 58 deletions
+3 -3
View File
@@ -146,9 +146,9 @@ struct xrdp_drdynvc
int (*open_response)(struct xrdp_process *id, int chan_id,
int creation_status);
int (*close_response)(struct xrdp_process *id, int chan_id);
int (*data_first)(struct xrdp_process *id, int chan_id, char *data,
int bytes, int total_bytes);
int (*data)(struct xrdp_process *id, int chan_id, char *data, int bytes);
int (*data_first)(struct xrdp_process *id, int chan_id, struct stream *s,
int total_bytes);
int (*data)(struct xrdp_process *id, int chan_id, struct stream *s);
};
struct vc_dechunker; // Forward declaration
+3 -3
View File
@@ -91,9 +91,9 @@ struct xrdp_drdynvc_procs
int (*open_response)(struct xrdp_process *id, int chan_id,
int creation_status);
int (*close_response)(struct xrdp_process *id, int chan_id);
int (*data_first)(struct xrdp_process *id, int chan_id,
char *data, int bytes, int total_bytes);
int (*data)(struct xrdp_process *id, int chan_id, char *data, int bytes);
int (*data_first)(struct xrdp_process *id, int chan_id, struct stream *s,
int total_bytes);
int (*data)(struct xrdp_process *id, int chan_id, struct stream *s);
};
/* Defined in xrdp_client_info.h */
+2 -3
View File
@@ -488,8 +488,7 @@ drdynvc_process_data_first(struct xrdp_channel *self,
drdynvc = self->drdynvcs + chan_id;
if (drdynvc->data_first != NULL)
{
return drdynvc->data_first(session->id, chan_id, s->p,
bytes, total_bytes);
return drdynvc->data_first(session->id, chan_id, s, total_bytes);
}
LOG_DEVEL(LOG_LEVEL_WARNING, "Dynamic Virtual Channel %s (%d): "
"callback 'data_first' is NULL",
@@ -530,7 +529,7 @@ drdynvc_process_data(struct xrdp_channel *self,
drdynvc = self->drdynvcs + chan_id;
if (drdynvc->data != NULL)
{
return drdynvc->data(session->id, chan_id, s->p, bytes);
return drdynvc->data(session->id, chan_id, s);
}
LOG_DEVEL(LOG_LEVEL_WARNING, "Dynamic Virtual Channel %s (%d): "
"callback 'data' is NULL",
+8 -11
View File
@@ -946,9 +946,10 @@ xrdp_egfx_close_response(struct xrdp_process *id, int chan_id)
/* from client */
static int
xrdp_egfx_data_first(struct xrdp_process *id, int chan_id,
char *data, int bytes, int total_bytes)
struct stream *s, int total_bytes)
{
struct xrdp_egfx *egfx;
int bytes = s_rem(s);
LOG(LOG_LEVEL_TRACE, "xrdp_egfx_data_first: bytes %d"
" total_bytes %d", bytes, total_bytes);
@@ -962,17 +963,16 @@ xrdp_egfx_data_first(struct xrdp_process *id, int chan_id,
make_stream(egfx->s);
// Caller has checked total_bytes is >= 0 and bytes is < total_bytes
init_stream(egfx->s, total_bytes);
out_uint8a(egfx->s, data, bytes);
out_uint8a(egfx->s, s->p, bytes);
return 0;
}
/******************************************************************************/
/* from client */
static int
xrdp_egfx_data(struct xrdp_process *id, int chan_id, char *data, int bytes)
xrdp_egfx_data(struct xrdp_process *id, int chan_id, struct stream *s)
{
int error;
struct stream ls;
struct xrdp_wm *wm;
struct xrdp_mm *mm;
struct xrdp_egfx *egfx;
@@ -1004,20 +1004,17 @@ xrdp_egfx_data(struct xrdp_process *id, int chan_id, char *data, int bytes)
if (egfx->s == NULL)
{
g_memset(&ls, 0, sizeof(ls));
ls.data = data;
ls.size = bytes;
ls.p = data;
ls.end = data + bytes;
return xrdp_egfx_process(egfx, &ls);
return xrdp_egfx_process(egfx, s);
}
int bytes = s_rem(s);
if (!s_check_rem_out(egfx->s, bytes))
{
LOG(LOG_LEVEL_ERROR, "DYNVC_DATA PDU data overflow on channel %d",
chan_id);
return 1;
}
out_uint8a(egfx->s, data, bytes);
out_uint8a(egfx->s, s->p, bytes);
if (!s_check_rem_out(egfx->s, 1))
{
s_mark_end(egfx->s);
+30 -38
View File
@@ -1047,7 +1047,7 @@ dynamic_monitor_close_response(struct xrdp_process *id, int chan_id)
/******************************************************************************/
static int
dynamic_monitor_data_first(struct xrdp_process *id, int chan_id,
char *data, int bytes, int total_bytes)
struct stream *s, int total_bytes)
{
LOG_DEVEL(LOG_LEVEL_TRACE, "dynamic_monitor_data_first:");
return 0;
@@ -1529,12 +1529,9 @@ add_resize_request_to_queue(struct xrdp_mm *self,
/******************************************************************************/
static int
dynamic_monitor_data(struct xrdp_process *id, int chan_id,
char *data, int bytes)
dynamic_monitor_data(struct xrdp_process *id, int chan_id, struct stream *s)
{
int error = 0;
struct stream ls;
struct stream *s;
int msg_type;
int msg_length;
struct xrdp_wm *wm;
@@ -1552,12 +1549,6 @@ dynamic_monitor_data(struct xrdp_process *id, int chan_id,
return error;
}
g_memset(&ls, 0, sizeof(ls));
ls.data = data;
ls.p = ls.data;
ls.size = bytes;
ls.end = ls.data + bytes;
s = &ls;
in_uint32_le(s, msg_type);
in_uint32_le(s, msg_length);
LOG_DEVEL(LOG_LEVEL_DEBUG,
@@ -2156,65 +2147,66 @@ xrdp_mm_drdynvc_close_response(struct xrdp_process *id, int chan_id)
/*****************************************************************************/
/* part data from client going to channel server */
static int
xrdp_mm_drdynvc_data_first(struct xrdp_process *id, int chan_id, char *data,
int bytes, int total_bytes)
xrdp_mm_drdynvc_data_first(struct xrdp_process *id, int chan_id,
struct stream *s, int total_bytes)
{
struct trans *trans;
struct stream *s;
struct stream *out_s;
struct xrdp_wm *wm;
int chansrv_chan_id;
int bytes = s_rem(s);
// Size of PDU sent to chansrv
int pdu_size = 8 + 8 + 4 + 4 + 4 + bytes;
wm = id->wm;
trans = wm->mm->chan_trans;
s = trans_get_out_s(trans, pdu_size);
if (s == NULL)
out_s = trans_get_out_s(trans, pdu_size);
if (out_s == NULL)
{
return 1;
}
out_uint32_le(s, 0); /* version */
out_uint32_le(s, pdu_size);
out_uint32_le(s, 17); /* msg id */
out_uint32_le(s, pdu_size - 8);
out_uint32_le(out_s, 0); /* version */
out_uint32_le(out_s, pdu_size);
out_uint32_le(out_s, 17); /* msg id */
out_uint32_le(out_s, pdu_size - 8);
chansrv_chan_id = wm->mm->xr2cr_cid_map[chan_id];
out_uint32_le(s, chansrv_chan_id);
out_uint32_le(s, bytes);
out_uint32_le(s, total_bytes);
out_uint8a(s, data, bytes);
s_mark_end(s);
out_uint32_le(out_s, chansrv_chan_id);
out_uint32_le(out_s, bytes);
out_uint32_le(out_s, total_bytes);
out_uint8p(out_s, s->p, bytes);
s_mark_end(out_s);
return trans_write_copy(trans);
}
/*****************************************************************************/
/* data from client going to channel server */
static int
xrdp_mm_drdynvc_data(struct xrdp_process *id, int chan_id,
char *data, int bytes)
xrdp_mm_drdynvc_data(struct xrdp_process *id, int chan_id, struct stream *s)
{
struct trans *trans;
struct stream *s;
struct stream *out_s;
struct xrdp_wm *wm;
int chansrv_chan_id;
int bytes = s_rem(s);
// Size of PDU sent to chansrv
int pdu_size = 8 + 8 + 4 + 4 + bytes;
wm = id->wm;
trans = wm->mm->chan_trans;
s = trans_get_out_s(trans, pdu_size);
if (s == NULL)
out_s = trans_get_out_s(trans, pdu_size);
if (out_s == NULL)
{
return 1;
}
out_uint32_le(s, 0); /* version */
out_uint32_le(s, pdu_size);
out_uint32_le(s, 19); /* msg id */
out_uint32_le(s, pdu_size - 8);
out_uint32_le(out_s, 0); /* version */
out_uint32_le(out_s, pdu_size);
out_uint32_le(out_s, 19); /* msg id */
out_uint32_le(out_s, pdu_size - 8);
chansrv_chan_id = wm->mm->xr2cr_cid_map[chan_id];
out_uint32_le(s, chansrv_chan_id);
out_uint32_le(s, bytes);
out_uint8a(s, data, bytes);
s_mark_end(s);
out_uint32_le(out_s, chansrv_chan_id);
out_uint32_le(out_s, bytes);
out_uint8p(out_s, s->p, bytes);
s_mark_end(out_s);
return trans_write_copy(trans);
}