Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/neutrinolabs/xrdp.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJay Sorg <jay.sorg@gmail.com>2013-09-05 23:56:12 +0400
committerJay Sorg <jay.sorg@gmail.com>2013-09-13 00:39:30 +0400
commit0bc3ee2cd7a4948007d4bea02c077c2bc23896d5 (patch)
treeb7350391e770e7fa10455e9de23aef3a743749a8
parent6504737b11ae763f9aa06fa55856440b1c86ef44 (diff)
VUL: fix some possible buffer overruns
Conflicts: libxrdp/xrdp_mcs.c
-rw-r--r--common/parse.h3
-rw-r--r--common/trans.c5
-rw-r--r--libxrdp/xrdp_iso.c16
-rw-r--r--libxrdp/xrdp_mcs.c83
-rw-r--r--libxrdp/xrdp_sec.c44
5 files changed, 146 insertions, 5 deletions
diff --git a/common/parse.h b/common/parse.h
index 9bd6850c..41cfa698 100644
--- a/common/parse.h
+++ b/common/parse.h
@@ -60,6 +60,9 @@ struct stream
#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)
/******************************************************************************/
diff --git a/common/trans.c b/common/trans.c
index 6b762d00..38dba51e 100644
--- a/common/trans.c
+++ b/common/trans.c
@@ -202,6 +202,11 @@ trans_force_read_s(struct trans* self, struct stream* in_s, int size)
}
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);
if (rcvd == -1)
{
diff --git a/libxrdp/xrdp_iso.c b/libxrdp/xrdp_iso.c
index 7fee92e6..983bfb9a 100644
--- a/libxrdp/xrdp_iso.c
+++ b/libxrdp/xrdp_iso.c
@@ -68,18 +68,34 @@ xrdp_iso_recv_msg(struct xrdp_iso* self, struct stream* s, int* code)
}
in_uint8s(s, 1);
in_uint16_be(s, len);
+ if (len < 4)
+ {
+ return 1;
+ }
if (xrdp_tcp_recv(self->tcp_layer, s, len - 4) != 0)
{
return 1;
}
+ if (!s_check_rem(s, 2))
+ {
+ return 1;
+ }
in_uint8s(s, 1);
in_uint8(s, *code);
if (*code == ISO_PDU_DT)
{
+ if (!s_check_rem(s, 1))
+ {
+ return 1;
+ }
in_uint8s(s, 1);
}
else
{
+ if (!s_check_rem(s, 5))
+ {
+ return 1;
+ }
in_uint8s(s, 5);
}
return 0;
diff --git a/libxrdp/xrdp_mcs.c b/libxrdp/xrdp_mcs.c
index 618a3433..304034d1 100644
--- a/libxrdp/xrdp_mcs.c
+++ b/libxrdp/xrdp_mcs.c
@@ -124,6 +124,10 @@ xrdp_mcs_recv(struct xrdp_mcs* self, struct stream* s, int* chan)
DEBUG((" out xrdp_mcs_recv xrdp_iso_recv returned non zero"));
return 1;
}
+ if (!s_check_rem(s, 1))
+ {
+ return 1;
+ }
in_uint8(s, opcode);
appid = opcode >> 2;
if (appid == MCS_DPUM) /* Disconnect Provider Ultimatum */
@@ -136,6 +140,10 @@ xrdp_mcs_recv(struct xrdp_mcs* self, struct stream* s, int* chan)
if (appid == MCS_CJRQ)
{
g_writeln("channel join request received");
+ if (!s_check_rem(s, 4))
+ {
+ return 1;
+ }
in_uint16_be(s, userid);
in_uint16_be(s, chanid);
DEBUG(("xrdp_mcs_recv adding channel %4.4x", chanid));
@@ -160,12 +168,20 @@ xrdp_mcs_recv(struct xrdp_mcs* self, struct stream* s, int* chan)
DEBUG((" out xrdp_mcs_recv err got 0x%x need MCS_SDRQ", appid));
return 1;
}
+ if (!s_check_rem(s, 6))
+ {
+ return 1;
+ }
in_uint8s(s, 2);
in_uint16_be(s, *chan);
in_uint8s(s, 1);
in_uint8(s, len);
if (len & 0x80)
{
+ if (!s_check_rem(s, 1))
+ {
+ return 1;
+ }
in_uint8s(s, 1);
}
DEBUG((" out xrdp_mcs_recv"));
@@ -184,16 +200,28 @@ xrdp_mcs_ber_parse_header(struct xrdp_mcs* self, struct stream* s,
if (tag_val > 0xff)
{
+ if (!s_check_rem(s, 2))
+ {
+ return 1;
+ }
in_uint16_be(s, tag);
}
else
{
+ if (!s_check_rem(s, 1))
+ {
+ return 1;
+ }
in_uint8(s, tag);
}
if (tag != tag_val)
{
return 1;
}
+ if (!s_check_rem(s, 1))
+ {
+ return 1;
+ }
in_uint8(s, l);
if (l & 0x80)
{
@@ -201,6 +229,10 @@ xrdp_mcs_ber_parse_header(struct xrdp_mcs* self, struct stream* s,
*len = 0;
while (l > 0)
{
+ if (!s_check_rem(s, 1))
+ {
+ return 1;
+ }
in_uint8(s, i);
*len = (*len << 8) | i;
l--;
@@ -231,6 +263,10 @@ xrdp_mcs_parse_domain_params(struct xrdp_mcs* self, struct stream* s)
{
return 1;
}
+ if (!s_check_rem(s, len))
+ {
+ return 1;
+ }
in_uint8s(s, len);
if (s_check(s))
{
@@ -251,7 +287,7 @@ xrdp_mcs_recv_connect_initial(struct xrdp_mcs* self)
struct stream* s;
make_stream(s);
- init_stream(s, 8192);
+ init_stream(s, 16 * 1024);
if (xrdp_iso_recv(self->iso_layer, s) != 0)
{
free_stream(s);
@@ -300,6 +336,11 @@ xrdp_mcs_recv_connect_initial(struct xrdp_mcs* self)
free_stream(s);
return 1;
}
+ if ((len <= 0) || (len > 16 * 1024))
+ {
+ free_stream(s);
+ return 1;
+ }
/* make a copy of client mcs data */
init_stream(self->client_mcs_data, len);
out_uint8a(self->client_mcs_data, s->p, len);
@@ -332,16 +373,31 @@ xrdp_mcs_recv_edrq(struct xrdp_mcs* self)
free_stream(s);
return 1;
}
+ if (!s_check_rem(s, 1))
+ {
+ free_stream(s);
+ return 1;
+ }
in_uint8(s, opcode);
if ((opcode >> 2) != MCS_EDRQ)
{
free_stream(s);
return 1;
}
+ if (!s_check_rem(s, 4))
+ {
+ free_stream(s);
+ return 1;
+ }
in_uint8s(s, 2);
in_uint8s(s, 2);
if (opcode & 2)
{
+ if (!s_check_rem(s, 2))
+ {
+ free_stream(s);
+ return 1;
+ }
in_uint16_be(s, self->userid);
}
if (!(s_check_end(s)))
@@ -368,6 +424,11 @@ xrdp_mcs_recv_aurq(struct xrdp_mcs* self)
free_stream(s);
return 1;
}
+ if (!s_check_rem(s, 1))
+ {
+ free_stream(s);
+ return 1;
+ }
in_uint8(s, opcode);
if ((opcode >> 2) != MCS_AURQ)
{
@@ -376,6 +437,11 @@ xrdp_mcs_recv_aurq(struct xrdp_mcs* self)
}
if (opcode & 2)
{
+ if (!s_check_rem(s, 2))
+ {
+ free_stream(s);
+ return 1;
+ }
in_uint16_be(s, self->userid);
}
if (!(s_check_end(s)))
@@ -433,15 +499,30 @@ xrdp_mcs_recv_cjrq(struct xrdp_mcs* self)
free_stream(s);
return 1;
}
+ if (!s_check_rem(s, 1))
+ {
+ free_stream(s);
+ return 1;
+ }
in_uint8(s, opcode);
if ((opcode >> 2) != MCS_CJRQ)
{
free_stream(s);
return 1;
}
+ if (!s_check_rem(s, 4))
+ {
+ free_stream(s);
+ return 1;
+ }
in_uint8s(s, 4);
if (opcode & 2)
{
+ if (!s_check_rem(s, 2))
+ {
+ free_stream(s);
+ return 1;
+ }
in_uint8s(s, 2);
}
if (!(s_check_end(s)))
diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c
index 381e8435..426816cb 100644
--- a/libxrdp/xrdp_sec.c
+++ b/libxrdp/xrdp_sec.c
@@ -739,15 +739,27 @@ xrdp_sec_process_mcs_data_channels(struct xrdp_sec* self, struct stream* s)
g_writeln("Processing channel data from client - The channel is off");
return 0;
}
+ if (!s_check_rem(s, 4))
+ {
+ return 1;
+ }
in_uint32_le(s, num_channels);
+ if (num_channels > 256)
+ {
+ return 1;
+ }
for (index = 0; index < num_channels; index++)
{
channel_item = (struct mcs_channel_item*)
g_malloc(sizeof(struct mcs_channel_item), 1);
+ if (!s_check_rem(s, 12))
+ {
+ return 1;
+ }
in_uint8a(s, channel_item->name, 8);
in_uint32_le(s, channel_item->flags);
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,
channel_item->name));
}
@@ -765,10 +777,14 @@ xrdp_sec_process_mcs_data(struct xrdp_sec* self)
int tag = 0;
int size = 0;
- s = &self->client_mcs_data;
+ s = &(self->client_mcs_data);
/* set p to beginning */
s->p = s->data;
/* skip header */
+ if (!s_check_rem(s, 23))
+ {
+ return 1;
+ }
in_uint8s(s, 23);
while (s_check_rem(s, 4))
{
@@ -893,7 +909,7 @@ xrdp_sec_out_mcs_data(struct xrdp_sec* self)
/*****************************************************************************/
/* 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)
{
struct stream* s = (struct stream *)NULL;
@@ -905,12 +921,20 @@ xrdp_sec_in_mcs_data(struct xrdp_sec* self)
s = &(self->client_mcs_data);
/* get hostname, its unicode */
s->p = s->data;
+ if (!s_check_rem(s, 47))
+ {
+ return 1;
+ }
in_uint8s(s, 47);
g_memset(client_info->hostname, 0, 32);
c = 1;
index = 0;
while (index < 16 && c != 0)
{
+ if (!s_check_rem(s, 2))
+ {
+ return 1;
+ }
in_uint8(s, c);
in_uint8s(s, 1);
client_info->hostname[index] = c;
@@ -918,13 +942,22 @@ xrdp_sec_in_mcs_data(struct xrdp_sec* self)
}
/* get build */
s->p = s->data;
+ if (!s_check_rem(s, 43 + 4))
+ {
+ return 1;
+ }
in_uint8s(s, 43);
in_uint32_le(s, client_info->build);
/* get keylayout */
s->p = s->data;
+ if (!s_check_rem(s, 39 + 4))
+ {
+ return 1;
+ }
in_uint8s(s, 39);
in_uint32_le(s, client_info->keylayout);
s->p = s->data;
+ return 0;
}
/*****************************************************************************/
@@ -991,7 +1024,10 @@ xrdp_sec_incoming(struct xrdp_sec* self)
(int)(self->server_mcs_data.end - self->server_mcs_data.data));
#endif
DEBUG((" out xrdp_sec_incoming"));
- xrdp_sec_in_mcs_data(self);
+ if (xrdp_sec_in_mcs_data(self) != 0)
+ {
+ return 1;
+ }
return 0;
}