NX means “no execute”. A region of memory can be marked as no-execute, and the processor will then refuse to run code from that region. This can be used to improve security by maintaining a strict separation between memory that is writable and memory that is executable. See W^X for details.
As of November 2022, Microsoft requires NX compatibility for all UEFI signing submissions. The specific requirements are:
IMAGE_DLLCHARACTERISTICS_NX_COMPAT
must be set.IMAGE_DLLCHARACTERISTICS_NX_COMPAT
must be set.EFI_MEMORY_ATTRIBUTE_PROTOCOL
is available, it must be used to enforce W^X on the child's sections.Most of the requirements are trivially satisfied by crdyboot (and crdyshim); the executable produced by rustc already covers the first five requirements.
The final requirement, for enforcing NX compatibility in a child executable, is handled in libcrdy/src/nx.rs
. However, we only enforce NX in the child if the EFI_MEMORY_ATTRIBUTE_PROTOCOL
is available. This is important, because our Linux kernel does not yet support NX in its EFI boot stub. As long as crdyboot is executing on firmware that doesn‘t support the memory-attribute protocol, this is fine; we won’t stop the kernel from booting. By the time we need to boot on devices with firmware that have support for the memory-attribute protocol, we expect our kernel will properly support NX.