|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH] efi: remove unreachable code in read_file()
On 8/14/25 11:23, Jan Beulich wrote:
> On 12.08.2025 21:17, Dmytro Prokopchuk1 wrote:
>> MISRA C Rule 2.1 states: "A project shall not contain unreachable code."
>>
>> Function `PrintErrMesg(const CHAR16*, EFI_STATUS)` isn't intended to return
>> control to its caller. At the end, it calls `blexit()`, which, in turn,
>> invokes the `__builtin_unreachable()` function, making subsequent return
>> statements in `read_file()` unreachable:
>>
>> PrintErrMesg(name, ret);
>> /* not reached */
>> return false;
>>
>> This also causes unreachability of the code meant to handle `read_file()`
>> errors, as seen in these examples:
>>
>> In this block:
>> if ( read_file(dir_handle, file_name, &cfg, NULL) )
>> break;
>> *tail = 0;
>> }
>> if ( !tail )
>> blexit(L"No configuration file found.");
>>
>> And here:
>> else if ( !read_file(dir_handle, cfg_file_name, &cfg, NULL) )
>> blexit(L"Configuration file not found.");
>>
>> And here:
>> if ( !read_file(dir_handle, s2w(&name), &cfg, NULL) )
>> {
>> PrintStr(L"Chained configuration file '");
>> PrintStr(name.w);
>> efi_bs->FreePool(name.w);
>> blexit(L"'not found.");
>> }
>>
>> The issue arises because when an error occurs inside `read_file()`, it calls
>> `PrintErrMesg()` and does not return to the caller.
>>
>> To address this the following changes are applied:
>> 1. Remove `PrintErrMesg(name, ret);` from the `read_file()` function.
>> 2. Replaced it with `PrintErr(name);`, which prints the file name and returns
>> control to the caller.
>> 3. Change the `read_file()` return type from `bool` to `EFI_STATUS`, allowing
>> file operation result codes to be returned to the caller.
>> 4. Properly handle error codes returned from the `read_file()` function in
>> the
>> relevant areas of the code.
>> 5. Replace `blexit()` calls with informative error codes using
>> `PrintErrMesg()`
>> where appropriate.
>>
>> Signed-off-by: Dmytro Prokopchuk <dmytro_prokopchuk1@xxxxxxxx>
>> ---
>> Test CI pipeline:
>> https://gitlab.com/xen-project/people/dimaprkp4k/xen/-/pipelines/1980590118
>> ---
>> xen/common/efi/boot.c | 57 ++++++++++++++++++++++++++++++-------------
>> 1 file changed, 40 insertions(+), 17 deletions(-)
>>
>> diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
>> index 50ff1d1bd2..ddbafb2f9c 100644
>> --- a/xen/common/efi/boot.c
>> +++ b/xen/common/efi/boot.c
>> @@ -132,7 +132,7 @@ struct file {
>> };
>> };
>>
>> -static bool read_file(EFI_FILE_HANDLE dir_handle, CHAR16 *name,
>> +static EFI_STATUS read_file(EFI_FILE_HANDLE dir_handle, CHAR16 *name,
>> struct file *file, const char *options);
>> static bool read_section(const EFI_LOADED_IMAGE *image, const CHAR16 *name,
>> struct file *file, const char *options);
>> @@ -782,7 +782,7 @@ static void __init handle_file_info(const CHAR16 *name,
>> efi_arch_handle_module(file, name, options);
>> }
>>
>> -static bool __init read_file(EFI_FILE_HANDLE dir_handle, CHAR16 *name,
>> +static EFI_STATUS __init read_file(EFI_FILE_HANDLE dir_handle, CHAR16 *name,
>> struct file *file, const char *options)
>> {
>> EFI_FILE_HANDLE FileHandle = NULL;
>> @@ -791,7 +791,7 @@ static bool __init read_file(EFI_FILE_HANDLE dir_handle,
>> CHAR16 *name,
>> const CHAR16 *what = NULL;
>>
>> if ( !name )
>> - PrintErrMesg(L"No filename", EFI_OUT_OF_RESOURCES);
>> + return EFI_INVALID_PARAMETER;
>
> Why the change in error code? EFI_OUT_OF_RESOURCES() was used deliberately for
> cases where the result of s2w() is passed directly into here.
>
> Between this hunk and ...
>
>> @@ -842,7 +842,7 @@ static bool __init read_file(EFI_FILE_HANDLE dir_handle,
>> CHAR16 *name,
>>
>> efi_arch_flush_dcache_area(file->ptr, file->size);
>>
>> - return true;
>> + return ret;
>>
>> fail:
>> if ( FileHandle )
>
> ... this one there's at least one "return false" which you leave untouched,
> thus
> wrongly reporting EFI_SUCCESS now to the caller.
>
>> @@ -850,10 +850,9 @@ static bool __init read_file(EFI_FILE_HANDLE
>> dir_handle, CHAR16 *name,
>>
>> PrintErr(what);
>> PrintErr(L" failed for ");
>> - PrintErrMesg(name, ret);
>> + PrintErr(name);
>>
>> - /* not reached */
>> - return false;
>> + return ret;
>> }
>
> With the comment here - possibly adjusted to become a SAF one - all should be
> fine with no other changes? Because of the other "return false" callers simply
> can't assume the function would never indicate failure back to them. (New
> "return false" could in principle also appear, which is why I think the base
> structure wants keeping as is, including in the callers.)
>
> Jan
Yes, probably the deviation is better in such case, that changing code
and introducing new errors.
Dmytro.
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |