diff options
| author | Gary Ching-Pang Lin <glin@suse.com> | 2013-05-30 14:05:59 +0800 |
|---|---|---|
| committer | Peter Jones <pjones@redhat.com> | 2013-09-26 11:58:01 -0400 |
| commit | b82d6d7cb1f235384251e45c553f5d6f50c033ee (patch) | |
| tree | c9e19cbc402d9b44028bc04081c167030ce813d6 /lib/simple_file.c | |
| parent | d359712e1b1b0ed7ca611dfd11d9f78754a7a013 (diff) | |
| download | efi-boot-shim-b82d6d7cb1f235384251e45c553f5d6f50c033ee.tar.gz efi-boot-shim-b82d6d7cb1f235384251e45c553f5d6f50c033ee.zip | |
simple_file: Allocate buffers for file entries
The dir filter appends L'/' to the directory entries without
allocating a new buffer, and this could crash the whole program.
Diffstat (limited to 'lib/simple_file.c')
| -rw-r--r-- | lib/simple_file.c | 42 |
1 files changed, 34 insertions, 8 deletions
diff --git a/lib/simple_file.c b/lib/simple_file.c index 0e5ecd25..e2882728 100644 --- a/lib/simple_file.c +++ b/lib/simple_file.c @@ -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); } |
