From 478235be701c43c929409b3bd8d90b202e534cfe Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Wed, 11 Dec 2013 15:00:00 -0800 Subject: [PATCH] Check path lengths. --- src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages.c | 12 ++++-------- .../rdp/guac_rdpdr/rdpdr_fs_messages_dir_info.c | 12 ++++++++---- .../rdp/guac_rdpdr/rdpdr_fs_messages_file_info.c | 4 ++-- src/protocols/rdp/unicode.c | 15 ++++++++++++--- src/protocols/rdp/unicode.h | 6 ++++-- 5 files changed, 30 insertions(+), 19 deletions(-) diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages.c b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages.c index 82b87459..6d842dc7 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages.c +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages.c @@ -79,11 +79,9 @@ void guac_rdpdr_fs_process_create(guac_rdpdr_device* device, Stream_Read_UINT32(input_stream, create_options); Stream_Read_UINT32(input_stream, path_length); - /* FIXME: Validate path length */ - /* Convert path to UTF-8 */ - guac_rdp_utf16_to_utf8(Stream_Pointer(input_stream), - path, path_length/2 - 1); + guac_rdp_utf16_to_utf8(Stream_Pointer(input_stream), path_length/2 - 1, + path, sizeof(path)); /* Open file */ file_id = guac_rdp_fs_open((guac_rdp_fs*) device->data, path, @@ -482,11 +480,9 @@ void guac_rdpdr_fs_process_query_directory(guac_rdpdr_device* device, wStream* i Stream_Seek(input_stream, 23); /* Padding */ - /* FIXME: Validate path length */ - /* Convert path to UTF-8 */ - guac_rdp_utf16_to_utf8(Stream_Pointer(input_stream), - file->dir_pattern, path_length/2 - 1); + guac_rdp_utf16_to_utf8(Stream_Pointer(input_stream), path_length/2 - 1, + file->dir_pattern, sizeof(file->dir_pattern)); } diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_dir_info.c b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_dir_info.c index ea9020d6..e00e1c42 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_dir_info.c +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_dir_info.c @@ -60,7 +60,8 @@ void guac_rdpdr_fs_process_query_directory_info(guac_rdpdr_device* device, int utf16_length = length*2; unsigned char utf16_entry_name[256]; - guac_rdp_utf8_to_utf16((const unsigned char*) entry_name, (char*) utf16_entry_name, length); + guac_rdp_utf8_to_utf16((const unsigned char*) entry_name, length, + (char*) utf16_entry_name, sizeof(utf16_entry_name)); /* Get file */ file = guac_rdp_fs_get_file((guac_rdp_fs*) device->data, file_id); @@ -103,7 +104,8 @@ void guac_rdpdr_fs_process_query_full_directory_info(guac_rdpdr_device* device, int utf16_length = length*2; unsigned char utf16_entry_name[256]; - guac_rdp_utf8_to_utf16((const unsigned char*) entry_name, (char*) utf16_entry_name, length); + guac_rdp_utf8_to_utf16((const unsigned char*) entry_name, length, + (char*) utf16_entry_name, sizeof(utf16_entry_name)); /* Get file */ file = guac_rdp_fs_get_file((guac_rdp_fs*) device->data, file_id); @@ -147,7 +149,8 @@ void guac_rdpdr_fs_process_query_both_directory_info(guac_rdpdr_device* device, int utf16_length = length*2; unsigned char utf16_entry_name[256]; - guac_rdp_utf8_to_utf16((const unsigned char*) entry_name, (char*) utf16_entry_name, length); + guac_rdp_utf8_to_utf16((const unsigned char*) entry_name, length, + (char*) utf16_entry_name, sizeof(utf16_entry_name)); /* Get file */ file = guac_rdp_fs_get_file((guac_rdp_fs*) device->data, file_id); @@ -195,7 +198,8 @@ void guac_rdpdr_fs_process_query_names_info(guac_rdpdr_device* device, int utf16_length = length*2; unsigned char utf16_entry_name[256]; - guac_rdp_utf8_to_utf16((const unsigned char*) entry_name, (char*) utf16_entry_name, length); + guac_rdp_utf8_to_utf16((const unsigned char*) entry_name, length, + (char*) utf16_entry_name, sizeof(utf16_entry_name)); /* Get file */ file = guac_rdp_fs_get_file((guac_rdp_fs*) device->data, file_id); 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 53d94a74..0aaa9bc7 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 @@ -157,8 +157,8 @@ void guac_rdpdr_fs_process_set_rename_info(guac_rdpdr_device* device, Stream_Read_UINT32(input_stream, filename_length); /* FileNameLength */ /* Convert name to UTF-8 */ - guac_rdp_utf16_to_utf8(Stream_Pointer(input_stream), - destination_path, filename_length/2); + guac_rdp_utf16_to_utf8(Stream_Pointer(input_stream), filename_length/2, + destination_path, sizeof(destination_path)); GUAC_RDP_DEBUG(2, "[file_id=%i] destination_path=\"%s\"", file_id, destination_path); diff --git a/src/protocols/rdp/unicode.c b/src/protocols/rdp/unicode.c index 0e7b6015..c79c099a 100644 --- a/src/protocols/rdp/unicode.c +++ b/src/protocols/rdp/unicode.c @@ -39,7 +39,8 @@ #include -void guac_rdp_utf16_to_utf8(const unsigned char* utf16, char* utf8, int length) { +void guac_rdp_utf16_to_utf8(const unsigned char* utf16, int length, + char* utf8, int size) { int i; const uint16_t* in_codepoint = (const uint16_t*) utf16; @@ -51,7 +52,9 @@ void guac_rdp_utf16_to_utf8(const unsigned char* utf16, char* utf8, int length) uint16_t codepoint = *(in_codepoint++); /* Save codepoint as UTF-8 */ - utf8 += guac_utf8_write(codepoint, utf8, 4); + int bytes_written = guac_utf8_write(codepoint, utf8, size); + size -= bytes_written; + utf8 += bytes_written; } @@ -60,7 +63,8 @@ void guac_rdp_utf16_to_utf8(const unsigned char* utf16, char* utf8, int length) } -void guac_rdp_utf8_to_utf16(const unsigned char* utf8, char* utf16, int length) { +void guac_rdp_utf8_to_utf16(const unsigned char* utf8, int length, + char* utf16, int size) { int i; uint16_t* out_codepoint = (uint16_t*) utf16; @@ -75,6 +79,11 @@ void guac_rdp_utf8_to_utf16(const unsigned char* utf8, char* utf16, int length) /* Save codepoint as UTF-16 */ *(out_codepoint++) = codepoint; + /* Stop if buffer full */ + size -= 2; + if (size < 2) + break; + } } diff --git a/src/protocols/rdp/unicode.h b/src/protocols/rdp/unicode.h index b59b74b5..37976819 100644 --- a/src/protocols/rdp/unicode.h +++ b/src/protocols/rdp/unicode.h @@ -38,10 +38,12 @@ /** * Convert the given number of UTF-16 characters to UTF-8 characters. */ -void guac_rdp_utf16_to_utf8(const unsigned char* utf16, char* utf8, int length); +void guac_rdp_utf16_to_utf8(const unsigned char* utf16, int length, + char* utf8, int size); /** * Convert the given number of UTF-8 characters to UTF-16 characters. */ -void guac_rdp_utf8_to_utf16(const unsigned char* utf8, char* utf16, int length); +void guac_rdp_utf8_to_utf16(const unsigned char* utf8, int length, + char* utf16, int size);