mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 23:24:38 +00:00
efi_loader: correct reading of directories
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@gmx.de>
This commit is contained in:
parent
87c4840610
commit
83a74ad143
1 changed files with 5 additions and 18 deletions
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue