[PATCH 1/2] efi_loader: Implement FileLoad2 for initramfs loading

Ilias Apalodimas ilias.apalodimas at linaro.org
Thu Mar 12 08:17:42 CET 2020


On Thu, Mar 12, 2020 at 03:58:03PM +0900, AKASHI Takahiro wrote:
> On Thu, Mar 12, 2020 at 08:29:38AM +0200, Ilias Apalodimas wrote:
> > Akashi-san,
> > 
> > On Thu, Mar 12, 2020 at 02:28:45PM +0900, AKASHI Takahiro wrote:
> > > Ilias,
> > > 
> > > I haven't followed this thread.
> > > 
> > > On Fri, Feb 21, 2020 at 09:55:45AM +0200, Ilias Apalodimas wrote:
> > > > Following kernel's proposal for an arch-agnostic initrd loading
> > > > mechanism [1] let's implement the U-boot counterpart.
> > > > This new approach has a number of advantages compared to what we did up
> > > > to now. The file is loaded into memory only when requested limiting the
> > > > area of TOCTOU attacks. Users will be allowed to place the initramfs
> > > > file on any u-boot accessible partition instead of just the ESP one.
> > > > Finally this is an attempt of a generic interface across architectures
> > > > in the linux kernel so it makes sense to support that.
> > > > 
> > > > The file location is intentionally only supported as a config option
> > > > argument(CONFIG_EFI_INITRD_FILESPEC), in an effort to enhance security.
> > > > Although U-boot is not responsible for verifying the integrity of the
> > > > initramfs, we can enhance the offered security by only accepting a
> > > > built-in option, which will be naturally verified by UEFI Secure Boot.
> > > > This can easily change in the future if needed and configure that via ENV
> > > > or UEFI variable.
> > > 
> > > What if we have several bootable images with different initrd
> > > required at the same time? For example, we may install ubuntu 16.04,
> > > 18.04 etc to the same device (and then boot one of them via grub).
> > > 
> > > Since the guid is unique, U-Boot doesn't have any measure to identify which
> > > initrd be exported via FILE2_PROTOCOL.
> > > In this sense, I don't think using a config option is a good idea in general.
> > 
> > Can't you concatenate multiple cpio archives for this? I haven't checked this
> > personally but i remember distros doing it to add firmware files they need for
> > example. It might not be ideal because you may need different user-space
> > program versions or different versions of the same script(??)
> 
> I wonder think why it is not a problem.
> 

I never said it wasn't, on the contrary, i pointed out cases were
concatenating cpio's might not be enough.

> > but the linux 
> > module loading part, of different kernel revisions, should be there.
> 
> Can we assume that this is only the use of initrd?
> 

Of course not.

> > I don't have any strong preference on this anyway hence my commit
> > message, it's just another naive protection, since the user can always replace
> > the initramfs using the same name and break out of this. I never needed multiple
> > initrd files so I preferred the config option. If people need a config option
> > it's easily extensible.
> 
> How? I don't think it's trivial.

Parse an env variable and override the config option?
Something like:
setenv efi_initrd 'mmc 0:1 foo.cpio.gz' -> env_get("efi_initrd")
wouldn't work?

