[U-Boot] [PATCH 3/4] efi_loader: correct reading of directories
Heinrich Schuchardt
xypron.glpk at gmx.de
Sat Sep 7 23:59:49 UTC 2019
EFI_FILE_PROTOCOL.Read() is used both to read files and directories.
When reaching the end of a directory we always have to return buffer size
zero irrespective of the incoming buffer size. (The described scenario for
a Shim quirk cannot arise because every directory has at least '.' and '..'
as entries.)
Even when the buffer_size is too small multiple times we have to keep a
reference to our last read directory entry.
When we return to the start of the directory via SetPosition() we must
remove the reference to a previously kept directory entry.
Signed-off-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
---
lib/efi_loader/efi_file.c | 23 +++++------------------
1 file changed, 5 insertions(+), 18 deletions(-)
diff --git a/lib/efi_loader/efi_file.c b/lib/efi_loader/efi_file.c
index 9f78b82241..74ad878217 100644
--- a/lib/efi_loader/efi_file.c
+++ b/lib/efi_loader/efi_file.c
@@ -338,7 +338,7 @@ static efi_status_t dir_read(struct file_handle *fh, u64 *buffer_size,
{
struct efi_file_info *info = buffer;
struct fs_dirent *dent;
- unsigned int required_size;
+ u64 required_size;
u16 *dst;
if (!fh->dirs) {
@@ -346,6 +346,7 @@ static efi_status_t dir_read(struct file_handle *fh, u64 *buffer_size,
fh->dirs = fs_opendir(fh->path);
if (!fh->dirs)
return EFI_DEVICE_ERROR;
+ fh->dent = NULL;
}
/*
@@ -356,28 +357,13 @@ static efi_status_t dir_read(struct file_handle *fh, u64 *buffer_size,
*/
if (fh->dent) {
dent = fh->dent;
- fh->dent = NULL;
} else {
dent = fs_readdir(fh->dirs);
}
-
if (!dent) {
- /* no more files in directory: */
- /* workaround shim.efi bug/quirk.. as find_boot_csv()
- * loops through directory contents, it initially calls
- * read w/ zero length buffer to find out how much mem
- * to allocate for the EFI_FILE_INFO, then allocates,
- * and then calls a 2nd time. If we return size of
- * zero the first time, it happily passes that to
- * AllocateZeroPool(), and when that returns NULL it
- * thinks it is EFI_OUT_OF_RESOURCES. So on first
- * call return a non-zero size:
- */
- if (*buffer_size == 0)
- *buffer_size = sizeof(*info);
- else
- *buffer_size = 0;
+ /* no more files in directory */
+ *buffer_size = 0;
return EFI_SUCCESS;
}
@@ -389,6 +375,7 @@ static efi_status_t dir_read(struct file_handle *fh, u64 *buffer_size,
fh->dent = dent;
return EFI_BUFFER_TOO_SMALL;
}
+ fh->dent = NULL;
*buffer_size = required_size;
memset(info, 0, required_size);
--
2.20.1
More information about the U-Boot
mailing list