vmbase: Support LLVM and Bionic stack guard
C code compiled with the Android toolchain has stack guard checks
enabled. So as to avoid having to recompile every target with
-fno-stack-guard, instead add the expected symbols to vmbase.
This means we need __stack_chk_guard variable containing the canary
(used by all libc implementations [1]) and a thread-local storage containing
another copy of the canary at offset 40 (Bionic only [2]).
If the instrumentation detects an error, it calls __stack_chk_fail.
Provide an implementation that simply panics.
[1] bionic/tests/stack_protector_test.cpp
[2] https://reviews.llvm.org/D18632
Bug: 237372981
Test: atest vmbase_example.integration_test
Change-Id: I00de7c75aef6a57a73667df6983a12b01fbe9e51
diff --git a/vmbase/example/src/main.rs b/vmbase/example/src/main.rs
index 3c91f97..9b362b2 100644
--- a/vmbase/example/src/main.rs
+++ b/vmbase/example/src/main.rs
@@ -24,7 +24,8 @@
extern crate alloc;
use crate::layout::{
- dtb_range, print_addresses, rodata_range, text_range, writable_region, DEVICE_REGION,
+ bionic_tls, dtb_range, print_addresses, rodata_range, stack_chk_guard, text_range,
+ writable_region, DEVICE_REGION,
};
use aarch64_paging::{idmap::IdMap, paging::Attributes};
use alloc::{vec, vec::Vec};
@@ -55,6 +56,7 @@
print_addresses();
assert_eq!(arg0, dtb_range().start.0 as u64);
check_data();
+ check_stack_guard();
unsafe {
HEAP_ALLOCATOR.lock().init(&mut HEAP as *mut u8 as usize, HEAP.len());
@@ -94,6 +96,13 @@
check_data();
}
+fn check_stack_guard() {
+ const BIONIC_TLS_STACK_GRD_OFF: usize = 40;
+
+ info!("Testing stack guard");
+ assert_eq!(bionic_tls(BIONIC_TLS_STACK_GRD_OFF), stack_chk_guard());
+}
+
fn check_data() {
info!("INITIALISED_DATA: {:#010x}", &INITIALISED_DATA as *const u32 as usize);
unsafe {