]> git.proxmox.com Git - efi-boot-shim.git/commitdiff
simple_file: Allocate buffers for file entries
authorGary Ching-Pang Lin <glin@suse.com>
Thu, 30 May 2013 06:05:59 +0000 (14:05 +0800)
committerPeter Jones <pjones@redhat.com>
Thu, 26 Sep 2013 15:58:01 +0000 (11:58 -0400)
The dir filter appends L'/' to the directory entries without
allocating a new buffer, and this could crash the whole program.

lib/simple_file.c

index 0e5ecd251f91b1fbd06ef7d2f146191a8de9fcb8..e28827282440b44a2ba8e208f9d280f4b180e454 100644 (file)
@@ -344,9 +344,12 @@ simple_dir_filter(EFI_HANDLE image, CHAR16 *name, CHAR16 *filter,
                        goto next;
 
                if (next->Attribute & EFI_FILE_DIRECTORY) {
-                               (*result)[(*count)] = next->FileName;
-                               (*result)[(*count)][len] = '/';
-                               (*result)[(*count)++][len + 1] = '\0';
+                               (*result)[(*count)] = PoolPrint(L"%s/", next->FileName);
+                               if (!(*result)[(*count)]) {
+                                       Print(L"Failed to allocate buffer");
+                                       return EFI_OUT_OF_RESOURCES;
+                               }
+                               (*count)++;
                                goto next;
                }
 
@@ -354,7 +357,12 @@ simple_dir_filter(EFI_HANDLE image, CHAR16 *name, CHAR16 *filter,
                        offs = StrLen(filterarr[c]);
 
                        if (StrCmp(&next->FileName[len - offs], filterarr[c]) == 0) {
-                               (*result)[(*count)++] = next->FileName;
+                               (*result)[(*count)] = StrDuplicate(next->FileName);
+                               if (!(*result)[(*count)]) {
+                                       Print(L"Failed to allocate buffer");
+                                       return EFI_OUT_OF_RESOURCES;
+                               }
+                               (*count)++;
                        } else {
                                continue;
                        }
@@ -362,7 +370,7 @@ simple_dir_filter(EFI_HANDLE image, CHAR16 *name, CHAR16 *filter,
                }
 
        next:           
-               if (StrCmp(next->FileName, L"../") == 0) {
+               if (StrCmp(next->FileName, L"..") == 0) {
                        /* place .. directory first */
                        CHAR16 *tmp = (*result)[(*count) - 1];
 
@@ -392,6 +400,15 @@ simple_dir_filter(EFI_HANDLE image, CHAR16 *name, CHAR16 *filter,
        return status;
 }
 
+static void
+free_entries(CHAR16 **entries, int count)
+{
+       int i;
+
+       for (i = 0; i<count; i++)
+               FreePool(entries[i]);
+}
+
 void
 simple_file_selector(EFI_HANDLE *im, CHAR16 **title, CHAR16 *name,
                     CHAR16 *filter, CHAR16 **result)
@@ -436,8 +453,6 @@ simple_file_selector(EFI_HANDLE *im, CHAR16 **title, CHAR16 *name,
                /* ESC key */
                goto out_free;
        selected = entries[select];
-       FreePool(entries);
-       entries = NULL;
        /* note that memory used by selected is valid until dmp is freed */
        len = StrLen(selected);
        if (selected[len - 1] == '/') {
@@ -445,6 +460,9 @@ simple_file_selector(EFI_HANDLE *im, CHAR16 **title, CHAR16 *name,
 
                /* stay where we are */
                if (StrCmp(selected, L"./") == 0) {
+                       free_entries(entries, count);
+                       FreePool(entries);
+                       entries = NULL;
                        FreePool(dmp);
                        goto redo;
                } else if (StrCmp(selected, L"../") == 0) {
@@ -463,6 +481,9 @@ simple_file_selector(EFI_HANDLE *im, CHAR16 **title, CHAR16 *name,
                        if (StrCmp(name, L"\\") != 0
                            && StrCmp(&name[i], L"..") != 0) {
                                name[i] = '\0';
+                               free_entries(entries, count);
+                               FreePool(entries);
+                               entries = NULL;
                                FreePool(dmp);
                                goto redo;
                        }
@@ -478,6 +499,9 @@ simple_file_selector(EFI_HANDLE *im, CHAR16 **title, CHAR16 *name,
                /* remove trailing / */
                newname[StrLen(newname) - 1] = '\0';
 
+               free_entries(entries, count);
+               FreePool(entries);
+               entries = NULL;
                FreePool(dmp);
                FreePool(name);
                name = newname;
@@ -494,8 +518,10 @@ simple_file_selector(EFI_HANDLE *im, CHAR16 **title, CHAR16 *name,
 
  out_free:
        FreePool(dmp);
-       if (entries)
+       if (entries) {
+               free_entries(entries, count);
                FreePool(entries);
+       }
  out_free_name:
        FreePool(name);
 }