[U-Boot] [RFC 1/1] cmd: fs: fix data abort in load cmd
Heinrich Schuchardt
xypron.glpk at gmx.de
Wed Apr 10 18:36:16 UTC 2019
On 4/10/19 8:48 AM, Igor Opaniuk wrote:
> Hi Heinrich,
>
> Thanks for looking into this,
>
> On Tue, Apr 9, 2019 at 11:28 PM Heinrich Schuchardt <xypron.glpk at gmx.de> wrote:
>>
>> On 4/9/19 3:08 PM, Igor Opaniuk wrote:
>>> With CONFIG_CMD_BOOTEFI=y, load command causes data abort
>>> when path_to_uefi(fp->str, path) tries to write uefi path out of
>>> bounds of u16 str[] array (check efi_device_path_file_path struct for
>>> details). This is caused by unproper handling of void *buf pointer
>>> in efi_dp_from_file(), particularly when the buf pointer value is changed
>>> after dp_part_fill() invocation.
>>>
>>>> load usb 0:1 0x12000000 imx6dl-colibri-eval-v3.dtb
>>> pc : [<2fab48ae>] lr : [<2fab4339>]
>>> reloc pc : [<178338ae>] lr : [<17833339>]
>>> sp : 2da77120 ip : 00000003 fp : 00000005
>>> r10: 2daa31d0 r9 : 2da80ea8 r8 : 00000001
>>> r7 : 2daa3098 r6 : 2ca75040 r5 : 2da77148 r4 : 0000003a
>>> r3 : 00000069 r2 : 2ca750a3 r1 : 2daa3104 r0 : 2ca7509f
>>> Flags: nzCv IRQs off FIQs off Mode SVC_32
>>> Code: 4630fb31 81f0e8bd e7d84606 bf082b2f (f822235c)
>>> Resetting CPU ...
>>>
>>
>> Thanks for reporting the problem.
>>
>>> With the change suggested:
>>>
>>>> load usb 0:1 0x12000000 imx6dl-colibri-eval-v3.dtb
>>> 5675440 bytes read in 188 ms (28.8 MiB/s)
>>>
>>> Signed-off-by: Igor Opaniuk <igor.opaniuk at toradex.com>
>>> ---
>>> lib/efi_loader/efi_device_path.c | 2 +-
>>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
>>> index 53b40c8c3c..97b4356167 100644
>>> --- a/lib/efi_loader/efi_device_path.c
>>> +++ b/lib/efi_loader/efi_device_path.c
>>> @@ -829,7 +829,7 @@ struct efi_device_path *efi_dp_from_file(struct blk_desc *desc, int part,
>>> buf = dp_part_fill(buf, desc, part);
>>>
>>> /* add file-path: */
>>> - fp = buf;
>>> + fp = start;
>>
>> This cannot be correct. dp_part_fill() is meant to set buf to the end of
>> the partition device path, e.g.
>> /VenHw(dbca4c98-6cb0-694d-0872-819c650cb7b8)/HD(1,MBR,0xd1535d21,0x1,0x7f)
>
> That's why I added RFC tag, as I definitely don't understand the full
> picture of what's going here(and lack of time to discover) :)
>
>>
>> In the lines below we want to add a further device path node with the
>> filename followed by the end node, e.g.
>>
>> /VenHw(dbca4c98-6cb0-694d-0872-819c650cb7b8)/HD(1,MBR,0xd1535d21,0x1,0x7f)/Shell.efi
>>
>> With your patch we end up with a device path containing only the file
>> name and the end node, e.g.
>>
>> /Shell.efi
>
> Thanks for the explanation.
>
>>
>> If you think this is an out of bound problem we must fix the estimation
>> of the device path size.
>>
>> For better understanding the problem could you, please, print the value
>> of dpsize and then call dp_alloc() with a sufficiently large argument.
>>
>> Before the return statement add
>>
>> printf("desc %p\n", desc);
>> printf("dp length %zu\n", efi_dp_size(start));
>>
>> This should provide the calculated device path length and its actual size.
>
> So with the changes:
>
> diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
> index 97b4356167..ef707e2505 100644
> --- a/lib/efi_loader/efi_device_path.c
> +++ b/lib/efi_loader/efi_device_path.c
> @@ -821,6 +821,8 @@ struct efi_device_path *efi_dp_from_file(struct
> blk_desc *desc, int part,
> fpsize = sizeof(struct efi_device_path) + 2 * (strlen(path) + 1);
> dpsize += fpsize;
>
> + printf("dpsize %zu\n", dpsize);
> +
> start = buf = dp_alloc(dpsize + sizeof(END));
> if (!buf)
> return NULL;
> @@ -837,6 +839,8 @@ struct efi_device_path *efi_dp_from_file(struct
> blk_desc *desc, int part,
> buf += fpsize;
>
> *((struct efi_device_path *)buf) = END;
> + printf("desc %p\n", desc);
> + printf("dp length %zu\n", efi_dp_size(start));
>
> return start;
> }
>
> Output:
> dpsize 153
> desc 2daa3d30
>
> And U-boot hangs on efi_dp_size(start) invocation, so I never receive
> any output from the last printf() invocation.
In
http://git.denx.de/?p=u-boot-efi.git;a=shortlog;h=refs/heads/efi-2019-07
I have already added a patch the problem with efi_dp_size().
efi_loader: move efi_save_gd() call to board_r.c
http://git.denx.de/?p=u-boot-efi.git;a=commit;h=5658c83d1c3637d4aa5bc366ab987b776ea105eb
So I suggest that you start from the efi-2019-07 branch.
Regards
Heinrich
>
>> Please, indicate the config file that you are using.
>
> colibri_imx6_defconfig
>
>>
>> Best regards
>>
>> Heinrich
>>
>>> fp->dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE;
>>> fp->dp.sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH;
>>> fp->dp.length = fpsize;
>>>
>>
>> _______________________________________________
>> U-Boot mailing list
>> U-Boot at lists.denx.de
>> https://lists.denx.de/listinfo/u-boot
>
>
>
More information about the U-Boot
mailing list