diff options
author | Matt Fleming <matt.fleming@intel.com> | 2011-08-23 17:53:55 +0100 |
---|---|---|
committer | Matt Fleming <matt.fleming@intel.com> | 2011-08-25 11:11:19 +0100 |
commit | 3f3b9e4f1d784f6133e11d186fae70da8705ecf3 (patch) | |
tree | a42b3a6d8bc7134f7914a47c6581e7d08007e96b | |
parent | 19755f3428dc4a676d9b60cf66c71c615a4852ba (diff) | |
download | efilinux-3f3b9e4f1d784f6133e11d186fae70da8705ecf3.tar.gz |
fs: Don't copy junk from locate_handle() buffer
Currently if we have more than one handle that supports
FileSystemProtocol we'll copy junk from 'fs_devices' when passing the
arguments to handle_protocol(). This is because we're using an
incorrect data type for the buffer filled out by locate_handle() - it
returns an array of EFI_HANDLE, not an array of struct fs_device's.
Instead use a temporary buffer to store the list of EFI_HANDLE's and
copy them individually to fs_devices[].handle.
Also, this is a good opportunity to clean up the error path in
fs_init() so no longer leak open handles and 'fs_devices'.
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
-rw-r--r-- | fs/fs.c | 34 |
1 files changed, 27 insertions, 7 deletions
@@ -179,9 +179,10 @@ void list_boot_devices(void) EFI_STATUS fs_init(void) { + EFI_HANDLE *buf; EFI_STATUS err; UINTN size = 0; - int i; + int i, j; size = 0; err = locate_handle(ByProtocol, &FileSystemProtocol, @@ -189,37 +190,56 @@ fs_init(void) if (err != EFI_SUCCESS && size == 0) { Print(L"No devices support filesystems\n"); - goto out; + return err; } + buf = malloc(size); + if (!buf) + return EFI_OUT_OF_RESOURCES; + nr_fs_devices = size / sizeof(EFI_HANDLE); fs_devices = malloc(sizeof(*fs_devices) * nr_fs_devices); - if (!fs_devices) + if (!fs_devices) { + err = EFI_OUT_OF_RESOURCES; goto out; + } err = locate_handle(ByProtocol, &FileSystemProtocol, - NULL, &size, (void **)fs_devices); + NULL, &size, (void **)buf); for (i = 0; i < nr_fs_devices; i++) { EFI_FILE_IO_INTERFACE *io; EFI_FILE_HANDLE fh; EFI_HANDLE dev_handle; - dev_handle = fs_devices[i].handle; + dev_handle = buf[i]; err = handle_protocol(dev_handle, &FileSystemProtocol, (void **)&io); if (err != EFI_SUCCESS) - goto out; + goto close_handles; err = volume_open(io, &fh); if (err != EFI_SUCCESS) - goto out; + goto close_handles; + fs_devices[i].handle = dev_handle; fs_devices[i].fh = fh; } out: + free(buf); return err; + +close_handles: + for (j = 0; j < i; j++) { + EFI_FILE_HANDLE fh; + + fh = fs_devices[j].fh; + uefi_call_wrapper(fh->Close, 1, fh); + } + + free(fs_devices); + goto out; } void fs_exit(void) |