Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP2:Update
xrdp
xrdp-CVE-2022-23480.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File xrdp-CVE-2022-23480.patch of Package xrdp
From 6f31db348357b3510e88c6d8b18cba1ae6348d88 Mon Sep 17 00:00:00 2001 From: matt335672 <30179339+matt335672@users.noreply.github.com> Date: Tue, 6 Dec 2022 12:48:57 +0000 Subject: [PATCH 05/10] CVE-2022-23480 Added length checking to redirector response parsing --- sesman/chansrv/devredir.c | 285 +++++++++++++++++++++++++------------- 1 file changed, 188 insertions(+), 97 deletions(-) diff --git a/sesman/chansrv/devredir.c b/sesman/chansrv/devredir.c index 806d9c06..ee69729b 100644 --- a/sesman/chansrv/devredir.c +++ b/sesman/chansrv/devredir.c @@ -164,10 +164,10 @@ static void devredir_send_server_core_cap_req(void); static void devredir_send_server_clientID_confirm(void); static void devredir_send_server_user_logged_on(void); -static void devredir_proc_client_core_cap_resp(struct stream *s); -static void devredir_proc_client_devlist_announce_req(struct stream *s); -static void devredir_proc_client_devlist_remove_req(struct stream *s); -static void devredir_proc_device_iocompletion(struct stream *s); +static int devredir_proc_client_core_cap_resp(struct stream *s); +static int devredir_proc_client_devlist_announce_req(struct stream *s); +static int devredir_proc_client_devlist_remove_req(struct stream *s); +static int devredir_proc_device_iocompletion(struct stream *s); static void devredir_proc_query_dir_response(IRP *irp, struct stream *s_in, tui32 DeviceId, @@ -345,6 +345,11 @@ devredir_data_in(struct stream *s, int chan_id, int chan_flags, int length, } /* read header from incoming data */ + if (!s_check_rem_and_log(ls, 4, "Parsing [MS-RDPEFS] RDPDR_HEADER")) + { + rv = -1; + goto done; + } xstream_rd_u16_le(ls, comp_type); xstream_rd_u16_le(ls, pktID); @@ -362,27 +367,34 @@ devredir_data_in(struct stream *s, int chan_id, int chan_flags, int length, switch (pktID) { case PAKID_CORE_CLIENTID_CONFIRM: - xstream_seek(ls, 2); /* major version, we ignore it */ - xstream_rd_u16_le(ls, minor_ver); - xstream_rd_u32_le(ls, g_clientID); + if (!s_check_rem_and_log(ls, 6, "Parsing [MS-RDPEFS] DR_CORE_CLIENT_ANNOUNCE_RSP")) + { + rv = -1; + } + else + { + xstream_seek(ls, 2); /* major version, we ignore it */ + xstream_rd_u16_le(ls, minor_ver); + xstream_rd_u32_le(ls, g_clientID); - g_client_rdp_version = minor_ver; + g_client_rdp_version = minor_ver; - switch (minor_ver) - { - case RDP_CLIENT_50: - break; + switch (minor_ver) + { + case RDP_CLIENT_50: + break; - case RDP_CLIENT_51: - break; + case RDP_CLIENT_51: + break; - case RDP_CLIENT_52: - break; + case RDP_CLIENT_52: + break; - case RDP_CLIENT_60_61: - break; + case RDP_CLIENT_60_61: + break; + } + // LK_TODO devredir_send_server_clientID_confirm(); } - // LK_TODO devredir_send_server_clientID_confirm(); break; case PAKID_CORE_CLIENT_NAME: @@ -400,19 +412,19 @@ devredir_data_in(struct stream *s, int chan_id, int chan_flags, int length, break; case PAKID_CORE_CLIENT_CAPABILITY: - devredir_proc_client_core_cap_resp(ls); + rv = devredir_proc_client_core_cap_resp(ls); break; case PAKID_CORE_DEVICELIST_ANNOUNCE: - devredir_proc_client_devlist_announce_req(ls); + rv = devredir_proc_client_devlist_announce_req(ls); break; case PAKID_CORE_DEVICELIST_REMOVE: - devredir_proc_client_devlist_remove_req(ls); + rv = devredir_proc_client_devlist_remove_req(ls); break; case PAKID_CORE_DEVICE_IOCOMPLETION: - devredir_proc_device_iocompletion(ls); + rv = devredir_proc_device_iocompletion(ls); break; default: @@ -747,8 +759,9 @@ devredir_send_drive_dir_request(IRP *irp, tui32 device_id, * @brief process client's response to our core_capability_req() msg * * @param s stream containing client's response + * @return 0 for success, -1 otherwise *****************************************************************************/ -static void +static int devredir_proc_client_core_cap_resp(struct stream *s) { int i; @@ -758,15 +771,31 @@ devredir_proc_client_core_cap_resp(struct stream *s) tui32 cap_version; char* holdp; + if (!s_check_rem_and_log(s, 4, "Parsing [MS-RDPEFS] DR_CORE_CAPABLITY_RSP")) + { + return -1; + } xstream_rd_u16_le(s, num_caps); xstream_seek(s, 2); /* padding */ for (i = 0; i < num_caps; i++) { holdp = s->p; + if (!s_check_rem_and_log(s, 8, "Parsing [MS-RDPEFS] CAPABILITY_HEADER")) + { + return -1; + } xstream_rd_u16_le(s, cap_type); xstream_rd_u16_le(s, cap_len); xstream_rd_u32_le(s, cap_version); + /* Convert the length to a remaining length. Underflow is possible, + * but this is an unsigned type so that's OK */ + cap_len -= (s->p - holdp); + if (cap_len > 0 && + !s_check_rem_and_log(s, cap_len, "Parsing [MS-RDPEFS] CAPABILITY_HEADER length")) + { + return -1; + } switch (cap_type) { @@ -799,11 +828,12 @@ devredir_proc_client_core_cap_resp(struct stream *s) scard_init(); break; } - s->p = holdp + cap_len; + xstream_seek(s, cap_len); } + return 0; } -static void +static int devredir_proc_client_devlist_announce_req(struct stream *s) { unsigned int i; @@ -815,12 +845,22 @@ devredir_proc_client_devlist_announce_req(struct stream *s) enum NTSTATUS response_status; /* get number of devices being announced */ + if (!s_check_rem_and_log(s, 4, "Parsing [MS-RDPEFS] DR_CORE_DEVICELIST_ANNOUNCE_REQ")) + { + return -1; + } + xstream_rd_u32_le(s, device_count); log_debug("num of devices announced: %d", device_count); for (i = 0; i < device_count; i++) { + if (!s_check_rem_and_log(s, 4 + 4 + 8 + 4, + "Parsing [MS-RDPEFS] DEVICE_ANNOUNCE")) + { + return -1; + } xstream_rd_u32_le(s, device_type); xstream_rd_u32_le(s, g_device_id); /* get preferred DOS name @@ -834,6 +874,15 @@ devredir_proc_client_devlist_announce_req(struct stream *s) /* Assume this device isn't supported by us */ response_status = STATUS_NOT_SUPPORTED; + /* Read the device data length from the stream */ + xstream_rd_u32_le(s, device_data_len); + if (device_data_len > 0 && ! + !s_check_rem_and_log(s, device_data_len, + "Parsing [MS-RDPEFS] DEVICE_ANNOUNCE devdata")) + { + return -1; + } + switch (device_type) { case RDPDR_DTYP_FILESYSTEM: @@ -897,9 +946,11 @@ devredir_proc_client_devlist_announce_req(struct stream *s) devredir_send_server_device_announce_resp(g_device_id, response_status); } + + return 0; } -static void +static int devredir_proc_client_devlist_remove_req(struct stream *s) { unsigned int i; @@ -907,7 +958,16 @@ devredir_proc_client_devlist_remove_req(struct stream *s) tui32 device_id; /* get number of devices being announced */ + if (!s_check_rem_and_log(s, 4, "Parsing [MS-RDPEFS] DR_DEVICELIST_REMOVE")) + { + return -1; + } xstream_rd_u32_le(s, device_count); + if (!s_check_rem_and_log(s, 4 * device_count, + "Parsing [MS-RDPEFS] DR_DEVICELIST_REMOVE list")) + { + return -1; + } log_debug("num of devices removed: %d", device_count); { @@ -917,9 +977,10 @@ devredir_proc_client_devlist_remove_req(struct stream *s) xfuse_delete_share(device_id); } } + return 0; } -static void +static int devredir_proc_device_iocompletion(struct stream *s) { IRP *irp = NULL; @@ -930,6 +991,10 @@ devredir_proc_device_iocompletion(struct stream *s) tui32 Length; enum COMPLETION_TYPE comp_type; + if (!s_check_rem_and_log(s, 12, "Parsing [MS-RDPEFS] DR_DEVICE_IOCOMPLETION")) + { + return -1; + } xstream_rd_u32_le(s, DeviceId); xstream_rd_u32_le(s, CompletionId); xstream_rd_u32_le(s, IoStatus32); @@ -968,87 +1033,112 @@ devredir_proc_device_iocompletion(struct stream *s) switch (comp_type) { - case CID_CREATE_DIR_REQ: - if (IoStatus != STATUS_SUCCESS) - { - xfuse_devredir_cb_enum_dir_done( - (struct state_dirscan *) irp->fuse_info, IoStatus); - devredir_irp_delete(irp); - } - else - { + case CID_CREATE_DIR_REQ: + if (IoStatus != STATUS_SUCCESS) + { + xfuse_devredir_cb_enum_dir_done( + (struct state_dirscan *) irp->fuse_info, IoStatus); + devredir_irp_delete(irp); + } + else + { + if (!s_check_rem_and_log(s, 4, "Parsing [MS-RDPEFS] DR_CREATE_RSP")) + { + return -1; + } + xstream_rd_u32_le(s, irp->FileId); + devredir_send_drive_dir_request(irp, DeviceId, + 1, irp->pathname); + } + break; + + case CID_CREATE_REQ: + if (!s_check_rem_and_log(s, 4, "Parsing [MS-RDPEFS] DR_CREATE_RSP")) + { + return -1; + } xstream_rd_u32_le(s, irp->FileId); - devredir_send_drive_dir_request(irp, DeviceId, - 1, irp->pathname); - } - break; - case CID_CREATE_REQ: - xstream_rd_u32_le(s, irp->FileId); + xfuse_devredir_cb_create_file( + (struct state_create *) irp->fuse_info, + IoStatus, DeviceId, irp->FileId); + if (irp->gen.create.creating_dir || IoStatus != STATUS_SUCCESS) + { + devredir_irp_delete(irp); + } + break; - xfuse_devredir_cb_create_file( - (struct state_create *) irp->fuse_info, - IoStatus, DeviceId, irp->FileId); - if (irp->gen.create.creating_dir || IoStatus != STATUS_SUCCESS) - { - devredir_irp_delete(irp); - } - break; + case CID_OPEN_REQ: + if (!s_check_rem_and_log(s, 4, "Parsing [MS-RDPEFS] DR_CREATE_RSP")) + { + return -1; + } + xstream_rd_u32_le(s, irp->FileId); - case CID_OPEN_REQ: - xstream_rd_u32_le(s, irp->FileId); + xfuse_devredir_cb_open_file((struct state_open *) irp->fuse_info, + IoStatus, DeviceId, irp->FileId); + if (IoStatus != STATUS_SUCCESS) + { + devredir_irp_delete(irp); + } + break; - xfuse_devredir_cb_open_file((struct state_open *) irp->fuse_info, - IoStatus, DeviceId, irp->FileId); - if (IoStatus != STATUS_SUCCESS) - { + case CID_READ: + if (!s_check_rem_and_log(s, 4, "Parsing [MS-RDPEFS] DR_READ_RSP")) + { + return -1; + } + xstream_rd_u32_le(s, Length); + if (!s_check_rem_and_log(s, Length, "Parsing [MS-RDPEFS] DR_READ_RSP")) + { + return -1; + } + xfuse_devredir_cb_read_file((struct state_read *) irp->fuse_info, + IoStatus, + s->p, Length); devredir_irp_delete(irp); - } - break; - - case CID_READ: - xstream_rd_u32_le(s, Length); - xfuse_devredir_cb_read_file((struct state_read *) irp->fuse_info, - IoStatus, - s->p, Length); - devredir_irp_delete(irp); - break; - - case CID_WRITE: - xstream_rd_u32_le(s, Length); - xfuse_devredir_cb_write_file((struct state_write *) irp->fuse_info, - IoStatus, - irp->gen.write.offset, Length); - devredir_irp_delete(irp); - break; + break; - case CID_CLOSE: - devredir_irp_delete(irp); - break; + case CID_WRITE: + if (!s_check_rem_and_log(s, 4, "Parsing [MS-RDPEFS] DR_WRITE_RSP")) + { + return -1; + } + xstream_rd_u32_le(s, Length); + xfuse_devredir_cb_write_file((struct state_write *) irp->fuse_info, + IoStatus, + irp->gen.write.offset, Length); + devredir_irp_delete(irp); + break; - case CID_FILE_CLOSE: - xfuse_devredir_cb_file_close((struct state_close *) irp->fuse_info); - devredir_irp_delete(irp); - break; + case CID_CLOSE: + devredir_irp_delete(irp); + break; - case CID_DIRECTORY_CONTROL: - devredir_proc_query_dir_response(irp, s, DeviceId, - CompletionId, IoStatus); - break; + case CID_FILE_CLOSE: + xfuse_devredir_cb_file_close((struct state_close *) irp->fuse_info); + devredir_irp_delete(irp); + break; - case CID_RMDIR_OR_FILE: - xstream_rd_u32_le(s, irp->FileId); - devredir_proc_cid_rmdir_or_file(irp, IoStatus); - break; + case CID_DIRECTORY_CONTROL: + devredir_proc_query_dir_response(irp, s, DeviceId, + CompletionId, IoStatus); + break; - case CID_RMDIR_OR_FILE_RESP: - devredir_proc_cid_rmdir_or_file_resp(irp, IoStatus); - break; + case CID_RMDIR_OR_FILE: + if (!s_check_rem_and_log(s, 4, "Parsing [MS-RDPEFS] DR_CREATE_RSP")) + { + return -1; + } - case CID_RENAME_FILE: - xstream_rd_u32_le(s, irp->FileId); - devredir_proc_cid_rename_file(irp, IoStatus); - break; + case CID_RENAME_FILE: + if (!s_check_rem_and_log(s, 4, "Parsing [MS-RDPEFS] DR_CREATE_RSP")) + { + return -1; + } + xstream_rd_u32_le(s, irp->FileId); + devredir_proc_cid_rename_file(irp, IoStatus); + break; case CID_RENAME_FILE_RESP: devredir_proc_cid_rename_file_resp(irp, IoStatus); @@ -1069,6 +1159,7 @@ devredir_proc_device_iocompletion(struct stream *s) break; } } + return 0; } static void -- 2.39.0
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor