Page MenuHomeFreeBSD

Disable stack redzone for amd64 EFI binaries.
ClosedPublic

Authored by jhb on Mar 12 2015, 5:38 PM.
Tags
None
Referenced Files
Unknown Object (File)
Sat, Dec 14, 7:29 AM
Unknown Object (File)
Tue, Dec 3, 11:10 PM
Unknown Object (File)
Oct 18 2024, 3:47 AM
Unknown Object (File)
Oct 2 2024, 7:28 AM
Unknown Object (File)
Sep 24 2024, 7:01 AM
Unknown Object (File)
Sep 24 2024, 5:29 AM
Unknown Object (File)
Sep 23 2024, 10:56 AM
Unknown Object (File)
Sep 18 2024, 10:21 AM
Subscribers

Details

Summary

The System V ABI for amd64 allows functions to use space in a 128
byte redzone below the stack pointer for scratch space and requires
interrupt and signal frames to avoid overwriting it. However, EFI
uses the Windows ABI which does not support this. As a result,
interrupt handlers in EFI push their interrupt frames directly on
top of the stack pointer. If the compiler used the red zone in a
function in the EFI loader, then a device interrupt that occurred
while that function was running could trash its local variables.
In practice this happens fairly reliable when using gzipfs as an
interrupt during decompression can trash the local variables in
the inflate_table() function resulting in corrupted output or hangs.

Fix this by disabling the redzone for amd64 EFI binaries. This
requires building not only the loader but any libraries used by the
loader without redzone support.

Thanks to Jilles for pointing me at the redzone once I found the
stack corruption.

Sponsored by: Cisco Systems, Inc.

I did think about building dedicated versions of libstand and libficl
for EFI in sys/amd64/efi. However, I think if the EFI loader is the
only consumer of the 64-bit libficl/libstand on amd64 then this is
simpler and results in less work in the future (we are already stuck
with having to keep libstand32/Makefile in sync with libstand/Makefile
going forward and this would add to that burden).

Test Plan
  • Try to load a small (16MB) mfsroot.gz under OVMF in qemu. An unpatched loader will either hang or provide corrupted data.
  • Note that adding printfs to inflate_table() "fixes" it since the compiler only uses the redzone space for leaf functions.

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Skipped
Unit
Tests Skipped

Event Timeline

jhb retitled this revision from to Disable stack redzone for amd64 EFI binaries..
jhb updated this object.
jhb edited the test plan for this revision. (Show Details)
jhb added a reviewer: benno.

This looks good to me on two conditions:
(1) It looks like libstand for userboot is built separately and is unaffected.
(2) The hack that OBrien did to use userboot's libstand needs to be backed out.

I already backed it out today in preparation for this (and so I could just MFC this change without having to merge his change along with it)

imp added a reviewer: imp.

Looks good to me. Though this reminds me of just how aweful these makefiles have become... Though I suppose that's to be expected for such a specialized application.

This revision is now accepted and ready to land.Mar 12 2015, 6:58 PM
jhb updated this revision to Diff 4207.

Closed by commit rS279949 (authored by @jhb).