[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v6] hw/core/loader-fit: fix freeing errp in fit_load_fdt
From: |
Markus Armbruster |
Subject: |
Re: [PATCH v6] hw/core/loader-fit: fix freeing errp in fit_load_fdt |
Date: |
Sat, 30 Nov 2019 20:48:35 +0100 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/26.2 (gnu/linux) |
Markus Armbruster <address@hidden> writes:
> Vladimir Sementsov-Ogievskiy <address@hidden> writes:
>
>> 29.11.2019 17:11, Vladimir Sementsov-Ogievskiy wrote:
>>> 29.11.2019 17:03, Markus Armbruster wrote:
>>>> Vladimir Sementsov-Ogievskiy <address@hidden> writes:
>>>>
>>>>> fit_load_fdt forget to check that errp is not NULL and to zero it after
>>>>> freeing. Fix it.
>>>>>
>>>>> Signed-off-by: Vladimir Sementsov-Ogievskiy <address@hidden>
>>>>> Reviewed-by: Eric Blake <address@hidden>
>>>>> ---
>>>>> hw/core/loader-fit.c | 5 ++++-
>>>>> 1 file changed, 4 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/hw/core/loader-fit.c b/hw/core/loader-fit.c
>>>>> index 953b16bc82..3ee9fb2f2e 100644
>>>>> --- a/hw/core/loader-fit.c
>>>>> +++ b/hw/core/loader-fit.c
>>>>> @@ -200,7 +200,10 @@ static int fit_load_fdt(const struct fit_loader
>>>>> *ldr, const void *itb,
>>>>> err = fit_image_addr(itb, img_off, "load", &load_addr, errp);
>>>>> if (err == -ENOENT) {
>>>>> load_addr = ROUND_UP(kernel_end, 64 * KiB) + (10 * MiB);
>>>>> - error_free(*errp);
>>>>> + if (errp) {
>>>>> + error_free(*errp);
>>>>> + *errp = NULL;
>>>>> + }
>>>>> } else if (err) {
>>>>> error_prepend(errp, "unable to read FDT load address from FIT:
>>>>> ");
>>>>> ret = err;
>>>>
>>>> This fixes latent bugs when fit_image_addr() fails with ENOENT:
>>>>
>>>> * If a caller passes a null @errp, we crash dereferencing it
>>>>
>>>> * Else, we pass a dangling Error * to the caller, and return success.
>>>> If a caller dereferences the Error * regardless, we have a
>>>> use-after-free.
>>>>
>>>> Not fixed:
>>>>
>>>> * If a caller passes &error_abort or &error_fatal, we die instead of
>>>> taking the recovery path.
>>>
>>> No, if it is error_abort or error_fatal, we will not reach this point, the
>>> execution
>>> finished before, when error was set.
>>
>> Ah, that is what you mention.. Hmm. Is it bad? At least crashing on
>> error_abort without any recovery should not be bad..
>
> Latent bugs aren't bad, but they could possibly become bad :)
>
> When you pass &err to fit_load_fdt(), where @err is a local variable,
> the ENOENT case is not actually an error; fit_load_fdt() recovers fine
> and succeeds.
>
> When you pass &error_fatal or &error_abort, it should likewise not be an
> error.
>
> General rule: when you want to handle some (or all) of a function's
> errors yourself, you must not pass your own @errp argument. Instead,
> pass &err and propagate the errors you don't handle yourself with
> error_propagate(errp, err).
>
>>>> We need to use a local_err here.
>>>>
>>>> I'll search for the pattern, and post fix(es).
>
> Found several bugs already...
[PATCH 00/21] Error handling fixes, may contain 4.2 material
Message-Id: <address@hidden>
I hope it doesn't clash too badly with your work.
PATCH 10 fixes the one we discussed above.