Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

c18n: Improve detection of interrupted compartment #2220

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 34 additions & 24 deletions libexec/rtld-elf/rtld_c18n.c
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,7 @@
*/
static char dummy_stk;
sp = &dummy_stk;
set_untrusted_stk(sp);
#endif
size = cheri_getlen(sp);
assert(size > 0);
Expand Down Expand Up @@ -1733,6 +1734,13 @@
thr_thread_start(curthread);
}

static bool
identify_untrusted_stk(void *canonical, void *untrusted)
{
canonical = cheri_clearperm(canonical, CHERI_PERM_SW_VMEM);
dpgao marked this conversation as resolved.
Show resolved Hide resolved
return (cheri_is_subset(untrusted, canonical));
}

void
_rtld_thr_exit(long *state)
{
Expand Down Expand Up @@ -1762,7 +1770,8 @@
data = &table->meta->compart_stk[i];
if (data->size == 0)
continue;
if (!cheri_is_subset(data->begin, table->entries[i].stack)) {
if (!identify_untrusted_stk(
data->begin, table->entries[i].stack)) {
rtld_fdprintf(STDERR_FILENO,
"c18n: Untrusted stack %#p of %s is not derived "
"from %#p\n", table->entries[i].stack,
Expand Down Expand Up @@ -1896,22 +1905,22 @@
intr_idx = tf->callee;
intr = index_to_cid(intr_idx);
if (intr < table->meta->capacity &&
table->meta->compart_stk[intr].size > 0) {
if (cheri_is_subset(table->meta->compart_stk[intr].begin, nsp))
goto found;
/*
* If the interrupt occured at a point in the trampoline while a
* tail-call is taking place, where the callee has been updated
* but the callee's stack has not been installed yet, nsp would
* refer to the stack top of the compartment identified as the
* caller in a partially constructed frame above the topmost
* frame.
*/
intr_idx = tf[-1].caller;
intr = index_to_cid(intr_idx);
if (cheri_is_subset(table->meta->compart_stk[intr].begin, nsp))
goto found_trusted;
}
table->meta->compart_stk[intr].size > 0 &&
identify_untrusted_stk(table->meta->compart_stk[intr].begin, nsp))
goto found;
/*
* If the interrupt occured at a point in the trampoline while a
* tail-call is taking place, where the callee has been updated but the
* callee's stack has not been installed yet, nsp would refer to the
* stack top of the compartment identified as the caller in a partially
* constructed frame above the topmost frame.
*/
intr_idx = tf[-1].caller;
intr = index_to_cid(intr_idx);
if (intr < table->meta->capacity &&
table->meta->compart_stk[intr].size > 0 &&
identify_untrusted_stk(table->meta->compart_stk[intr].begin, nsp))
goto found_trusted;
/*
* If the interrupt occurred at a point in the trampoline where a new
* frame has been pushed but the callee's stack has not been installed
Expand All @@ -1928,7 +1937,7 @@
*/
intr_idx = tf->caller;
intr = index_to_cid(intr_idx);
if (cheri_is_subset(table->meta->compart_stk[intr].begin, nsp))
if (identify_untrusted_stk(table->meta->compart_stk[intr].begin, nsp))
goto found_trusted;
/*
* Lazy binding, thread-local storage, and stack resolution all involve
Expand All @@ -1937,11 +1946,8 @@
*/
intr_idx = cid_to_index(RTLD_COMPART_ID);
intr = RTLD_COMPART_ID;
if (cheri_is_subset(table->meta->compart_stk[intr].begin, nsp))
if (identify_untrusted_stk(table->meta->compart_stk[intr].begin, nsp))
goto found_trusted;
#ifndef __ARM_MORELLO_PURECAP_BENCHMARK_ABI
found_failed:
#endif
rtld_fdprintf(STDERR_FILENO,
"c18n: Cannot resolve inconsistent untrusted stack %#p. "
"Please file a bug report!\n", nsp);
Expand All @@ -1953,11 +1959,15 @@
* running code in Executive mode. This performs a quick sanity check.
*/
if ((cheri_getperm(ucp->uc_mcontext.mc_capregs.cap_elr) &
CHERI_PERM_EXECUTIVE) == 0)
goto found_failed;
CHERI_PERM_EXECUTIVE) == 0) {
rtld_fdprintf(STDERR_FILENO,
"c18n: Cannot resolve inconsistent untrusted stack %#p in "
"Restricted Mode. Please file a bug report!\n", nsp);
abort();
}
#endif
found:

Check warning on line 1970 in libexec/rtld-elf/rtld_c18n.c

View workflow job for this annotation

GitHub Actions / Style Checker

Missing Signed-off-by: line
/*
* Emulate a compartment transition from the interrupted compartment to
* RTLD.
Expand Down
Loading