Discussion:
boot1.efi future
Warner Losh
2017-10-17 23:18:24 UTC
Permalink
I'd like to remove boot1.efi. It's no longer relevant. It was a useful hack
to get us going, but now it's becoming more of a liability than a win.

There's a lot of work that has been put into it so it can understand every
filesystem. However, in doing so boot1.efi has morphed into a loader.efi
without the scripting interpreter. Let's just kill boot1.efi and load the
full-featured loader directly.

boot1.efi used to have a role to play. It was a tiny, rarely changing bit
of glue in the UEFI world. It is now none of those things. It has become
rather large and bloated, and there's work to make it even more so.

My proposal is to fix the one bug in loader.efi that would preclude its use
as a primary boot loader (it sometimes guesses wrong for currdev and
loaddev). Once we've done that, we'll use it where we use boot1.efi today.
It would also simplify the load process and make it easier to implement the
full EFI Boot Manager protocol from the UEFI specifications. It should also
make secure boot easier to bring to market.

This dovetails nicely into some of the other changes on-tap for FreeBSD 12.
efibootmgr is coming soon (I'm reviewing the code from a coworker now).
There's plans to move the FreeBSD boot loader to
\efi\FreeBSD\loader-$ARCH.efi when that goes in, since we'll be able to
point the LoadOptions to that. There's plans to make the installer create
the EFI partition rather than just dd the efifat file we're doing today.
Plus, there's work underway to move all the boot block installation stuff
to a new script (install-boot) as well as efforts to make images for any
bootable system (spin).

There's lots of details to get right before we can make the final switch,
but I think it's in the interest of the project to do so.

Comments?

Warner
Warner Losh
2017-10-18 03:16:12 UTC
Permalink
Post by Warner Losh
I'd like to remove boot1.efi. It's no longer relevant. It was a useful hack
to get us going, but now it's becoming more of a liability than a win.
There's a lot of work that has been put into it so it can understand every
filesystem. However, in doing so boot1.efi has morphed into a loader.efi
without the scripting interpreter. Let's just kill boot1.efi and load the
full-featured loader directly.
boot1.efi used to have a role to play. It was a tiny, rarely changing bit
of glue in the UEFI world. It is now none of those things. It has become
rather large and bloated, and there's work to make it even more so.
My proposal is to fix the one bug in loader.efi that would preclude its use
as a primary boot loader (it sometimes guesses wrong for currdev and
loaddev). Once we've done that, we'll use it where we use boot1.efi today.
It would also simplify the load process and make it easier to implement the
full EFI Boot Manager protocol from the UEFI specifications. It should also
make secure boot easier to bring to market.
This dovetails nicely into some of the other changes on-tap for FreeBSD 12.
efibootmgr is coming soon (I'm reviewing the code from a coworker now).
There's plans to move the FreeBSD boot loader to
\efi\FreeBSD\loader-$ARCH.efi when that goes in, since we'll be able to
point the LoadOptions to that. There's plans to make the installer create
the EFI partition rather than just dd the efifat file we're doing today.
Plus, there's work underway to move all the boot block installation stuff
to a new script (install-boot) as well as efforts to make images for any
bootable system (spin).
There's lots of details to get right before we can make the final switch,
but I think it's in the interest of the project to do so.
Comments?
I haven't been following the EFI story.
Is there a doc that describes the current FreeBSD EFI boot process?
I wrote one for the EFI Boot Manger stuff.
https://docs.google.com/document/d/1aK9IqF-60JPEbUeSAUAkYjF2W_8EnmczFs6RqCT90Jg/edit#heading=h.jdwnfj2sxlfb
and nobody objected to it in a timely fashion, so it's the implementation
path I set out on...

But long story short: We bogusly put boot1.efi into \efi\boot\bootx64.efi
and hope for the best (since it's the default for removable media and most
BIOSes use it as a default for non-removable media too). If it loads, we
search in the vain hope that we might guess which of the /boot/loader.efi's
might be out there is the right one and jump to it. From there, the process
is much the same as anything else.

The above doc changes this to 'we follow the normal EFI boot mgr protocol
as amended by the above doc' though the elimination of boot1.efi hasn't
made it's way through the above doc. Basically, we pass two device paths in
the BootOptions BootXXXX variable. First one is loader.efi (which we'll
preferentially put in \efi\freebsd\loader-x64.efi) and the second one is
the kernel to load (with the implicit load module path, per today's stuff).

boot1.efi complicates things for no benefit. It complicates loading, it
complicates guessing where to put stuff to make it happy, it complicates
key signing and handoff for secure boot. We should ditch this clever hack
as something whose time has come and gone. We'd like to get secure boot in
place, and boot1.efi just increases by 1 the number of boot loaders that
have to cope with that stuff. boot1.efi has to have all the filesystem
support for everything. It has to know about EFI Boot mgr protocol. In
short, it's every single thing that /boot/loader.efi must be, but without
the FORTH or the flexibility.

Warner
Eric McCorkle
2017-10-18 14:15:12 UTC
Permalink
My $0.02...

I'm in agreement. I've been down in this stuff with the ZFS EFI
support, and lately the GELI stuff. In both cases, it complicates
things quite a bit. With ZFS, it meant I basically had to do everything
twice. With GELI, it introduced a number of complications, and GELI
probably would have landed over a year ago if it was just loader. Going
forward, I want to do some signed kernel/modules stuff, and the
existence of boot1 is just going to complicate that as well.

An interesting point: back when I briefly took up EFI support as a GSoC
project (which I was forced to abandon, unfortunately), the prototype
*did* only have loader.efi, which was installed to the ESP. So the plan
should work. You'd have to modify loader.efi a bit to alter its device
detection logic, but you could probably salvage some code from my boot1
refactor (which is actually modified code I stole from loader.efi anyway).

As far as my work goes, this won't cause me any problems, and in fact
will simplify things. The GELI stuff mostly modifies loader anyway, and
the actual GELI EFI driver works the same in boot1 and loader (by
design). For secure boot, getting rid of boot1 avoids having to haul in
a bunch more EFI APIs and debug signed image stuff. For other work, I
can't say for certain, of course, but I've been working on this stuff
for a while now and I can't really think of a use case that makes me say
"man, boot1 really solves that problem in a way nothing else can".

So in summary, I don't doubt it was a sensible decision at some point,
but I'm in agreement that its time has come.
Post by Warner Losh
I'd like to remove boot1.efi. It's no longer relevant. It was a useful hack
to get us going, but now it's becoming more of a liability than a win.
There's a lot of work that has been put into it so it can understand every
filesystem. However, in doing so boot1.efi has morphed into a loader.efi
without the scripting interpreter. Let's just kill boot1.efi and load the
full-featured loader directly.
boot1.efi used to have a role to play. It was a tiny, rarely changing bit
of glue in the UEFI world. It is now none of those things. It has become
rather large and bloated, and there's work to make it even more so.
My proposal is to fix the one bug in loader.efi that would preclude its use
as a primary boot loader (it sometimes guesses wrong for currdev and
loaddev). Once we've done that, we'll use it where we use boot1.efi today.
It would also simplify the load process and make it easier to implement the
full EFI Boot Manager protocol from the UEFI specifications. It should also
make secure boot easier to bring to market.
This dovetails nicely into some of the other changes on-tap for FreeBSD 12.
efibootmgr is coming soon (I'm reviewing the code from a coworker now).
There's plans to move the FreeBSD boot loader to
\efi\FreeBSD\loader-$ARCH.efi when that goes in, since we'll be able to
point the LoadOptions to that. There's plans to make the installer create
the EFI partition rather than just dd the efifat file we're doing today.
Plus, there's work underway to move all the boot block installation stuff
to a new script (install-boot) as well as efforts to make images for any
bootable system (spin).
There's lots of details to get right before we can make the final switch,
but I think it's in the interest of the project to do so.
Comments?
Warner
_______________________________________________
https://lists.freebsd.org/mailman/listinfo/freebsd-arch
Kris Moore
2017-10-18 14:26:05 UTC
Permalink
Post by Eric McCorkle
My $0.02...
I'm in agreement. I've been down in this stuff with the ZFS EFI
support, and lately the GELI stuff. In both cases, it complicates
things quite a bit. With ZFS, it meant I basically had to do everything
twice. With GELI, it introduced a number of complications, and GELI
probably would have landed over a year ago if it was just loader. Going
forward, I want to do some signed kernel/modules stuff, and the
existence of boot1 is just going to complicate that as well.
An interesting point: back when I briefly took up EFI support as a GSoC
project (which I was forced to abandon, unfortunately), the prototype
*did* only have loader.efi, which was installed to the ESP. So the plan
should work. You'd have to modify loader.efi a bit to alter its device
detection logic, but you could probably salvage some code from my boot1
refactor (which is actually modified code I stole from loader.efi anyway).
As far as my work goes, this won't cause me any problems, and in fact
will simplify things. The GELI stuff mostly modifies loader anyway, and
the actual GELI EFI driver works the same in boot1 and loader (by
design). For secure boot, getting rid of boot1 avoids having to haul in
a bunch more EFI APIs and debug signed image stuff. For other work, I
can't say for certain, of course, but I've been working on this stuff
for a while now and I can't really think of a use case that makes me say
"man, boot1 really solves that problem in a way nothing else can".
So in summary, I don't doubt it was a sensible decision at some point,
but I'm in agreement that its time has come.
Post by Warner Losh
I'd like to remove boot1.efi. It's no longer relevant. It was a useful hack
to get us going, but now it's becoming more of a liability than a win.
There's a lot of work that has been put into it so it can understand every
filesystem. However, in doing so boot1.efi has morphed into a loader.efi
without the scripting interpreter. Let's just kill boot1.efi and load the
full-featured loader directly.
boot1.efi used to have a role to play. It was a tiny, rarely changing bit
of glue in the UEFI world. It is now none of those things. It has become
rather large and bloated, and there's work to make it even more so.
My proposal is to fix the one bug in loader.efi that would preclude its use
as a primary boot loader (it sometimes guesses wrong for currdev and
loaddev). Once we've done that, we'll use it where we use boot1.efi today.
It would also simplify the load process and make it easier to implement the
full EFI Boot Manager protocol from the UEFI specifications. It should also
make secure boot easier to bring to market.
This dovetails nicely into some of the other changes on-tap for FreeBSD 12.
efibootmgr is coming soon (I'm reviewing the code from a coworker now).
There's plans to move the FreeBSD boot loader to
\efi\FreeBSD\loader-$ARCH.efi when that goes in, since we'll be able to
point the LoadOptions to that. There's plans to make the installer create
the EFI partition rather than just dd the efifat file we're doing today.
Plus, there's work underway to move all the boot block installation stuff
to a new script (install-boot) as well as efforts to make images for any
bootable system (spin).
There's lots of details to get right before we can make the final switch,
but I think it's in the interest of the project to do so.
Comments?
Warner
_______________________________________________
https://lists.freebsd.org/mailman/listinfo/freebsd-arch
_______________________________________________
https://lists.freebsd.org/mailman/listinfo/freebsd-arch
+1 here. We still use boot1.efi in TrueOS but if retiring that brings
with it the aforementioned improvements, then bring it on!
--
Kris Moore
Director of Engineering
iXsystems
Enterprise Storage & Servers Driven By Open Source
Nathan Whitehorn
2017-10-18 14:27:52 UTC
Permalink
Post by Warner Losh
I'd like to remove boot1.efi. It's no longer relevant. It was a useful hack
to get us going, but now it's becoming more of a liability than a win.
There's a lot of work that has been put into it so it can understand every
filesystem. However, in doing so boot1.efi has morphed into a loader.efi
without the scripting interpreter. Let's just kill boot1.efi and load the
full-featured loader directly.
boot1.efi used to have a role to play. It was a tiny, rarely changing bit
of glue in the UEFI world. It is now none of those things. It has become
rather large and bloated, and there's work to make it even more so.
My proposal is to fix the one bug in loader.efi that would preclude its use
as a primary boot loader (it sometimes guesses wrong for currdev and
loaddev). Once we've done that, we'll use it where we use boot1.efi today.
It would also simplify the load process and make it easier to implement the
full EFI Boot Manager protocol from the UEFI specifications. It should also
make secure boot easier to bring to market.
This dovetails nicely into some of the other changes on-tap for FreeBSD 12.
efibootmgr is coming soon (I'm reviewing the code from a coworker now).
There's plans to move the FreeBSD boot loader to
\efi\FreeBSD\loader-$ARCH.efi when that goes in, since we'll be able to
point the LoadOptions to that. There's plans to make the installer create
the EFI partition rather than just dd the efifat file we're doing today.
Plus, there's work underway to move all the boot block installation stuff
to a new script (install-boot) as well as efforts to make images for any
bootable system (spin).
There's lots of details to get right before we can make the final switch,
but I think it's in the interest of the project to do so.
Comments?
As the guy who wrote boot1.efi in the first place, I think this is a
great idea. boot1.efi exists to make the boot flow on EFI more like
non-EFI so that loader can live in /boot on filesystems (UFS, ZFS) that
EFI doesn't understand, thus preventing the need for a bunch of special
logic in make installworld. It has seriously outlived its usefulness.
Thanks for doing this!
-Nathan
Simon J. Gerraty
2017-10-19 17:02:47 UTC
Permalink
Post by Warner Losh
There's lots of details to get right before we can make the final switch,
but I think it's in the interest of the project to do so.
Just one comment that may or may not be relevant depending on the overal
plan.

I've implemented verification in the freebsd loader, along the lines
previously mentioned, for us this pretty much closes the secure-boot
gap - loader verifies kernel and its initial rootfs so init and etc/rc.
Which then gets us to mac_veriexec.

From that pov the initial boot bits can change as you like without
affecting the above. Is that the plan?

It only matters I guess in terms of the effort to upstream - assuming
there is interest from other embedded vendors.

Thanks
--sjg
Warner Losh
2017-10-19 17:18:57 UTC
Permalink
Post by Warner Losh
There's lots of details to get right before we can make the final switch,
but I think it's in the interest of the project to do so.
Just one comment that may or may not be relevant depending on the overal
plan.

I've implemented verification in the freebsd loader, along the lines
previously mentioned, for us this pretty much closes the secure-boot
gap - loader verifies kernel and its initial rootfs so init and etc/rc.
Which then gets us to mac_veriexec.

From that pov the initial boot bits can change as you like without
affecting the above. Is that the plan?

It only matters I guess in terms of the effort to upstream - assuming
there is interest from other embedded vendors.

Thanks
--sjg



I'm interested. Can you send me diff for review?
Warner
Simon J. Gerraty
2017-10-19 18:24:48 UTC
Permalink
Post by Warner Losh
I'm interested. Can you send me diff for review?
Not yet sorry... hopefully in a few weeks when the legal work is done.
Eric McCorkle
2017-10-20 02:03:28 UTC
Permalink
Post by Simon J. Gerraty
Post by Warner Losh
There's lots of details to get right before we can make the final switch,
but I think it's in the interest of the project to do so.
Just one comment that may or may not be relevant depending on the overal
plan.
I've implemented verification in the freebsd loader, along the lines
previously mentioned, for us this pretty much closes the secure-boot
gap - loader verifies kernel and its initial rootfs so init and etc/rc.
Which then gets us to mac_veriexec.
From that pov the initial boot bits can change as you like without
affecting the above. Is that the plan?
It only matters I guess in terms of the effort to upstream - assuming
there is interest from other embedded vendors.
Do I assume correctly that this is based on the NetBSD mac-based
verification stuff? ie. Not the public-key crypto stuff I've talked about?
Simon J. Gerraty
2017-10-20 05:05:51 UTC
Permalink
Post by Eric McCorkle
Post by Simon J. Gerraty
I've implemented verification in the freebsd loader, along the lines
previously mentioned, for us this pretty much closes the secure-boot
gap - loader verifies kernel and its initial rootfs so init and etc/rc.
Which then gets us to mac_veriexec.
Do I assume correctly that this is based on the NetBSD mac-based
verification stuff? ie. Not the public-key crypto stuff I've talked about?
I didn't want to thread-jack...

I've not looked at what's in NetBSD in this area for a decade at least,
but I ported the original veriexec from NetBSD to Junos about a dozen
years or so ago. More recently stevek re-implemented it for FreeBSD
10's MAC framework - the diffs (most of them anyway) have been sitting
in phabricator for a year or so...

The loader implementation shares no code with the above, but uses the
same verification model and leverages the same signed manifests.
Thus it retains all the flexibility of using X.509 certificate chains to
verify the signatures on the manifests.

This is very important for us, because it allows a 10 year old binary to
verify the latest signatures - provided that the RootCA certs have not
changed. For Junos the loader knows two RootCA's one for RSA and one for
ECDSA - that's all it needs.

We can tollerate more limited signing methods for the loader itself, to
fit in to various secure BIOS/boot environments, but from there we want
all the flexibility we can get.

--sjg
Eric McCorkle
2017-10-20 13:43:41 UTC
Permalink
Keeping it short, I've got a bunch of plans in this area. I was actually planning to finish off a paper and put it up for discussion this weekend. I'll talk more about it elsewhere.
Post by Simon J. Gerraty
Post by Eric McCorkle
Post by Simon J. Gerraty
I've implemented verification in the freebsd loader, along the
lines
Post by Eric McCorkle
Post by Simon J. Gerraty
previously mentioned, for us this pretty much closes the
secure-boot
Post by Eric McCorkle
Post by Simon J. Gerraty
gap - loader verifies kernel and its initial rootfs so init and
etc/rc.
Post by Eric McCorkle
Post by Simon J. Gerraty
Which then gets us to mac_veriexec.
Do I assume correctly that this is based on the NetBSD mac-based
verification stuff? ie. Not the public-key crypto stuff I've talked
about?
I didn't want to thread-jack...
I've not looked at what's in NetBSD in this area for a decade at least,
but I ported the original veriexec from NetBSD to Junos about a dozen
years or so ago. More recently stevek re-implemented it for FreeBSD
10's MAC framework - the diffs (most of them anyway) have been sitting
in phabricator for a year or so...
The loader implementation shares no code with the above, but uses the
same verification model and leverages the same signed manifests.
Thus it retains all the flexibility of using X.509 certificate chains to
verify the signatures on the manifests.
This is very important for us, because it allows a 10 year old binary to
verify the latest signatures - provided that the RootCA certs have not
changed. For Junos the loader knows two RootCA's one for RSA and one for
ECDSA - that's all it needs.
We can tollerate more limited signing methods for the loader itself, to
fit in to various secure BIOS/boot environments, but from there we want
all the flexibility we can get.
--sjg
--
Sent from my Android device with K-9 Mail. Please excuse my brevity.
Loading...