acidanthera / bugtracker

Acidanthera Bugtracker
384 stars 44 forks source link

Recent update to edk2-stable202405 has broken network boot support in OVMF #2421

Closed mikebeaton closed 2 months ago

mikebeaton commented 2 months ago

Recent update to edk2-stable202405 has broken network boot in OVMF. Suspect this may be to do with SecurityPkg RNG changes, but have not got to the bottom of it.

If I check out audk at audk-stable-202311 and then use it to build and start OVMF with network boot support, then I see PXE and HTTP Boot entries in the UI Boot Manager. Performing the same operations from current audk master, there are no network boot entries in the Boot Manager.

Here is a sample command using OvmfPkg/build.sh which should build OVMF with full network boot support:

./build.sh -b NOOPT -D DEBUG_ON_SERIAL_PORT -D LINUX_LOADER \
-D NETWORK_HTTP_BOOT_ENABLE -D NETWORK_TLS_ENABLE -D NETWORK_IP6_ENABLE

Here is a matching command to start OVMF with a bridged NIC configured. Starts and shows network boot entries in edk2-stable202405, starts but no network boot entries in current audk master:

sudo ./build.sh -b NOOPT qemu -serial stdio \
-netdev vmnet-bridged,id=mynet0,ifname=en0 \
-device e1000,netdev=mynet0,id=mynic0
mikebeaton commented 2 months ago

It appears to be broken in EDK 2 itself. 😭

mikebeaton commented 2 months ago

https://bugzilla.tianocore.org/show_bug.cgi?id=4827

mikebeaton commented 2 months ago

The issue is that the network stack drivers have all been updated by M$ to use a secure random number generator, which means that protocol gEfiRngProtocolGuid must be found, otherwise they will fail to load if using Depex, or fail to start (with an assertion in debug mode) if loaded directly.

You can fix the specific issue of no network boot options in OVMF by starting OVMF with additional qemu -device virtio-rng-pci option, so that the VirtioRngDxe driver (which was already present in OVMF prior to these changes) will install this protocol providing random numbers using an entropy source provided by qemu.

Unfortunately, AFAICT, OVMF started without that option is more representative of normal firmware - i.e. our network boot stack will fail to start on most firmware, now that it includes this update.

Correct solution (for us at least) seems to be to ship an instance of the SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf driver, which must be loaded (first, if loading the drivers manually) in order for the network boot stack to work.

vit9696 commented 2 months ago

What about rdrand-based CRNG? Cannot we just pass -cpu IvyBridge and have it work?

mikebeaton commented 2 months ago

Just passing -cpu IvyBridge (say instead of -device virtio-rng-pci) doesn't make the network stack load on OVMF.

I hope I'm not misunderstanding, but look at the changes here. All of the changes in the other drivers end up calling PseudoRandom in DxeNetLib, which is also introduced in that commit. That requires the protocol with GUID gEfiRngProtocolGuid to be present.

So the issue (as I understand it) is not just whether random number support is available (from the hardware or otherwise), but whether it is available wrapped up in that protocol. The only ways I can see currently, in their or our code, to provide that protocol are RngDxe (which basically means loading that driver) or VirtioRngDxe (which basically means setting that flag in qemu, noting that VirtioRngDxe was already part of OVMF all along; but not required for anything - or at least not for the network boot stack - before).

Network boot stack drivers we compile, from the new code, need random number support wrapped in that protocol. To use these on real hardware, since VirtioRngDxe does not apply, the only option I can see is to load the driver RngDxe before the network stack drivers.

vit9696 commented 2 months ago

Yes, you need to add RngDxe to OVMF, and this will not require virtio rng.

mikebeaton commented 2 months ago

That's what I tried to say, above! That's not what M$ (signed off by Ard) have done, though. They have not added RngDxe to OvmfPkg, nor to ArmVirtPkg, though they have added it to EmulatorPkg. Instead, for ArmVirtPkg and OvmfPkg, they have worked under the assumption, I guess, that they should use the implementation of that protocol which was already there, as long as you provide flag -device virtio-rng-pci!

Screenshot 2024-08-10 at 12 44 42

So the simplest solution for OVMF is to do what you're 'supposed' to do, it seems, and add that flag. (But yes, it works, tested, to also load RngDxe (as well as VirtioRngDxe, which is there anyway), in which case the flag is not needed and it works.)

My main point out of all that - after having worked out how to start network boot in OVMF successfully again - is that these drivers have changed, and we're going to need to provide RngDxe as part of our network boot stack now.

mikebeaton commented 2 months ago

Not sure there's anything needing changing to address the issue title. Just a not very obvious update in intended usage in the underlying library.

I need to update the network boot PR to cover this in the OVMF instructions, and to include RngDxe as a network stack driver.