diff options
author | Jay Sorg <jay.sorg@gmail.com> | 2013-09-10 16:00:30 -0700 |
---|---|---|
committer | Jay Sorg <jay.sorg@gmail.com> | 2013-09-10 16:00:30 -0700 |
commit | 39ed446e1513c52f795d090fc9b1f173c0912d6a (patch) | |
tree | 6e47fae59fd77f52b44fa3d1bf51871152e9a363 /libxrdp | |
parent | 4e58a5a3c022f90ce9219e126893b721fee2b90a (diff) | |
download | xrdp-proprietary-39ed446e1513c52f795d090fc9b1f173c0912d6a.tar.gz xrdp-proprietary-39ed446e1513c52f795d090fc9b1f173c0912d6a.zip |
VUL: fix some possible buffer overruns
Diffstat (limited to 'libxrdp')
-rw-r--r-- | libxrdp/xrdp_iso.c | 18 | ||||
-rw-r--r-- | libxrdp/xrdp_mcs.c | 89 | ||||
-rw-r--r-- | libxrdp/xrdp_sec.c | 46 |
3 files changed, 148 insertions, 5 deletions
diff --git a/libxrdp/xrdp_iso.c b/libxrdp/xrdp_iso.c index d851c1bb..feba6814 100644 --- a/libxrdp/xrdp_iso.c +++ b/libxrdp/xrdp_iso.c @@ -72,20 +72,38 @@ 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); } diff --git a/libxrdp/xrdp_mcs.c b/libxrdp/xrdp_mcs.c index 4bf3d025..cdcfeee6 100644 --- a/libxrdp/xrdp_mcs.c +++ b/libxrdp/xrdp_mcs.c @@ -132,6 +132,11 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan) return 1; } + if (!s_check_rem(s, 1)) + { + return 1; + } + in_uint8(s, opcode); 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 */ if (appid == MCS_CJRQ) { + if (!s_check_rem(s, 4)) + { + return 1; + } + in_uint16_be(s, userid); in_uint16_be(s, chanid); 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; } + if (!s_check_rem(s, 6)) + { + return 1; + } + in_uint8s(s, 2); in_uint16_be(s, *chan); in_uint8s(s, 1); @@ -183,6 +198,10 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan) if (len & 0x80) { + if (!s_check_rem(s, 1)) + { + return 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 (!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); } @@ -214,6 +241,11 @@ xrdp_mcs_ber_parse_header(struct xrdp_mcs *self, struct stream *s, return 1; } + if (!s_check_rem(s, 1)) + { + return 1; + } + in_uint8(s, l); if (l & 0x80) @@ -223,6 +255,10 @@ xrdp_mcs_ber_parse_header(struct xrdp_mcs *self, struct stream *s, while (l > 0) { + if (!s_check_rem(s, 1)) + { + return 1; + } in_uint8(s, i); *len = (*len << 8) | i; l--; @@ -255,6 +291,11 @@ 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)) @@ -276,7 +317,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) { @@ -338,6 +379,12 @@ xrdp_mcs_recv_connect_initial(struct xrdp_mcs *self) 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); @@ -372,6 +419,12 @@ 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); @@ -381,11 +434,22 @@ xrdp_mcs_recv_edrq(struct xrdp_mcs *self) 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); } @@ -416,6 +480,12 @@ xrdp_mcs_recv_aurq(struct xrdp_mcs *self) return 1; } + if (!s_check_rem(s, 1)) + { + free_stream(s); + return 1; + } + in_uint8(s, opcode); if ((opcode >> 2) != MCS_AURQ) @@ -426,6 +496,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); } @@ -491,6 +566,12 @@ xrdp_mcs_recv_cjrq(struct xrdp_mcs *self) return 1; } + if (!s_check_rem(s, 1)) + { + free_stream(s); + return 1; + } + in_uint8(s, opcode); if ((opcode >> 2) != MCS_CJRQ) @@ -499,6 +580,12 @@ xrdp_mcs_recv_cjrq(struct xrdp_mcs *self) return 1; } + if (!s_check_rem(s, 4)) + { + free_stream(s); + return 1; + } + in_uint8s(s, 4); if (opcode & 2) diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c index 726fcde4..c44ae420 100644 --- a/libxrdp/xrdp_sec.c +++ b/libxrdp/xrdp_sec.c @@ -836,16 +836,30 @@ xrdp_sec_process_mcs_data_channels(struct xrdp_sec *self, struct stream *s) 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)); } @@ -864,10 +878,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)) @@ -999,7 +1017,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; @@ -1011,6 +1029,10 @@ 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; @@ -1018,6 +1040,10 @@ xrdp_sec_in_mcs_data(struct xrdp_sec *self) 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; @@ -1026,13 +1052,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; } /*****************************************************************************/ @@ -1105,7 +1140,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; } |