On 16/03/2023 10:43, Amit Daniel Kachhap wrote:
Some of the Gcc compiled clone tests in restricted mode face stack corruption. This occurs as the run-time permission settings (executive or restricted mode) in the PCC may be lost if function pointers are materialised from the GOT entries. This further leads to selecting an incorrect stack pointer(CSP instead of RCSP) and hence the crash.
As a workaround, materialise the function pointer clone_base_fn explicitly by building branch address from the PCC. Here it is assumed that the bounds and permissions of clone_base_fn are same as the PCC , which is not an issue in practice (being in the same translation unit).
Signed-off-by: Amit Daniel Kachhap amit.kachhap@arm.com
tools/testing/selftests/arm64/morello/clone.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/arm64/morello/clone.c b/tools/testing/selftests/arm64/morello/clone.c index 69189287144a..730811f9b7c2 100644 --- a/tools/testing/selftests/arm64/morello/clone.c +++ b/tools/testing/selftests/arm64/morello/clone.c @@ -98,6 +98,7 @@ void clone_single(struct test_fixture *data) { int ppid = 0, cpid = 0; int result = -EINVAL;
- void *ptr = clone_base_fn;
A more descriptive name would be good, maybe clone_fn? Also I think that using the real type should work: int (*clone_fn)(void *) = ...
Another minor improvement, this could be moved after clone_flags, and move the if block just after the declaration, to have it all in one place.
Kevin
void *new_stack = mmap_verified(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0, STACK_REQ_PERMS); @@ -119,7 +120,18 @@ void clone_single(struct test_fixture *data) EXPECT_TRUE(!(data->flags & CLONE_TH_RESTRICTED) || in_restricted());
- result = __clone(clone_base_fn, (uintcap_t)new_stack + STACK_SIZE,
- /*
* Function pointers are materialised by the compiler by either
* computing from the PCC (ADRP + ADD + SEAL) or loading from GOT. The
* run-time permission settings (executive or restrictive) in PCC may
* not match with the GOT entries. Hence, materialise the function
* pointers explicitly to avoid this mismatch issue.
*/
- if (in_restricted()) {
ptr = cheri_address_set(cheri_pcc_get(), (ptraddr_t)ptr);
ptr = cheri_sentry_create(ptr);
- }
- result = __clone(ptr, (uintcap_t)new_stack + STACK_SIZE, clone_flags, data, &ppid, tls, &cpid);
EXPECT_GT(result, 0) {