> 
> > > > +#define EFI_LOAD_FILE_PROTOCOL_GUID \
> > [...]
> > > > +	EFI_GUID(0x56ec3091, 0x954c, 0x11d2, \
> > > > +		 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
> > > 
> > > Do you need this definition?
> > > 
> > 
> > Not really it just felt weird adding LOAD_FILE2 without the LOAD_FILE
> > definition.
> > 
> > > > +#define EFI_LOAD_FILE2_PROTOCOL_GUID \
> > > > +	EFI_GUID(0x4006c0c1, 0xfcb3, 0x403e, \
> > > > +		 0x99, 0x6d, 0x4a, 0x6c, 0x87, 0x24, 0xe0, 0x6d)
> > > > +
> > > > --- /dev/null
> > [...]
> > > > +++ b/include/efi_load_initrd.h
> > > 
> > > It might be unlikely, but the file name should be more generic
> > > for potential enhancement.
> > > 
> > 
> > This is defining a very specific GUID for initramfs that Linux consumes to load
> > the file, I'd rather keep it as is.
> 
> I didn't intent the guid, but a file name.

Yes my response is for the file name. It serves a sole purpose, define the 
explicit GUID linux expects.

> > > > @@ -0,0 +1,25 @@
> > [...]
> > > > +
> > > > +config EFI_INITRD_FILESPEC
> > > > +	string "initramfs path"
> > > > +	default "host 0:1 initrd"
> > > 
> > > "host" interface makes sense only on sandbox, which will not be expected
> > > to be able to boot any linux kernel.
> > > So this default value is inappropriate anyway.
> > > 
> > 
> > Not really. The user *must* have an idea on what he is doing and this is the
> > default config we need to run on the sandbox. So it serves both as an example
> > and a defult config for the sandbox testing.
> 
> I don't think we can boot a linux kernel from U-Boot on sandbox.
> 

We run the sefltest though, which is replicating the Linux efi stub 
functionality.

> > > > +	depends on EFI_LOAD_FILE2_INITRD
> > > > +	help
> > > > +	  Full path of the initramfs file, e.g. mmc 0:2 initramfs.cpio.gz.
> > > > +
> > > >  endif
> > > > diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
> > > > index 04dc8648512b..9b3b70447336 100644
> > > > --- a/lib/efi_loader/Makefile
> > > > +++ b/lib/efi_loader/Makefile
> > > > @@ -43,3 +43,4 @@ obj-$(CONFIG_NET) += efi_net.o
> > > >  obj-$(CONFIG_GENERATE_ACPI_TABLE) += efi_acpi.o
> > > >  obj-$(CONFIG_GENERATE_SMBIOS_TABLE) += efi_smbios.o
> > > >  obj-$(CONFIG_EFI_RNG_PROTOCOL) += efi_rng.o
> > > > +obj-$(CONFIG_EFI_LOAD_FILE2_INITRD) += efi_load_initrd.o
> > > > diff --git a/lib/efi_loader/efi_load_initrd.c b/lib/efi_loader/efi_load_initrd.c
> > > > new file mode 100644
> > > > index 000000000000..574a83d7e308
> > > > --- /dev/null
> > > > +++ b/lib/efi_loader/efi_load_initrd.c
> > > 
> > > I'd prefer efi_file_initrd.c for similarity to efi_file.c, or
> > > more specifically efi_linux.c.
> > > 
> > 
> > I can send a patch renaming those but i think it's pointless.
> > The filename describes exactly what's the intent imho.
> 
> What if we will want to add another FILE2_PROTOCOL or linux-specifc
> hack?
> Now I believe that OS (or platform)-dependent implementation
> should go into a separate directory, like lib/efi_linux/...
> for clarification.
> 

I am not against that, i just think the tons of comments are already enough. 
But i see the point in the long run, assuming we'll add enough OS-specific
options to justify this.

> > > > @@ -0,0 +1,198 @@
> > > > +// SPDX-License-Identifier: GPL-2.0+
> > > > +/*

[...]

> > > I think that we should return a better error code rather than NOT_FOUND.
> > > 
> > 
> > Like? The spec has a specific set of returns codes you can use there, 
> > EFI_UNSUPPORTED
> > EFI_INVALID_PARAMETER
> > EFI_NO_MEDIA
> > EFI_DEVICE_ERROR
> > EFI_NO_RESPONSE
> > EFI_NOT_FOUND
> > EFI_ABORTED
> > EFI_BUFFER_TOO_SMALL
> > 
> > Is there anything you like better?
> 
> In most of all cases, OUT_OF_RESOURCES.

If i am not reading the spec wrong you *can't* return that here and even if you
could, the majority of error cases fail if the file was not found.
Maybe apart from this:
ret = fs_set_blk_dev(dev, part, FS_TYPE_ANY);
if (ret) {
	status = EFI_NO_MEDIA;
   	goto out;
}


Thanks
/Ilias


More information about the U-Boot mailing list