VUL: add some more buffer checks
This commit is contained in:
parent
445e7d9800
commit
6848cbbc04
@ -291,7 +291,7 @@ xrdp_mcs_parse_domain_params(struct xrdp_mcs *self, struct stream *s)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!s_check_rem(s, len))
|
||||
if ((len < 0) || !s_check_rem(s, len))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
@ -337,6 +337,12 @@ xrdp_mcs_recv_connect_initial(struct xrdp_mcs *self)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((len < 0) || !s_check_rem(s, len))
|
||||
{
|
||||
free_stream(s);
|
||||
return 1;
|
||||
}
|
||||
|
||||
in_uint8s(s, len);
|
||||
|
||||
if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_OCTET_STRING, &len) != 0)
|
||||
@ -345,6 +351,12 @@ xrdp_mcs_recv_connect_initial(struct xrdp_mcs *self)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((len < 0) || !s_check_rem(s, len))
|
||||
{
|
||||
free_stream(s);
|
||||
return 1;
|
||||
}
|
||||
|
||||
in_uint8s(s, len);
|
||||
|
||||
if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_BOOLEAN, &len) != 0)
|
||||
@ -353,6 +365,12 @@ xrdp_mcs_recv_connect_initial(struct xrdp_mcs *self)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((len < 0) || !s_check_rem(s, len))
|
||||
{
|
||||
free_stream(s);
|
||||
return 1;
|
||||
}
|
||||
|
||||
in_uint8s(s, len);
|
||||
|
||||
if (xrdp_mcs_parse_domain_params(self, s) != 0)
|
||||
@ -379,6 +397,7 @@ xrdp_mcs_recv_connect_initial(struct xrdp_mcs *self)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* mcs data can not be zero length */
|
||||
if ((len <= 0) || (len > 16 * 1024))
|
||||
{
|
||||
free_stream(s);
|
||||
@ -596,6 +615,11 @@ xrdp_mcs_recv_cjrq(struct xrdp_mcs *self)
|
||||
|
||||
if (opcode & 2)
|
||||
{
|
||||
if (!s_check_rem(s, 2))
|
||||
{
|
||||
free_stream(s);
|
||||
return 1;
|
||||
}
|
||||
in_uint8s(s, 2);
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
@ -917,6 +936,11 @@ xrdp_process_capset_bmpcache(struct xrdp_rdp *self, struct stream *s,
|
||||
{
|
||||
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);
|
||||
/* cache 1 */
|
||||
@ -955,6 +979,11 @@ 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 */
|
||||
@ -992,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);
|
||||
@ -1009,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;
|
||||
@ -1045,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;
|
||||
@ -1057,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);
|
||||
@ -1083,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",
|
||||
@ -1102,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);
|
||||
@ -1134,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)
|
||||
@ -1207,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 */
|
||||
@ -1295,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"));
|
||||
|
@ -331,12 +331,20 @@ unicode_in(struct stream *s, int uni_len, char *dst, int dst_len)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!s_check_rem(s, 2))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
in_uint8(s, dst[dst_index]);
|
||||
in_uint8s(s, 1);
|
||||
dst_index++;
|
||||
src_index += 2;
|
||||
}
|
||||
|
||||
if (!s_check_rem(s, 2))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
in_uint8s(s, 2);
|
||||
return 0;
|
||||
}
|
||||
@ -359,6 +367,10 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
|
||||
|
||||
/* initialize (zero out) local variables */
|
||||
g_memset(tmpdata, 0, sizeof(char) * 256);
|
||||
if (!s_check_rem(s, 8))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
in_uint8s(s, 4);
|
||||
in_uint32_le(s, flags);
|
||||
DEBUG(("in xrdp_sec_process_logon_info flags $%x", flags));
|
||||
@ -398,6 +410,10 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
|
||||
}
|
||||
}
|
||||
|
||||
if (!s_check_rem(s, 2))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
in_uint16_le(s, len_domain);
|
||||
|
||||
if (len_domain > 511)
|
||||
@ -406,6 +422,10 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!s_check_rem(s, 2))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
in_uint16_le(s, len_user);
|
||||
|
||||
if (len_user > 511)
|
||||
@ -414,6 +434,10 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!s_check_rem(s, 2))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
in_uint16_le(s, len_password);
|
||||
|
||||
if (len_password > 511)
|
||||
@ -422,6 +446,10 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!s_check_rem(s, 2))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
in_uint16_le(s, len_program);
|
||||
|
||||
if (len_program > 511)
|
||||
@ -430,6 +458,10 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!s_check_rem(s, 2))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
in_uint16_le(s, len_directory);
|
||||
|
||||
if (len_directory > 511)
|
||||
@ -438,35 +470,75 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
|
||||
return 1;
|
||||
}
|
||||
|
||||
unicode_in(s, len_domain, self->rdp_layer->client_info.domain, 255);
|
||||
if (unicode_in(s, len_domain, self->rdp_layer->client_info.domain, 255) != 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
DEBUG(("domain %s", self->rdp_layer->client_info.domain));
|
||||
unicode_in(s, len_user, self->rdp_layer->client_info.username, 255);
|
||||
if (unicode_in(s, len_user, self->rdp_layer->client_info.username, 255) != 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
DEBUG(("username %s", self->rdp_layer->client_info.username));
|
||||
|
||||
if (flags & RDP_LOGON_AUTO)
|
||||
{
|
||||
unicode_in(s, len_password, self->rdp_layer->client_info.password, 255);
|
||||
if (unicode_in(s, len_password, self->rdp_layer->client_info.password, 255) != 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
DEBUG(("flag RDP_LOGON_AUTO found"));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!s_check_rem(s, len_password + 2))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
in_uint8s(s, len_password + 2);
|
||||
if (self->rdp_layer->client_info.require_credentials)
|
||||
{
|
||||
g_writeln("xrdp_sec_process_logon_info: credentials on cmd line is mandatory");
|
||||
return 1; /* credentials on cmd line is mandatory */
|
||||
}
|
||||
}
|
||||
|
||||
unicode_in(s, len_program, self->rdp_layer->client_info.program, 255);
|
||||
if (unicode_in(s, len_program, self->rdp_layer->client_info.program, 255) != 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
DEBUG(("program %s", self->rdp_layer->client_info.program));
|
||||
unicode_in(s, len_directory, self->rdp_layer->client_info.directory, 255);
|
||||
if (unicode_in(s, len_directory, self->rdp_layer->client_info.directory, 255) != 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
DEBUG(("directory %s", self->rdp_layer->client_info.directory));
|
||||
|
||||
if (flags & RDP_LOGON_BLOB)
|
||||
{
|
||||
if (!s_check_rem(s, 4))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
in_uint8s(s, 2); /* unknown */
|
||||
in_uint16_le(s, len_ip);
|
||||
unicode_in(s, len_ip - 2, tmpdata, 255);
|
||||
if (unicode_in(s, len_ip - 2, tmpdata, 255) != 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (!s_check_rem(s, 2))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
in_uint16_le(s, len_dll);
|
||||
unicode_in(s, len_dll - 2, tmpdata, 255);
|
||||
if (unicode_in(s, len_dll - 2, tmpdata, 255) != 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (!s_check_rem(s, 4 + 62 + 22 + 62 + 26 + 4))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
in_uint32_le(s, tzone); /* len of timetone */
|
||||
in_uint8s(s, 62); /* skip */
|
||||
in_uint8s(s, 22); /* skip misc. */
|
||||
@ -676,17 +748,29 @@ xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!s_check_rem(s, 4))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
in_uint32_le(s, flags);
|
||||
DEBUG((" in xrdp_sec_recv flags $%x", flags));
|
||||
|
||||
if (flags & SEC_ENCRYPT) /* 0x08 */
|
||||
{
|
||||
if (!s_check_rem(s, 8))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
in_uint8s(s, 8); /* signature */
|
||||
xrdp_sec_decrypt(self, s->p, (int)(s->end - s->p));
|
||||
}
|
||||
|
||||
if (flags & SEC_CLIENT_RANDOM) /* 0x01 */
|
||||
{
|
||||
if (!s_check_rem(s, 4 + 64))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
in_uint32_le(s, len);
|
||||
in_uint8a(s, self->client_crypt_random, 64);
|
||||
xrdp_sec_rsa_op(self->client_random, self->client_crypt_random,
|
||||
|
Loading…
Reference in New Issue
Block a user