Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP2:Update
xrdp.27289
xrdp-CVE-2022-23480.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File xrdp-CVE-2022-23480.patch of Package xrdp.27289
From 86ca19bfe8b227291041694348c55468968ff25b 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 4/8] CVE-2022-23480 Added length checking to redirector response parsing --- sesman/chansrv/devredir.c | 142 +++++++++++++++++++++++++++++--------- sesman/chansrv/devredir.h | 6 +- 2 files changed, 113 insertions(+), 35 deletions(-) diff --git a/sesman/chansrv/devredir.c b/sesman/chansrv/devredir.c index 629b3cc9..5a45589d 100644 --- a/sesman/chansrv/devredir.c +++ b/sesman/chansrv/devredir.c @@ -204,6 +204,11 @@ dev_redir_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); @@ -221,27 +226,34 @@ dev_redir_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 dev_redir_send_server_clientID_confirm(); break; case PAKID_CORE_CLIENT_NAME: @@ -259,15 +271,15 @@ dev_redir_data_in(struct stream *s, int chan_id, int chan_flags, int length, break; case PAKID_CORE_CLIENT_CAPABILITY: - dev_redir_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_DEVICE_IOCOMPLETION: - dev_redir_proc_device_iocompletion(ls); + rv = devredir_proc_device_iocompletion(ls); break; default: @@ -585,8 +597,10 @@ void dev_redir_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 *****************************************************************************/ -void dev_redir_proc_client_core_cap_resp(struct stream *s) +int +devredir_proc_client_core_cap_resp(struct stream *s) { int i; tui16 num_caps; @@ -595,15 +609,31 @@ void dev_redir_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) { @@ -636,11 +666,13 @@ void dev_redir_proc_client_core_cap_resp(struct stream *s) scard_init(); break; } - s->p = holdp + cap_len; + xstream_seek(s, cap_len); } + return 0; } -void devredir_proc_client_devlist_announce_req(struct stream *s) +int +devredir_proc_client_devlist_announce_req(struct stream *s) { unsigned int i; int j; @@ -650,12 +682,22 @@ void devredir_proc_client_devlist_announce_req(struct stream *s) char preferred_dos_name[9]; /* 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); @@ -718,10 +760,11 @@ void devredir_proc_client_devlist_announce_req(struct stream *s) break; } } + return 0; } -void -dev_redir_proc_device_iocompletion(struct stream *s) +int +devredir_proc_device_iocompletion(struct stream *s) { FUSE_DATA *fuse_data = NULL; IRP *irp = NULL; @@ -731,6 +774,10 @@ dev_redir_proc_device_iocompletion(struct stream *s) tui32 IoStatus; tui32 Length; + 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, IoStatus); @@ -740,7 +787,7 @@ dev_redir_proc_device_iocompletion(struct stream *s) if ((irp = devredir_irp_find(CompletionId)) == NULL) { log_error("IRP with completion ID %d not found", CompletionId); - return; + return -1; } /* if callback has been set, call it */ @@ -766,17 +813,27 @@ dev_redir_proc_device_iocompletion(struct stream *s) free(fuse_data); } devredir_irp_delete(irp); - return; } + else + { + if (!s_check_rem_and_log(s, 4, "Parsing [MS-RDPEFS] DR_CREATE_RSP")) + { + return -1; + } + xstream_rd_u32_le(s, irp->FileId); + log_debug("got CID_CREATE_DIR_REQ IoStatus=0x%x FileId=%d", + IoStatus, irp->FileId); + + dev_redir_send_drive_dir_request(irp, DeviceId, 1, irp->pathname); + } - xstream_rd_u32_le(s, irp->FileId); - log_debug("got CID_CREATE_DIR_REQ IoStatus=0x%x FileId=%d", - IoStatus, irp->FileId); - - dev_redir_send_drive_dir_request(irp, DeviceId, 1, irp->pathname); break; case CID_CREATE_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); log_debug("got CID_CREATE_OPEN_REQ IoStatus=0x%x FileId=%d", @@ -791,7 +848,15 @@ dev_redir_proc_device_iocompletion(struct stream *s) case CID_READ: log_debug("got 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; + } fuse_data = devredir_fuse_data_dequeue(irp); if (fuse_data == NULL) @@ -807,6 +872,10 @@ dev_redir_proc_device_iocompletion(struct stream *s) case CID_WRITE: log_debug("got CID_WRITE"); + if (!s_check_rem_and_log(s, 4, "Parsing [MS-RDPEFS] DR_WRITE_RSP")) + { + return -1; + } xstream_rd_u32_le(s, Length); fuse_data = devredir_fuse_data_dequeue(irp); @@ -844,9 +913,13 @@ dev_redir_proc_device_iocompletion(struct stream *s) case CID_RMDIR_OR_FILE: log_debug("got CID_RMDIR_OR_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_rmdir_or_file(irp, IoStatus); - return; + return 0; break; case CID_RMDIR_OR_FILE_RESP: @@ -856,9 +929,13 @@ dev_redir_proc_device_iocompletion(struct stream *s) case CID_RENAME_FILE: log_debug("got 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); - return; + return 0; break; case CID_RENAME_FILE_RESP: @@ -882,6 +959,7 @@ done: } log_debug("exiting"); + return 0; } void diff --git a/sesman/chansrv/devredir.h b/sesman/chansrv/devredir.h index 5618b39c..0905d26b 100644 --- a/sesman/chansrv/devredir.h +++ b/sesman/chansrv/devredir.h @@ -63,9 +63,9 @@ int dev_redir_send_drive_close_request(tui16 Component, tui16 PacketId, tui32 MinorFunc, int pad_len); -void devredir_proc_client_devlist_announce_req(struct stream *s); -void dev_redir_proc_client_core_cap_resp(struct stream *s); -void dev_redir_proc_device_iocompletion(struct stream *s); +int devredir_proc_client_devlist_announce_req(struct stream *s); +int dev_redir_proc_client_core_cap_resp(struct stream *s); +int dev_redir_proc_device_iocompletion(struct stream *s); void dev_redir_proc_query_dir_response(IRP *irp, struct stream *s, -- 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