summaryrefslogtreecommitdiffstats
path: root/libxrdp/xrdp_rdp.c
diff options
context:
space:
mode:
authorLaxmikant Rashinkar <LK.Rashinkar@gmail.com>2013-09-24 17:19:43 -0700
committerLaxmikant Rashinkar <LK.Rashinkar@gmail.com>2013-09-24 17:19:43 -0700
commit06f01f6c37856ce00930ca3dcbaa9fdfb0c4d72b (patch)
tree88ceac43251b4a3beb88be4a812f067a480efaec /libxrdp/xrdp_rdp.c
parent379685bfcaa4dffd707b932574c99f0bab33b83e (diff)
parent675e1b86c44d6b75032ec4cb40f4ccfb8cd06358 (diff)
downloadxrdp-proprietary-06f01f6c37856ce00930ca3dcbaa9fdfb0c4d72b.tar.gz
xrdp-proprietary-06f01f6c37856ce00930ca3dcbaa9fdfb0c4d72b.zip
Merge branch 'master' of github.com:neutrinolabs/xrdp
Diffstat (limited to 'libxrdp/xrdp_rdp.c')
-rw-r--r--libxrdp/xrdp_rdp.c128
1 files changed, 111 insertions, 17 deletions
diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c
index 2d90485f..214202f5 100644
--- a/libxrdp/xrdp_rdp.c
+++ b/libxrdp/xrdp_rdp.c
@@ -514,6 +514,11 @@ xrdp_rdp_parse_client_mcs_data(struct xrdp_rdp *self)
p = &(self->sec_layer->client_mcs_data);
p->p = p->data;
+ if (!s_check_rem(p, 31 + 2 + 2 + 120 + 2))
+ {
+ g_writeln("xrdp_rdp_parse_client_mcs_data: error");
+ return 1;
+ }
in_uint8s(p, 31);
in_uint16_le(p, self->client_info.width);
in_uint16_le(p, self->client_info.height);
@@ -524,6 +529,10 @@ xrdp_rdp_parse_client_mcs_data(struct xrdp_rdp *self)
switch (i)
{
case 0xca01:
+ if (!s_check_rem(p, 6 + 1))
+ {
+ return 1;
+ }
in_uint8s(p, 6);
in_uint8(p, i);
@@ -837,6 +846,11 @@ xrdp_process_capset_general(struct xrdp_rdp *self, struct stream *s,
{
int i;
+ if (len < 10 + 2)
+ {
+ g_writeln("xrdp_process_capset_general: error");
+ return 1;
+ }
in_uint8s(s, 10);
in_uint16_le(s, i);
/* use_compact_packets is pretty much 'use rdp5' */
@@ -858,6 +872,11 @@ xrdp_process_capset_order(struct xrdp_rdp *self, struct stream *s,
int cap_flags;
DEBUG(("order capabilities"));
+ if (len < 20 + 2 + 2 + 2 + 2 + 2 + 2 + 32 + 2 + 2 + 4 + 4 + 4 + 4)
+ {
+ g_writeln("xrdp_process_capset_order: error");
+ return 1;
+ }
in_uint8s(s, 20); /* Terminal desc, pad */
in_uint8s(s, 2); /* Cache X granularity */
in_uint8s(s, 2); /* Cache Y granularity */
@@ -915,13 +934,32 @@ static int APP_CC
xrdp_process_capset_bmpcache(struct xrdp_rdp *self, struct stream *s,
int len)
{
+ int i;
+
+ if (len < 24 + 2 + 2 + 2 + 2 + 2 + 2)
+ {
+ g_writeln("xrdp_process_capset_bmpcache: error");
+ return 1;
+ }
self->client_info.bitmap_cache_version |= 1;
in_uint8s(s, 24);
- in_uint16_le(s, self->client_info.cache1_entries);
+ /* cache 1 */
+ in_uint16_le(s, i);
+ i = MIN(i, XRDP_MAX_BITMAP_CACHE_IDX);
+ i = MAX(i, 0);
+ self->client_info.cache1_entries = i;
in_uint16_le(s, self->client_info.cache1_size);
- in_uint16_le(s, self->client_info.cache2_entries);
+ /* cache 2 */
+ in_uint16_le(s, i);
+ i = MIN(i, XRDP_MAX_BITMAP_CACHE_IDX);
+ i = MAX(i, 0);
+ self->client_info.cache2_entries = i;
in_uint16_le(s, self->client_info.cache2_size);
- in_uint16_le(s, self->client_info.cache3_entries);
+ /* caceh 3 */
+ in_uint16_le(s, i);
+ i = MIN(i, XRDP_MAX_BITMAP_CACHE_IDX);
+ i = MAX(i, 0);
+ self->client_info.cache3_entries = i;
in_uint16_le(s, self->client_info.cache3_size);
DEBUG(("cache1 entries %d size %d", self->client_info.cache1_entries,
self->client_info.cache1_size));
@@ -941,22 +979,30 @@ xrdp_process_capset_bmpcache2(struct xrdp_rdp *self, struct stream *s,
int Bpp = 0;
int i = 0;
+ if (len < 2 + 2 + 4 + 4 + 4)
+ {
+ g_writeln("xrdp_process_capset_bmpcache2: error");
+ return 1;
+ }
self->client_info.bitmap_cache_version |= 2;
Bpp = (self->client_info.bpp + 7) / 8;
in_uint16_le(s, i); /* cache flags */
self->client_info.bitmap_cache_persist_enable = i;
in_uint8s(s, 2); /* number of caches in set, 3 */
in_uint32_le(s, i);
- i = MIN(i, 2000);
+ i = MIN(i, XRDP_MAX_BITMAP_CACHE_IDX);
+ i = MAX(i, 0);
self->client_info.cache1_entries = i;
self->client_info.cache1_size = 256 * Bpp;
in_uint32_le(s, i);
- i = MIN(i, 2000);
+ i = MIN(i, XRDP_MAX_BITMAP_CACHE_IDX);
+ i = MAX(i, 0);
self->client_info.cache2_entries = i;
self->client_info.cache2_size = 1024 * Bpp;
in_uint32_le(s, i);
i = i & 0x7fffffff;
- i = MIN(i, 2000);
+ i = MIN(i, XRDP_MAX_BITMAP_CACHE_IDX);
+ i = MAX(i, 0);
self->client_info.cache3_entries = i;
self->client_info.cache3_size = 4096 * Bpp;
DEBUG(("cache1 entries %d size %d", self->client_info.cache1_entries,
@@ -975,6 +1021,11 @@ xrdp_process_capset_cache_v3_codec_id(struct xrdp_rdp *self, struct stream *s,
{
int codec_id;
+ if (len < 1)
+ {
+ g_writeln("xrdp_process_capset_cache_v3_codec_id: error");
+ return 1;
+ }
in_uint8(s, codec_id);
g_writeln("xrdp_process_capset_cache_v3_codec_id: cache_v3_codec_id %d",
codec_id);
@@ -992,6 +1043,11 @@ xrdp_process_capset_pointercache(struct xrdp_rdp *self, struct stream *s,
int colorPointerFlag;
int no_new_cursor;
+ if (len < 2 + 2 + 2)
+ {
+ g_writeln("xrdp_process_capset_pointercache: error");
+ return 1;
+ }
no_new_cursor = self->client_info.pointer_flags & 2;
in_uint16_le(s, colorPointerFlag);
self->client_info.pointer_flags = colorPointerFlag;
@@ -1028,6 +1084,11 @@ xrdp_process_capset_brushcache(struct xrdp_rdp *self, struct stream *s,
{
int code;
+ if (len < 4)
+ {
+ g_writeln("xrdp_process_capset_brushcache: error");
+ return 1;
+ }
in_uint32_le(s, code);
self->client_info.brush_cache_code = code;
return 0;
@@ -1040,12 +1101,11 @@ xrdp_process_offscreen_bmpcache(struct xrdp_rdp *self, struct stream *s,
{
int i32;
- if (len - 4 < 8)
+ if (len < 4 + 2 + 2)
{
- g_writeln("xrdp_process_offscreen_bmpcache: bad len");
+ g_writeln("xrdp_process_offscreen_bmpcache: error");
return 1;
}
-
in_uint32_le(s, i32);
self->client_info.offscreen_support_level = i32;
in_uint16_le(s, i32);
@@ -1066,12 +1126,11 @@ xrdp_process_capset_rail(struct xrdp_rdp *self, struct stream *s, int len)
{
int i32;
- if (len - 4 < 4)
+ if (len < 4)
{
- g_writeln("xrdp_process_capset_rail: bad len");
+ g_writeln("xrdp_process_capset_rail: error");
return 1;
}
-
in_uint32_le(s, i32);
self->client_info.rail_support_level = i32;
g_writeln("xrdp_process_capset_rail: rail_support_level %d",
@@ -1085,12 +1144,11 @@ xrdp_process_capset_window(struct xrdp_rdp *self, struct stream *s, int len)
{
int i32;
- if (len - 4 < 7)
+ if (len < 4 + 1 + 2)
{
- g_writeln("xrdp_process_capset_window: bad len");
+ g_writeln("xrdp_process_capset_window: error");
return 1;
}
-
in_uint32_le(s, i32);
self->client_info.wnd_support_level = i32;
in_uint8(s, i32);
@@ -1117,14 +1175,32 @@ xrdp_process_capset_codecs(struct xrdp_rdp *self, struct stream *s, int len)
char *codec_guid;
char *next_guid;
+ if (len < 1)
+ {
+ g_writeln("xrdp_process_capset_codecs: error");
+ return 1;
+ }
in_uint8(s, codec_count);
+ len--;
for (index = 0; index < codec_count; index++)
{
codec_guid = s->p;
+ if (len < 16 + 1 + 2)
+ {
+ g_writeln("xrdp_process_capset_codecs: error");
+ return 1;
+ }
in_uint8s(s, 16);
in_uint8(s, codec_id);
in_uint16_le(s, codec_properties_length);
+ len -= 16 + 1 + 2;
+ if (len < codec_properties_length)
+ {
+ g_writeln("xrdp_process_capset_codecs: error");
+ return 1;
+ }
+ len -= codec_properties_length;
next_guid = s->p + codec_properties_length;
if (g_memcmp(codec_guid, XR_CODEC_GUID_NSCODEC, 16) == 0)
@@ -1190,9 +1266,19 @@ xrdp_rdp_process_confirm_active(struct xrdp_rdp *self, struct stream *s)
for (index = 0; index < num_caps; index++)
{
p = s->p;
+ if (!s_check_rem(s, 4))
+ {
+ g_writeln("xrdp_rdp_process_confirm_active: error 1");
+ return 1;
+ }
in_uint16_le(s, type);
in_uint16_le(s, len);
-
+ if ((len < 4) || !s_check_rem(s, len - 4))
+ {
+ g_writeln("xrdp_rdp_process_confirm_active: error len %d", len, s->end - s->p);
+ return 1;
+ }
+ len -= 4;
switch (type)
{
case RDP_CAPSET_GENERAL: /* 1 */
@@ -1278,7 +1364,7 @@ xrdp_rdp_process_confirm_active(struct xrdp_rdp *self, struct stream *s)
break;
}
- s->p = p + len;
+ s->p = p + len + 4;
}
DEBUG(("out xrdp_rdp_process_confirm_active"));
@@ -1305,12 +1391,20 @@ xrdp_rdp_process_data_input(struct xrdp_rdp *self, struct stream *s)
int param2;
int time;
+ if (!s_check_rem(s, 4))
+ {
+ return 1;
+ }
in_uint16_le(s, num_events);
in_uint8s(s, 2); /* pad */
DEBUG(("in xrdp_rdp_process_data_input %d events", num_events));
for (index = 0; index < num_events; index++)
{
+ if (!s_check_rem(s, 12))
+ {
+ return 1;
+ }
in_uint32_le(s, time);
in_uint16_le(s, msg_type);
in_uint16_le(s, device_flags);