mirror of https://github.com/neutrinolabs/xrdp
VUL: fix some possible buffer overruns
This commit is contained in:
parent
4e58a5a3c0
commit
39ed446e15
|
@ -55,6 +55,9 @@ struct stream
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
#define s_check_rem(s, n) ((s)->p + (n) <= (s)->end)
|
#define s_check_rem(s, n) ((s)->p + (n) <= (s)->end)
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
#define s_check_rem_out(s, n) ((s)->p + (n) <= (s)->data + (s)->size)
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
#define s_check_end(s) ((s)->p == (s)->end)
|
#define s_check_end(s) ((s)->p == (s)->end)
|
||||||
|
|
||||||
|
|
|
@ -221,8 +221,12 @@ trans_force_read_s(struct trans *self, struct stream *in_s, int size)
|
||||||
|
|
||||||
while (size > 0)
|
while (size > 0)
|
||||||
{
|
{
|
||||||
|
/* make sure stream has room */
|
||||||
|
if ((in_s->end + size) > (in_s->data + in_s->size))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
rcvd = g_tcp_recv(self->sck, in_s->end, size, 0);
|
rcvd = g_tcp_recv(self->sck, in_s->end, size, 0);
|
||||||
|
|
||||||
if (rcvd == -1)
|
if (rcvd == -1)
|
||||||
{
|
{
|
||||||
if (g_tcp_last_error_would_block(self->sck))
|
if (g_tcp_last_error_would_block(self->sck))
|
||||||
|
|
|
@ -72,20 +72,38 @@ xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code)
|
||||||
in_uint8s(s, 1);
|
in_uint8s(s, 1);
|
||||||
in_uint16_be(s, len);
|
in_uint16_be(s, len);
|
||||||
|
|
||||||
|
if (len < 4)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (xrdp_tcp_recv(self->tcp_layer, s, len - 4) != 0)
|
if (xrdp_tcp_recv(self->tcp_layer, s, len - 4) != 0)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!s_check_rem(s, 2))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
in_uint8s(s, 1);
|
in_uint8s(s, 1);
|
||||||
in_uint8(s, *code);
|
in_uint8(s, *code);
|
||||||
|
|
||||||
if (*code == ISO_PDU_DT)
|
if (*code == ISO_PDU_DT)
|
||||||
{
|
{
|
||||||
|
if (!s_check_rem(s, 1))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
in_uint8s(s, 1);
|
in_uint8s(s, 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (!s_check_rem(s, 5))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
in_uint8s(s, 5);
|
in_uint8s(s, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -132,6 +132,11 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!s_check_rem(s, 1))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
in_uint8(s, opcode);
|
in_uint8(s, opcode);
|
||||||
appid = opcode >> 2;
|
appid = opcode >> 2;
|
||||||
|
|
||||||
|
@ -145,6 +150,11 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan)
|
||||||
/* this is channels getting added from the client */
|
/* this is channels getting added from the client */
|
||||||
if (appid == MCS_CJRQ)
|
if (appid == MCS_CJRQ)
|
||||||
{
|
{
|
||||||
|
if (!s_check_rem(s, 4))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
in_uint16_be(s, userid);
|
in_uint16_be(s, userid);
|
||||||
in_uint16_be(s, chanid);
|
in_uint16_be(s, chanid);
|
||||||
log_message(LOG_LEVEL_DEBUG,"MCS_CJRQ - channel join request received");
|
log_message(LOG_LEVEL_DEBUG,"MCS_CJRQ - channel join request received");
|
||||||
|
@ -176,6 +186,11 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!s_check_rem(s, 6))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
in_uint8s(s, 2);
|
in_uint8s(s, 2);
|
||||||
in_uint16_be(s, *chan);
|
in_uint16_be(s, *chan);
|
||||||
in_uint8s(s, 1);
|
in_uint8s(s, 1);
|
||||||
|
@ -183,6 +198,10 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan)
|
||||||
|
|
||||||
if (len & 0x80)
|
if (len & 0x80)
|
||||||
{
|
{
|
||||||
|
if (!s_check_rem(s, 1))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
in_uint8s(s, 1);
|
in_uint8s(s, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,10 +221,18 @@ xrdp_mcs_ber_parse_header(struct xrdp_mcs *self, struct stream *s,
|
||||||
|
|
||||||
if (tag_val > 0xff)
|
if (tag_val > 0xff)
|
||||||
{
|
{
|
||||||
|
if (!s_check_rem(s, 2))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
in_uint16_be(s, tag);
|
in_uint16_be(s, tag);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (!s_check_rem(s, 1))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
in_uint8(s, tag);
|
in_uint8(s, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,6 +241,11 @@ xrdp_mcs_ber_parse_header(struct xrdp_mcs *self, struct stream *s,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!s_check_rem(s, 1))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
in_uint8(s, l);
|
in_uint8(s, l);
|
||||||
|
|
||||||
if (l & 0x80)
|
if (l & 0x80)
|
||||||
|
@ -223,6 +255,10 @@ xrdp_mcs_ber_parse_header(struct xrdp_mcs *self, struct stream *s,
|
||||||
|
|
||||||
while (l > 0)
|
while (l > 0)
|
||||||
{
|
{
|
||||||
|
if (!s_check_rem(s, 1))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
in_uint8(s, i);
|
in_uint8(s, i);
|
||||||
*len = (*len << 8) | i;
|
*len = (*len << 8) | i;
|
||||||
l--;
|
l--;
|
||||||
|
@ -255,6 +291,11 @@ xrdp_mcs_parse_domain_params(struct xrdp_mcs *self, struct stream *s)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!s_check_rem(s, len))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
in_uint8s(s, len);
|
in_uint8s(s, len);
|
||||||
|
|
||||||
if (s_check(s))
|
if (s_check(s))
|
||||||
|
@ -276,7 +317,7 @@ xrdp_mcs_recv_connect_initial(struct xrdp_mcs *self)
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
|
|
||||||
make_stream(s);
|
make_stream(s);
|
||||||
init_stream(s, 8192);
|
init_stream(s, 16 * 1024);
|
||||||
|
|
||||||
if (xrdp_iso_recv(self->iso_layer, s) != 0)
|
if (xrdp_iso_recv(self->iso_layer, s) != 0)
|
||||||
{
|
{
|
||||||
|
@ -338,6 +379,12 @@ xrdp_mcs_recv_connect_initial(struct xrdp_mcs *self)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((len <= 0) || (len > 16 * 1024))
|
||||||
|
{
|
||||||
|
free_stream(s);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* make a copy of client mcs data */
|
/* make a copy of client mcs data */
|
||||||
init_stream(self->client_mcs_data, len);
|
init_stream(self->client_mcs_data, len);
|
||||||
out_uint8a(self->client_mcs_data, s->p, len);
|
out_uint8a(self->client_mcs_data, s->p, len);
|
||||||
|
@ -372,6 +419,12 @@ xrdp_mcs_recv_edrq(struct xrdp_mcs *self)
|
||||||
free_stream(s);
|
free_stream(s);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!s_check_rem(s, 1))
|
||||||
|
{
|
||||||
|
free_stream(s);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
in_uint8(s, opcode);
|
in_uint8(s, opcode);
|
||||||
|
|
||||||
|
@ -381,11 +434,22 @@ xrdp_mcs_recv_edrq(struct xrdp_mcs *self)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!s_check_rem(s, 4))
|
||||||
|
{
|
||||||
|
free_stream(s);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
in_uint8s(s, 2);
|
in_uint8s(s, 2);
|
||||||
in_uint8s(s, 2);
|
in_uint8s(s, 2);
|
||||||
|
|
||||||
if (opcode & 2)
|
if (opcode & 2)
|
||||||
{
|
{
|
||||||
|
if (!s_check_rem(s, 2))
|
||||||
|
{
|
||||||
|
free_stream(s);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
in_uint16_be(s, self->userid);
|
in_uint16_be(s, self->userid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,6 +480,12 @@ xrdp_mcs_recv_aurq(struct xrdp_mcs *self)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!s_check_rem(s, 1))
|
||||||
|
{
|
||||||
|
free_stream(s);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
in_uint8(s, opcode);
|
in_uint8(s, opcode);
|
||||||
|
|
||||||
if ((opcode >> 2) != MCS_AURQ)
|
if ((opcode >> 2) != MCS_AURQ)
|
||||||
|
@ -426,6 +496,11 @@ xrdp_mcs_recv_aurq(struct xrdp_mcs *self)
|
||||||
|
|
||||||
if (opcode & 2)
|
if (opcode & 2)
|
||||||
{
|
{
|
||||||
|
if (!s_check_rem(s, 2))
|
||||||
|
{
|
||||||
|
free_stream(s);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
in_uint16_be(s, self->userid);
|
in_uint16_be(s, self->userid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -491,6 +566,12 @@ xrdp_mcs_recv_cjrq(struct xrdp_mcs *self)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!s_check_rem(s, 1))
|
||||||
|
{
|
||||||
|
free_stream(s);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
in_uint8(s, opcode);
|
in_uint8(s, opcode);
|
||||||
|
|
||||||
if ((opcode >> 2) != MCS_CJRQ)
|
if ((opcode >> 2) != MCS_CJRQ)
|
||||||
|
@ -499,6 +580,12 @@ xrdp_mcs_recv_cjrq(struct xrdp_mcs *self)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!s_check_rem(s, 4))
|
||||||
|
{
|
||||||
|
free_stream(s);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
in_uint8s(s, 4);
|
in_uint8s(s, 4);
|
||||||
|
|
||||||
if (opcode & 2)
|
if (opcode & 2)
|
||||||
|
|
|
@ -836,16 +836,30 @@ xrdp_sec_process_mcs_data_channels(struct xrdp_sec *self, struct stream *s)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!s_check_rem(s, 4))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
in_uint32_le(s, num_channels);
|
in_uint32_le(s, num_channels);
|
||||||
|
|
||||||
|
if (num_channels > 256)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
for (index = 0; index < num_channels; index++)
|
for (index = 0; index < num_channels; index++)
|
||||||
{
|
{
|
||||||
channel_item = (struct mcs_channel_item *)
|
channel_item = (struct mcs_channel_item *)
|
||||||
g_malloc(sizeof(struct mcs_channel_item), 1);
|
g_malloc(sizeof(struct mcs_channel_item), 1);
|
||||||
|
if (!s_check_rem(s, 12))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
in_uint8a(s, channel_item->name, 8);
|
in_uint8a(s, channel_item->name, 8);
|
||||||
in_uint32_le(s, channel_item->flags);
|
in_uint32_le(s, channel_item->flags);
|
||||||
channel_item->chanid = MCS_GLOBAL_CHANNEL + (index + 1);
|
channel_item->chanid = MCS_GLOBAL_CHANNEL + (index + 1);
|
||||||
list_add_item(self->mcs_layer->channel_list, (long)channel_item);
|
list_add_item(self->mcs_layer->channel_list, (tintptr)channel_item);
|
||||||
DEBUG(("got channel flags %8.8x name %s", channel_item->flags,
|
DEBUG(("got channel flags %8.8x name %s", channel_item->flags,
|
||||||
channel_item->name));
|
channel_item->name));
|
||||||
}
|
}
|
||||||
|
@ -864,10 +878,14 @@ xrdp_sec_process_mcs_data(struct xrdp_sec *self)
|
||||||
int tag = 0;
|
int tag = 0;
|
||||||
int size = 0;
|
int size = 0;
|
||||||
|
|
||||||
s = &self->client_mcs_data;
|
s = &(self->client_mcs_data);
|
||||||
/* set p to beginning */
|
/* set p to beginning */
|
||||||
s->p = s->data;
|
s->p = s->data;
|
||||||
/* skip header */
|
/* skip header */
|
||||||
|
if (!s_check_rem(s, 23))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
in_uint8s(s, 23);
|
in_uint8s(s, 23);
|
||||||
|
|
||||||
while (s_check_rem(s, 4))
|
while (s_check_rem(s, 4))
|
||||||
|
@ -999,7 +1017,7 @@ xrdp_sec_out_mcs_data(struct xrdp_sec *self)
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* process the mcs client data we received from the mcs layer */
|
/* process the mcs client data we received from the mcs layer */
|
||||||
static void APP_CC
|
static int APP_CC
|
||||||
xrdp_sec_in_mcs_data(struct xrdp_sec *self)
|
xrdp_sec_in_mcs_data(struct xrdp_sec *self)
|
||||||
{
|
{
|
||||||
struct stream *s = (struct stream *)NULL;
|
struct stream *s = (struct stream *)NULL;
|
||||||
|
@ -1011,6 +1029,10 @@ xrdp_sec_in_mcs_data(struct xrdp_sec *self)
|
||||||
s = &(self->client_mcs_data);
|
s = &(self->client_mcs_data);
|
||||||
/* get hostname, its unicode */
|
/* get hostname, its unicode */
|
||||||
s->p = s->data;
|
s->p = s->data;
|
||||||
|
if (!s_check_rem(s, 47))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
in_uint8s(s, 47);
|
in_uint8s(s, 47);
|
||||||
g_memset(client_info->hostname, 0, 32);
|
g_memset(client_info->hostname, 0, 32);
|
||||||
c = 1;
|
c = 1;
|
||||||
|
@ -1018,6 +1040,10 @@ xrdp_sec_in_mcs_data(struct xrdp_sec *self)
|
||||||
|
|
||||||
while (index < 16 && c != 0)
|
while (index < 16 && c != 0)
|
||||||
{
|
{
|
||||||
|
if (!s_check_rem(s, 2))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
in_uint8(s, c);
|
in_uint8(s, c);
|
||||||
in_uint8s(s, 1);
|
in_uint8s(s, 1);
|
||||||
client_info->hostname[index] = c;
|
client_info->hostname[index] = c;
|
||||||
|
@ -1026,13 +1052,22 @@ xrdp_sec_in_mcs_data(struct xrdp_sec *self)
|
||||||
|
|
||||||
/* get build */
|
/* get build */
|
||||||
s->p = s->data;
|
s->p = s->data;
|
||||||
|
if (!s_check_rem(s, 43 + 4))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
in_uint8s(s, 43);
|
in_uint8s(s, 43);
|
||||||
in_uint32_le(s, client_info->build);
|
in_uint32_le(s, client_info->build);
|
||||||
/* get keylayout */
|
/* get keylayout */
|
||||||
s->p = s->data;
|
s->p = s->data;
|
||||||
|
if (!s_check_rem(s, 39 + 4))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
in_uint8s(s, 39);
|
in_uint8s(s, 39);
|
||||||
in_uint32_le(s, client_info->keylayout);
|
in_uint32_le(s, client_info->keylayout);
|
||||||
s->p = s->data;
|
s->p = s->data;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -1105,7 +1140,10 @@ xrdp_sec_incoming(struct xrdp_sec *self)
|
||||||
(int)(self->server_mcs_data.end - self->server_mcs_data.data));
|
(int)(self->server_mcs_data.end - self->server_mcs_data.data));
|
||||||
#endif
|
#endif
|
||||||
DEBUG((" out xrdp_sec_incoming"));
|
DEBUG((" out xrdp_sec_incoming"));
|
||||||
xrdp_sec_in_mcs_data(self);
|
if (xrdp_sec_in_mcs_data(self) != 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue