Some of the Gcc compiled clone tests in restricted mode face stack corruption. This occurs as the dynamic relocations by Gcc do not get input from compiler about clearing the executive mode in function pointers. On the other hand, Clang provides input about this permission in the structure cap_reloc (may be with hint from instruction blrr) to the capability relocation code.
As a workaround, clear this permission bit explicitly if required before branching to this function pointer. Also, keep any other function called from this function as inline.
Signed-off-by: Amit Daniel Kachhap amit.kachhap@arm.com --- tools/testing/selftests/arm64/morello/clone.c | 3 ++- .../arm64/morello/freestanding_start.S | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/arm64/morello/clone.c b/tools/testing/selftests/arm64/morello/clone.c index 69189287144a..67468cb524bc 100644 --- a/tools/testing/selftests/arm64/morello/clone.c +++ b/tools/testing/selftests/arm64/morello/clone.c @@ -44,7 +44,8 @@ struct test_fixture {
#define PROBE_INTERVAL (1 << 12)
-static void probe_addr_range(uintcap_t start_addr, size_t size, int interval) +static inline __attribute__((always_inline)) +void probe_addr_range(uintcap_t start_addr, size_t size, int interval) { size_t i;
diff --git a/tools/testing/selftests/arm64/morello/freestanding_start.S b/tools/testing/selftests/arm64/morello/freestanding_start.S index 92260fdc384d..365a8d16606a 100644 --- a/tools/testing/selftests/arm64/morello/freestanding_start.S +++ b/tools/testing/selftests/arm64/morello/freestanding_start.S @@ -199,6 +199,24 @@ FUNCTION_START(__clone) 1: mov c0, c10 mov c1, c9 + + /* + * Function pointers executed in restrictive mode have the executive + * mode permission cleared off by the Clang capability relocation code. + * However, dynamic relocations by GCC do not manage this, so clear this + * permission bit explicitly if required. + */ + adr c2, #0 + gcperm x3, c2 + tbnz x3, #__ARM_CAP_PERMISSION_EXECUTIVE__, 2f + mov x4, #__ARM_CAP_PERMISSION_EXECUTIVE__ + clrperm c1, c1, x4 + /* + * Function pointers are sealed so clrperm untagged c1 - rebuild a valid + * capability from PCC + */ + build c1, c1, c2 +2: blr c1 mov x8, #__NR_exit svc #0