[gnome-remote-desktop] clipboard-rdp: Validate filename before processing it



commit b16379b4a84220e60ef726673db3bbddca432da6
Author: Pascal Nowack <Pascal Nowack gmx de>
Date:   Wed Aug 10 07:44:45 2022 +0200

    clipboard-rdp: Validate filename before processing it
    
    The filename in a FILEDESCRIPTORW structure is supposed to be a 260
    long null terminated Unicode string.
    These 260 characters also include the null terminator.
    To prevent a potential out-of-bounds read due to malicious clients,
    check these constraints.

 src/grd-clipboard-rdp.c | 27 +++++++++++++++++++++++----
 1 file changed, 23 insertions(+), 4 deletions(-)
---
diff --git a/src/grd-clipboard-rdp.c b/src/grd-clipboard-rdp.c
index 4147fe29..55dc996d 100644
--- a/src/grd-clipboard-rdp.c
+++ b/src/grd-clipboard-rdp.c
@@ -1685,6 +1685,23 @@ extract_format_data_response (GrdClipboardRdp               *clipboard_rdp,
   return response_ok && *data;
 }
 
+static gboolean
+filedescriptorw_filename_is_valid (const WCHAR *filename)
+{
+  uint16_t i;
+
+  if (filename[0] == L'\0')
+    return FALSE;
+
+  for (i = 1; i < 260; ++i)
+    {
+      if (filename[i] == L'\0')
+        return TRUE;
+    }
+
+  return FALSE;
+}
+
 static uint8_t *
 get_uri_list_from_packet_file_list (GrdClipboardRdp *clipboard_rdp,
                                     uint8_t         *src_data,
@@ -1693,7 +1710,7 @@ get_uri_list_from_packet_file_list (GrdClipboardRdp *clipboard_rdp,
                                     gboolean         has_clip_data_id,
                                     uint32_t         clip_data_id)
 {
-  FILEDESCRIPTORW *files = NULL;
+  g_autofree FILEDESCRIPTORW *files = NULL;
   FILEDESCRIPTORW *file;
   uint32_t n_files = 0;
   g_autofree char *clip_data_dir_name = NULL;
@@ -1715,11 +1732,15 @@ get_uri_list_from_packet_file_list (GrdClipboardRdp *clipboard_rdp,
     {
       file = &files[i];
 
+      if (!filedescriptorw_filename_is_valid (file->cFileName))
+        {
+          g_array_free (dst_data, TRUE);
+          return NULL;
+        }
       if (ConvertFromUnicode (CP_UTF8, 0, file->cFileName, -1, &filename,
                               0, NULL, NULL) <= 0)
         {
           g_array_free (dst_data, TRUE);
-          g_free (files);
           return NULL;
         }
       if (strchr (filename, '\\'))
@@ -1743,8 +1764,6 @@ get_uri_list_from_packet_file_list (GrdClipboardRdp *clipboard_rdp,
 
   *dst_size = dst_data->len;
 
-  g_free (files);
-
   return (uint8_t *) g_array_free (dst_data, FALSE);
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]