Skip to content
Snippets Groups Projects
Commit c5763039 authored by Chris Coulson's avatar Chris Coulson Committed by Colin Watson
Browse files

Fix a regression caused by "efi: fix some malformed device path arithmetic errors"

This commit introduced a bogus check inside copy_file_path to
determine whether the destination grub_efi_file_path_device_path_t
was valid before anything was copied to it. Depending on the
contents of the heap buffer, this check could fail which would
result in copy_file_path returning early.

Without any error propagated to the caller, make_file_path would
then try to advance the invalid device path node with
GRUB_EFI_NEXT_DEVICE_PATH, which would also fail, returning a NULL
pointer that would subsequently be dereferenced.

Remove the bogus check, and also propagate errors from copy_file_path.

Patch-Name: efi-malformed-device-path-2.patch
parent 9735a4b2
No related branches found
No related tags found
No related merge requests found
......@@ -106,7 +106,7 @@ grub_chainloader_boot (void)
return grub_errno;
}
static void
static grub_err_t
copy_file_path (grub_efi_file_path_device_path_t *fp,
const char *str, grub_efi_uint16_t len)
{
......@@ -116,15 +116,9 @@ copy_file_path (grub_efi_file_path_device_path_t *fp,
fp->header.type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE;
fp->header.subtype = GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE;
if (!GRUB_EFI_DEVICE_PATH_VALID ((grub_efi_device_path_t *)fp))
{
grub_error (GRUB_ERR_BAD_ARGUMENT, "EFI Device Path is invalid");
return;
}
path_name = grub_calloc (len, GRUB_MAX_UTF16_PER_UTF8 * sizeof (*path_name));
if (!path_name)
return;
return grub_error (GRUB_ERR_OUT_OF_MEMORY, "failed to allocate path buffer");
size = grub_utf8_to_utf16 (path_name, len * GRUB_MAX_UTF16_PER_UTF8,
(const grub_uint8_t *) str, len, 0);
......@@ -137,6 +131,7 @@ copy_file_path (grub_efi_file_path_device_path_t *fp,
fp->path_name[size++] = '\0';
fp->header.length = size * sizeof (grub_efi_char16_t) + sizeof (*fp);
grub_free (path_name);
return GRUB_ERR_NONE;
}
static grub_efi_device_path_t *
......@@ -195,13 +190,19 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename)
d = (grub_efi_device_path_t *) ((char *) file_path
+ ((char *) d - (char *) dp));
grub_efi_print_device_path (d);
copy_file_path ((grub_efi_file_path_device_path_t *) d,
dir_start, dir_end - dir_start);
if (copy_file_path ((grub_efi_file_path_device_path_t *) d,
dir_start, dir_end - dir_start) != GRUB_ERR_NONE)
{
fail:
grub_free (file_path);
return 0;
}
/* Fill the file path for the file. */
d = GRUB_EFI_NEXT_DEVICE_PATH (d);
copy_file_path ((grub_efi_file_path_device_path_t *) d,
dir_end + 1, grub_strlen (dir_end + 1));
if (copy_file_path ((grub_efi_file_path_device_path_t *) d,
dir_end + 1, grub_strlen (dir_end + 1)) != GRUB_ERR_NONE)
goto fail;
/* Fill the end of device path nodes. */
d = GRUB_EFI_NEXT_DEVICE_PATH (d);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment