vmbase: Fix undetected EH stack overflows
If pvmfw receives a payload, it maps the region potentially containing
it (from ALIGN(bin_end, 4096) to ORIGIN(image) + LENGTH(image)) with
read-write permissions, meaning that the EH stack could overflow into it
and go undetected.
Address this by reserving a page of the writable_data region as guard
page instead and move the EH stack appropriately. Alternatively, we
could have "reserved" the last page of the image but this risks causing
unexpected issues when we say that the region available to the loader is
2 MiB but then unexpectedly crop it by one page.
Similar to the .stack, give the guard page its own section for clarity.
Bug: 381440625
Test: m {pvmfw,rialto,vmbase_example_{bios,kernel}}_bin
Change-Id: I17c32d5f8b5fae4fb7af325c05de3c08047922c1
diff --git a/libs/libvmbase/sections.ld b/libs/libvmbase/sections.ld
index 5ca5ff4..61af60f 100644
--- a/libs/libvmbase/sections.ld
+++ b/libs/libvmbase/sections.ld
@@ -56,17 +56,6 @@
} >image
rodata_end = .;
- .eh_stack (NOLOAD) : ALIGN(4096) {
- /*
- * Get stack overflow guard from the previous page being from
- * .rodata and mapped read-only or left unmapped.
- */
- eh_stack_limit = .;
- . += 4096;
- . = ALIGN(4096);
- init_eh_stack_pointer = .;
- } >writable_data
-
/*
* Collect together the read-write data including .bss at the end which
* will be zero'd by the entry code. This is page aligned so it can be
@@ -96,6 +85,18 @@
bss_end = .;
} >writable_data
+ /* Left unmapped, to catch overflows of the exception handler stack. */
+ .eh_stack_guard_page (NOLOAD) : ALIGN(4096) {
+ . += 4096;
+ } >writable_data
+
+ /* Exception handler stack, mapped read-write. */
+ .eh_stack (NOLOAD) : ALIGN(4096) {
+ eh_stack_limit = .;
+ . += 4096;
+ init_eh_stack_pointer = .;
+ } >writable_data
+
/* Left unmapped, to catch overflows of the stack. */
.stack_guard_page (NOLOAD) : ALIGN(4096) {
. += 4096;