mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
xen/efi: Fix crash with initial empty EFI options
EFI code path split options from EFI LoadOptions fields in 2 pieces, first EFI options, second Xen options. "get_argv" function is called first to get the number of arguments in the LoadOptions, second, after allocating enough space, to fill some "argc"/"argv" variable. However the first parsing could be different from second as second is able to detect "--" argument separator. So it was possible that "argc" was bigger than the initialized portion of "argv" array, leading to potential uninitialized pointer dereference, in particular a string like "-- a b c" would lead to crashes. Using EFI shell is possible to pass any kind of string in LoadOptions. Fixes:bf6501a62e("x86-64: EFI boot code") Signed-off-by: Frediano Ziglio <frediano.ziglio@cloud.com> Reviewed-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com> master commit:375f0dd538master date: 2025-09-01 13:07:01 +0200
This commit is contained in:
1 parent
c275e90b3c
commit
dc04d4e8c7
1 file changed
+7
-6
@@ -327,10 +327,11 @@ static unsigned int __init get_argv(unsigned int argc, CHAR16 **argv,
|
||||
|
||||
if ( argc )
|
||||
{
|
||||
argc = 0;
|
||||
cmdline = data + *offset;
|
||||
/* EFI_LOAD_OPTION does not supply an image name as first component. */
|
||||
if ( *offset )
|
||||
*argv++ = NULL;
|
||||
argv[argc++] = NULL;
|
||||
}
|
||||
else if ( size > sizeof(*cmdline) && !(size % sizeof(*cmdline)) &&
|
||||
(wmemchr(data, 0, size / sizeof(*cmdline)) ==
|
||||
@@ -391,14 +392,14 @@ static unsigned int __init get_argv(unsigned int argc, CHAR16 **argv,
|
||||
++argc;
|
||||
else if ( prev && wstrcmp(prev, L"--") == 0 )
|
||||
{
|
||||
--argv;
|
||||
--argc;
|
||||
if ( options )
|
||||
*options = cmdline;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
*argv++ = prev = ptr;
|
||||
argv[argc++] = prev = ptr;
|
||||
*ptr = *cmdline;
|
||||
*++ptr = 0;
|
||||
}
|
||||
@@ -406,7 +407,7 @@ static unsigned int __init get_argv(unsigned int argc, CHAR16 **argv,
|
||||
prev_sep = cur_sep;
|
||||
}
|
||||
if ( argv )
|
||||
*argv = NULL;
|
||||
argv[argc] = NULL;
|
||||
return argc;
|
||||
}
|
||||
|
||||
@@ -1302,8 +1303,8 @@ void EFIAPI __init noreturn efi_start(EFI_HANDLE ImageHandle,
|
||||
(argc + 1) * sizeof(*argv) +
|
||||
loaded_image->LoadOptionsSize,
|
||||
(void **)&argv) == EFI_SUCCESS )
|
||||
get_argv(argc, argv, loaded_image->LoadOptions,
|
||||
loaded_image->LoadOptionsSize, &offset, &options);
|
||||
argc = get_argv(argc, argv, loaded_image->LoadOptions,
|
||||
loaded_image->LoadOptionsSize, &offset, &options);
|
||||
else
|
||||
argc = 0;
|
||||
for ( i = 1; i < argc; ++i )
|
||||
|
||||