chansrv: Use streams for dynamic channel processing

Change the dynamic channel processing to use streams rather than
a data pointer and a length. This mirrors an earlier commit for
xrdp.

The reason for the change is to make it easier to check for buffer
overflows using standard stream features.
This commit is contained in:
matt335672
2026-08-10 09:53:13 +01:00
parent 63afb676e6
commit 77d9b49432
4 changed files with 37 additions and 59 deletions
+9 -15
View File
@@ -429,10 +429,10 @@ audin_close_response(int chan_id)
/*****************************************************************************/
static int
audin_data_fragment(int chan_id, char *data, int bytes)
audin_data_fragment(int chan_id, struct stream *s)
{
int rv;
int bytes = s_rem(s);
LOG_DEVEL(LOG_LEVEL_DEBUG, "audin_data_fragment:");
if (!s_check_rem(g_in_s, bytes))
{
@@ -440,7 +440,7 @@ audin_data_fragment(int chan_id, char *data, int bytes)
bytes, (int) (g_in_s->end - g_in_s->p));
return 1;
}
out_uint8a(g_in_s, data, bytes);
out_uint8a(g_in_s, s->p, bytes);
if (g_in_s->p == g_in_s->end)
{
g_in_s->p = g_in_s->data;
@@ -454,7 +454,7 @@ audin_data_fragment(int chan_id, char *data, int bytes)
/*****************************************************************************/
static int
audin_data_first(int chan_id, char *data, int bytes, int total_bytes)
audin_data_first(int chan_id, struct stream *s, int total_bytes)
{
LOG_DEVEL(LOG_LEVEL_DEBUG, "audin_data_first:");
if (g_in_s != NULL)
@@ -465,25 +465,19 @@ audin_data_first(int chan_id, char *data, int bytes, int total_bytes)
make_stream(g_in_s);
init_stream(g_in_s, total_bytes);
g_in_s->end = g_in_s->data + total_bytes;
return audin_data_fragment(chan_id, data, bytes);
return audin_data_fragment(chan_id, s);
}
/*****************************************************************************/
static int
audin_data(int chan_id, char *data, int bytes)
audin_data(int chan_id, struct stream *s)
{
struct stream ls;
LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "audin_data:", data, bytes);
LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "audin_data:", s->p, s_rem(s));
if (g_in_s == NULL)
{
g_memset(&ls, 0, sizeof(ls));
ls.data = data;
ls.p = ls.data;
ls.end = ls.p + bytes;
return audin_process_msg(chan_id, &ls);
return audin_process_msg(chan_id, s);
}
return audin_data_fragment(chan_id, data, bytes);
return audin_data_fragment(chan_id, s);
}
/*****************************************************************************/
+22 -38
View File
@@ -100,8 +100,8 @@ struct chansrv_drdynvc
int pad0;
int (*open_response)(int chan_id, int creation_status);
int (*close_response)(int chan_id);
int (*data_first)(int chan_id, char *data, int bytes, int total_bytes);
int (*data)(int chan_id, char *data, int bytes);
int (*data_first)(int chan_id, struct stream *s, int total_bytes);
int (*data)(int chan_id, struct stream *s);
struct trans *xrdp_api_trans;
};
@@ -657,32 +657,24 @@ static int
process_message_drdynvc_data_first(struct stream *s)
{
struct chansrv_drdynvc *drdynvc;
int chan_id;
int bytes;
uint32_t chan_id;
int total_bytes;
char *data;
LOG_DEVEL(LOG_LEVEL_DEBUG, "process_message_drdynvc_data_first:");
if (!s_check_rem(s, 12))
if (!s_check_rem(s, 8))
{
return 1;
}
in_uint32_le(s, chan_id);
in_uint32_le(s, bytes);
in_uint32_le(s, total_bytes);
if (!s_check_rem(s, bytes))
{
return 1;
}
in_uint8p(s, data, bytes);
if ((chan_id < 0) || (chan_id > 255))
if (chan_id > 255)
{
return 1;
}
drdynvc = g_drdynvcs + chan_id;
if (drdynvc->data_first != NULL)
{
if (drdynvc->data_first(chan_id, data, bytes, total_bytes) != 0)
if (drdynvc->data_first(chan_id, s, total_bytes) != 0)
{
return 1;
}
@@ -697,9 +689,7 @@ static int
process_message_drdynvc_data(struct stream *s)
{
struct chansrv_drdynvc *drdynvc;
int chan_id;
int bytes;
char *data;
uint32_t chan_id;
LOG_DEVEL(LOG_LEVEL_DEBUG, "process_message_drdynvc_data:");
if (!s_check_rem(s, 8))
@@ -707,16 +697,10 @@ process_message_drdynvc_data(struct stream *s)
return 1;
}
in_uint32_le(s, chan_id);
in_uint32_le(s, bytes);
if (!s_check_rem(s, bytes))
{
return 1;
}
in_uint8p(s, data, bytes);
drdynvc = g_drdynvcs + chan_id;
if (drdynvc->data != NULL)
{
if (drdynvc->data(chan_id, data, bytes) != 0)
if (drdynvc->data(chan_id, s) != 0)
{
return 1;
}
@@ -1136,24 +1120,24 @@ my_api_close_response(int chan_id)
/*****************************************************************************/
static int
my_api_data_first(int chan_id, char *data, int bytes, int total_bytes)
my_api_data_first(int chan_id, struct stream *s, int total_bytes)
{
struct trans *trans;
struct stream *s;
struct stream *out_s;
int bytes = s_rem(s);
//g_writeln("my_api_data_first: bytes %d total_bytes %d", bytes, total_bytes);
trans = get_api_trans_from_chan_id(chan_id);
if (trans == NULL)
{
return 1;
}
s = trans_get_out_s(trans, bytes);
if (s == NULL)
out_s = trans_get_out_s(trans, bytes);
if (out_s == NULL)
{
return 1;
}
out_uint8a(s, data, bytes);
s_mark_end(s);
out_uint8a(out_s, s->p, bytes);
s_mark_end(out_s);
if (trans_write_copy(trans) != 0)
{
return 1;
@@ -1163,24 +1147,24 @@ my_api_data_first(int chan_id, char *data, int bytes, int total_bytes)
/*****************************************************************************/
static int
my_api_data(int chan_id, char *data, int bytes)
my_api_data(int chan_id, struct stream *s)
{
struct trans *trans;
struct stream *s;
struct stream *out_s;
int bytes = s_rem(s);
//g_writeln("my_api_data: bytes %d", bytes);
trans = get_api_trans_from_chan_id(chan_id);
if (trans == NULL)
{
return 1;
}
s = trans_get_out_s(trans, bytes);
if (s == NULL)
out_s = trans_get_out_s(trans, bytes);
if (out_s == NULL)
{
return 1;
}
out_uint8a(s, data, bytes);
s_mark_end(s);
out_uint8a(out_s, s->p, bytes);
s_mark_end(out_s);
if (trans_write_copy(trans) != 0)
{
return 1;
+2 -2
View File
@@ -62,8 +62,8 @@ struct chansrv_drdynvc_procs
{
int (*open_response)(int chan_id, int creation_status);
int (*close_response)(int chan_id);
int (*data_first)(int chan_id, char *data, int bytes, int total_bytes);
int (*data)(int chan_id, char *data, int bytes);
int (*data_first)(int chan_id, struct stream *s, int total_bytes);
int (*data)(int chan_id, struct stream *s);
};
int