Control: tags -1 patch
Hi,I'm attaching my patch for Stretch to this bug report. Since the versions in Stretch and unstable are identical, it should work there too. However I don't intend to NMU guacamole-server because I believe a new upstream version should be packaged instead.
Regards, Markus
diff -Nru guacamole-server-0.9.9/debian/patches/CVE-2020-9497-and-CVE-2020-9498.patch guacamole-server-0.9.9/debian/patches/CVE-2020-9497-and-CVE-2020-9498.patch --- guacamole-server-0.9.9/debian/patches/CVE-2020-9497-and-CVE-2020-9498.patch 1970-01-01 01:00:00.000000000 +0100 +++ guacamole-server-0.9.9/debian/patches/CVE-2020-9497-and-CVE-2020-9498.patch 2020-11-06 22:44:56.000000000 +0100 @@ -0,0 +1,355 @@ +From: Markus Koschany <a...@debian.org> +Date: Tue, 3 Nov 2020 13:45:20 +0100 +Subject: CVE-2020-9497 and CVE-2020-9498 + +Bug-Debian: https://bugs.debian.org/964195 +Origin: https://github.com/apache/guacamole-server/commit/a0e11dc81727528224d28466903454e1cb0266bb +--- + src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages.c | 40 ++++++++++++++++++++++ + .../rdp/guac_rdpdr/rdpdr_fs_messages_file_info.c | 12 +++++++ + src/protocols/rdp/guac_rdpdr/rdpdr_messages.c | 18 ++++++++++ + src/protocols/rdp/guac_rdpdr/rdpdr_printer.c | 7 ++++ + src/protocols/rdp/guac_rdpdr/rdpdr_service.c | 3 ++ + src/protocols/rdp/guac_rdpsnd/rdpsnd_messages.c | 29 ++++++++++++++++ + src/protocols/rdp/guac_rdpsnd/rdpsnd_service.c | 5 +++ + 7 files changed, 114 insertions(+) + +diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages.c b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages.c +index bfd8ead..10d41bb 100644 +--- a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages.c ++++ b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages.c +@@ -58,6 +58,10 @@ void guac_rdpdr_fs_process_create(guac_rdpdr_device* device, + int create_disposition, create_options, path_length; + char path[GUAC_RDP_FS_MAX_PATH]; + ++ /* Check remaining stream data prior to reading. */ ++ if (Stream_GetRemainingLength(input_stream) < 32) ++ return; ++ + /* Read "create" information */ + Stream_Read_UINT32(input_stream, desired_access); + Stream_Seek_UINT64(input_stream); /* allocation size */ +@@ -67,6 +71,11 @@ void guac_rdpdr_fs_process_create(guac_rdpdr_device* device, + Stream_Read_UINT32(input_stream, create_options); + Stream_Read_UINT32(input_stream, path_length); + ++ /* Check to make sure the stream contains path_length bytes. */ ++ if(Stream_GetRemainingLength(input_stream) < path_length) { ++ return; ++ } ++ + /* Convert path to UTF-8 */ + guac_rdp_utf16_to_utf8(Stream_Pointer(input_stream), path_length/2 - 1, + path, sizeof(path)); +@@ -133,6 +142,10 @@ void guac_rdpdr_fs_process_read(guac_rdpdr_device* device, + + wStream* output_stream; + ++ /* Check remaining bytes before reading stream. */ ++ if (Stream_GetRemainingLength(input_stream) < 12) ++ return; ++ + /* Read packet */ + Stream_Read_UINT32(input_stream, length); + Stream_Read_UINT64(input_stream, offset); +@@ -181,6 +194,10 @@ void guac_rdpdr_fs_process_write(guac_rdpdr_device* device, + + wStream* output_stream; + ++ /* Check remaining length. */ ++ if (Stream_GetRemainingLength(input_stream) < 32) ++ return; ++ + /* Read packet */ + Stream_Read_UINT32(input_stream, length); + Stream_Read_UINT64(input_stream, offset); +@@ -190,6 +207,11 @@ void guac_rdpdr_fs_process_write(guac_rdpdr_device* device, + "%s: [file_id=%i] length=%i, offset=%" PRIu64, + __func__, file_id, length, (uint64_t) offset); + ++ /* Check to make sure stream contains at least length bytes */ ++ if (Stream_GetRemainingLength(input_stream) < length) { ++ return; ++ } ++ + /* Attempt write */ + bytes_written = guac_rdp_fs_write((guac_rdp_fs*) device->data, file_id, + offset, Stream_Pointer(input_stream), length); +@@ -252,6 +274,10 @@ void guac_rdpdr_fs_process_volume_info(guac_rdpdr_device* device, wStream* input + + int fs_information_class; + ++ /* Check remaining length */ ++ if (Stream_GetRemainingLength(input_stream) < 4) ++ return; ++ + Stream_Read_UINT32(input_stream, fs_information_class); + + /* Dispatch to appropriate class-specific handler */ +@@ -294,6 +320,10 @@ void guac_rdpdr_fs_process_file_info(guac_rdpdr_device* device, wStream* input_s + + int fs_information_class; + ++ /* Check remaining length */ ++ if (Stream_GetRemainingLength(input_stream) < 4) ++ return; ++ + Stream_Read_UINT32(input_stream, fs_information_class); + + /* Dispatch to appropriate class-specific handler */ +@@ -341,6 +371,10 @@ void guac_rdpdr_fs_process_set_file_info(guac_rdpdr_device* device, + int fs_information_class; + int length; + ++ /* Check remaining length */ ++ if (Stream_GetRemainingLength(input_stream) < 32) ++ return; ++ + Stream_Read_UINT32(input_stream, fs_information_class); + Stream_Read_UINT32(input_stream, length); /* Length */ + Stream_Seek(input_stream, 24); /* Padding */ +@@ -423,6 +457,9 @@ void guac_rdpdr_fs_process_query_directory(guac_rdpdr_device* device, wStream* i + if (file == NULL) + return; + ++ if (Stream_GetRemainingLength(input_stream) < 9) ++ return; ++ + /* Read main header */ + Stream_Read_UINT32(input_stream, fs_information_class); + Stream_Read_UINT8(input_stream, initial_query); +@@ -431,6 +468,9 @@ void guac_rdpdr_fs_process_query_directory(guac_rdpdr_device* device, wStream* i + /* If this is the first query, the path is included after padding */ + if (initial_query) { + ++ if (Stream_GetRemainingLength(input_stream) < 23 + path_length) ++ return; ++ + Stream_Seek(input_stream, 23); /* Padding */ + + /* Convert path to UTF-8 */ +diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_file_info.c b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_file_info.c +index a0a7a73..99711fe 100644 +--- a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_file_info.c ++++ b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_file_info.c +@@ -143,11 +143,19 @@ void guac_rdpdr_fs_process_set_rename_info(guac_rdpdr_device* device, + wStream* output_stream; + char destination_path[GUAC_RDP_FS_MAX_PATH]; + ++ /* Check stream size prior to reading. */ ++ if (Stream_GetRemainingLength(input_stream) < 6) ++ return; ++ + /* Read structure */ + Stream_Seek_UINT8(input_stream); /* ReplaceIfExists */ + Stream_Seek_UINT8(input_stream); /* RootDirectory */ + Stream_Read_UINT32(input_stream, filename_length); /* FileNameLength */ + ++ if (Stream_GetRemainingLength(input_stream) < filename_length) { ++ return; ++ } ++ + /* Convert name to UTF-8 */ + guac_rdp_utf16_to_utf8(Stream_Pointer(input_stream), filename_length/2, + destination_path, sizeof(destination_path)); +@@ -199,6 +207,10 @@ void guac_rdpdr_fs_process_set_allocation_info(guac_rdpdr_device* device, + UINT64 size; + wStream* output_stream; + ++ if (Stream_GetRemainingLength(input_stream) < 8) { ++ return; ++ } ++ + /* Read new size */ + Stream_Read_UINT64(input_stream, size); /* AllocationSize */ + +diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_messages.c b/src/protocols/rdp/guac_rdpdr/rdpdr_messages.c +index aa11532..0ef2fbf 100644 +--- a/src/protocols/rdp/guac_rdpdr/rdpdr_messages.c ++++ b/src/protocols/rdp/guac_rdpdr/rdpdr_messages.c +@@ -150,6 +150,9 @@ void guac_rdpdr_process_server_announce(guac_rdpdrPlugin* rdpdr, + + unsigned int major, minor, client_id; + ++ if (Stream_GetRemainingLength(input_stream) < 8) ++ return; ++ + Stream_Read_UINT16(input_stream, major); + Stream_Read_UINT16(input_stream, minor); + Stream_Read_UINT32(input_stream, client_id); +@@ -177,6 +180,9 @@ void guac_rdpdr_process_device_reply(guac_rdpdrPlugin* rdpdr, wStream* input_str + unsigned int device_id, ntstatus; + int severity, c, n, facility, code; + ++ if (Stream_GetRemainingLength(input_stream) < 8) ++ return; ++ + Stream_Read_UINT32(input_stream, device_id); + Stream_Read_UINT32(input_stream, ntstatus); + +@@ -210,6 +216,9 @@ void guac_rdpdr_process_device_iorequest(guac_rdpdrPlugin* rdpdr, wStream* input + + int device_id, file_id, completion_id, major_func, minor_func; + ++ if (Stream_GetRemainingLength(input_stream) < 20) ++ return; ++ + /* Read header */ + Stream_Read_UINT32(input_stream, device_id); + Stream_Read_UINT32(input_stream, file_id); +@@ -237,6 +246,9 @@ void guac_rdpdr_process_server_capability(guac_rdpdrPlugin* rdpdr, wStream* inpu + int count; + int i; + ++ if (Stream_GetRemainingLength(input_stream) < 4) ++ return; ++ + /* Read header */ + Stream_Read_UINT16(input_stream, count); + Stream_Seek(input_stream, 2); +@@ -247,9 +259,15 @@ void guac_rdpdr_process_server_capability(guac_rdpdrPlugin* rdpdr, wStream* inpu + int type; + int length; + ++ if (Stream_GetRemainingLength(input_stream) < 4) ++ break; ++ + Stream_Read_UINT16(input_stream, type); + Stream_Read_UINT16(input_stream, length); + ++ if (Stream_GetRemainingLength(input_stream) < (length - 4)) ++ break; ++ + /* Ignore all for now */ + guac_client_log(rdpdr->client, GUAC_LOG_INFO, "Ignoring server capability set type=0x%04x, length=%i", type, length); + Stream_Seek(input_stream, length - 4); +diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_printer.c b/src/protocols/rdp/guac_rdpdr/rdpdr_printer.c +index 7aca701..4880304 100644 +--- a/src/protocols/rdp/guac_rdpdr/rdpdr_printer.c ++++ b/src/protocols/rdp/guac_rdpdr/rdpdr_printer.c +@@ -190,6 +190,9 @@ void guac_rdpdr_process_print_job_write(guac_rdpdr_device* device, + int status=0, length; + unsigned char* buffer; + ++ if (Stream_GetRemainingLength(input_stream) < 32) ++ return; ++ + wStream* output_stream; + + Stream_Read_UINT32(input_stream, length); +@@ -197,6 +200,10 @@ void guac_rdpdr_process_print_job_write(guac_rdpdr_device* device, + Stream_Seek(input_stream, 20); /* Padding */ + buffer = Stream_Pointer(input_stream); + ++ if (Stream_GetRemainingLength(input_stream) < length) { ++ return; ++ } ++ + /* Create print job, if not yet created */ + if (printer_data->bytes_received == 0) { + +diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_service.c b/src/protocols/rdp/guac_rdpdr/rdpdr_service.c +index 9be53f7..5d507ec 100644 +--- a/src/protocols/rdp/guac_rdpdr/rdpdr_service.c ++++ b/src/protocols/rdp/guac_rdpdr/rdpdr_service.c +@@ -137,6 +137,9 @@ void guac_rdpdr_process_receive(rdpSvcPlugin* plugin, + int component; + int packet_id; + ++ if (Stream_GetRemainingLength(input_stream) < 4) ++ return; ++ + /* Read header */ + Stream_Read_UINT16(input_stream, component); + Stream_Read_UINT16(input_stream, packet_id); +diff --git a/src/protocols/rdp/guac_rdpsnd/rdpsnd_messages.c b/src/protocols/rdp/guac_rdpsnd/rdpsnd_messages.c +index a0827d3..8b58daa 100644 +--- a/src/protocols/rdp/guac_rdpsnd/rdpsnd_messages.c ++++ b/src/protocols/rdp/guac_rdpsnd/rdpsnd_messages.c +@@ -61,6 +61,10 @@ void guac_rdpsnd_formats_handler(guac_rdpsndPlugin* rdpsnd, + /* Get audio stream from client data */ + guac_audio_stream* audio = client_data->audio; + ++ if (Stream_GetRemainingLength(input_stream) < 20) { ++ return; ++ } ++ + /* Format header */ + Stream_Seek(input_stream, 14); + Stream_Read_UINT16(input_stream, server_format_count); +@@ -107,6 +111,11 @@ void guac_rdpsnd_formats_handler(guac_rdpsndPlugin* rdpsnd, + /* Remember position in stream */ + Stream_GetPointer(input_stream, format_start); + ++ /* Check to make sure Stream has at least 18 bytes. */ ++ if (Stream_GetRemainingLength(input_stream) < 18) { ++ return; ++ } ++ + /* Read format */ + Stream_Read_UINT16(input_stream, format_tag); + Stream_Read_UINT16(input_stream, channels); +@@ -119,6 +128,11 @@ void guac_rdpsnd_formats_handler(guac_rdpsndPlugin* rdpsnd, + Stream_Read_UINT16(input_stream, body_size); + Stream_Seek(input_stream, body_size); + ++ /* Check that Stream has at least body_size bytes remaining. */ ++ if (Stream_GetRemainingLength(input_stream) < body_size) { ++ return; ++ } ++ + /* If PCM, accept */ + if (format_tag == WAVE_FORMAT_PCM) { + +@@ -220,6 +234,11 @@ void guac_rdpsnd_training_handler(guac_rdpsndPlugin* rdpsnd, + guac_client* client = rdpsnd->client; + rdp_guac_client_data* client_data = (rdp_guac_client_data*) client->data; + ++ /* Check to make sure audio stream contains a minimum number of bytes. */ ++ if (Stream_GetRemainingLength(input_stream) < 4) { ++ return; ++ } ++ + /* Read timestamp and data size */ + Stream_Read_UINT16(input_stream, rdpsnd->server_timestamp); + Stream_Read_UINT16(input_stream, data_size); +@@ -250,6 +269,11 @@ void guac_rdpsnd_wave_info_handler(guac_rdpsndPlugin* rdpsnd, + /* Get audio stream from client data */ + guac_audio_stream* audio = client_data->audio; + ++ /* Check to make sure audio stream contains a minimum number of bytes. */ ++ if (Stream_GetRemainingLength(input_stream) < 12) { ++ return; ++ } ++ + /* Read wave information */ + Stream_Read_UINT16(input_stream, rdpsnd->server_timestamp); + Stream_Read_UINT16(input_stream, format); +@@ -288,6 +312,11 @@ void guac_rdpsnd_wave_handler(guac_rdpsndPlugin* rdpsnd, + /* Get audio stream from client data */ + guac_audio_stream* audio = client_data->audio; + ++ /* Verify that the stream has bytes to cover the wave size plus header. */ ++ if (Stream_Length(input_stream) < (rdpsnd->incoming_wave_size + 4)) { ++ return; ++ } ++ + /* Wave Confirmation PDU */ + wStream* output_stream = Stream_New(NULL, 8); + +diff --git a/src/protocols/rdp/guac_rdpsnd/rdpsnd_service.c b/src/protocols/rdp/guac_rdpsnd/rdpsnd_service.c +index 30810ef..88e5c75 100644 +--- a/src/protocols/rdp/guac_rdpsnd/rdpsnd_service.c ++++ b/src/protocols/rdp/guac_rdpsnd/rdpsnd_service.c +@@ -104,6 +104,11 @@ void guac_rdpsnd_process_receive(rdpSvcPlugin* plugin, + guac_rdpsndPlugin* rdpsnd = (guac_rdpsndPlugin*) plugin; + guac_rdpsnd_pdu_header header; + ++ /* Check that we have at least the 4 byte header (UINT8 + UINT8 + UINT16) */ ++ if (Stream_GetRemainingLength(input_stream) < 4) { ++ return; ++ } ++ + /* Read RDPSND PDU header */ + Stream_Read_UINT8(input_stream, header.message_type); + Stream_Seek_UINT8(input_stream); diff -Nru guacamole-server-0.9.9/debian/patches/series guacamole-server-0.9.9/debian/patches/series --- guacamole-server-0.9.9/debian/patches/series 2016-11-30 16:18:15.000000000 +0100 +++ guacamole-server-0.9.9/debian/patches/series 2020-11-06 22:44:56.000000000 +0100 @@ -1,3 +1,4 @@ openssl-1.1.patch fix-buildsystem.patch fix-lfs.patch +CVE-2020-9497-and-CVE-2020-9498.patch
OpenPGP_0xD9AD14B9513B51E4.asc
Description: application/pgp-keys
OpenPGP_signature
Description: OpenPGP digital signature