aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2011-08-23 17:53:55 +0100
committerMatt Fleming <matt.fleming@intel.com>2011-08-25 11:11:19 +0100
commit3f3b9e4f1d784f6133e11d186fae70da8705ecf3 (patch)
treea42b3a6d8bc7134f7914a47c6581e7d08007e96b
parent19755f3428dc4a676d9b60cf66c71c615a4852ba (diff)
downloadefilinux-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.c34
1 files changed, 27 insertions, 7 deletions
diff --git a/fs/fs.c b/fs/fs.c
index 6d6d58c..b6835c7 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -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)