/** *trusty_app_callback()-Testthatapphasavalidusershadowcallstack * *@ta:Applicationtotest *@status:Pointertoastructuretrackingthecurrentteststatus.
*/ staticvoid trusty_app_callback(struct trusty_app* ta, void* status) { struct scs_test_status* status_ptr = (struct scs_test_status*)status; if (strcmp(ta->props.app_name, "userscs-custom") == 0) { /* were we able to request a custom shadow stack size? */
ASSERT_EQ(ta->props.min_shadow_stack_size, 128);
} elseif (strcmp(ta->props.app_name, "userscs-disabled") == 0) { /* were we able to opt out of shadow stacks? */
ASSERT_EQ(ta->props.min_shadow_stack_size, 0); /* userscs-* apps loop infinitely so they'll always have a thread */
ASSERT_NE((void*)ta->thread, NULL, "App has thread");
ASSERT_EQ((void*)ta->thread->shadow_stack_base, NULL, "Shadow call stack was disabled"); return;
} elseif (strcmp(ta->props.app_name, "userscs-default") == 0) { /* did default scs app get the default shadow stack size? */
ASSERT_EQ(ta->props.min_shadow_stack_size, DEFAULT_SHADOW_STACK_SIZE, "Expected shadow call stack to have the default size");
}
/* size must be a multiple of the pointer size */
ASSERT_EQ(0, ta->props.min_shadow_stack_size % sizeof(vaddr_t), "Shadow call stack size is not a multiple of the pointer size");
struct trusty_thread* tt = ta->thread;
ASSERT_NE((void*)tt, NULL, "Running trusty app must have a valid thread");
ASSERT_NE((void*)tt->shadow_stack_base, NULL, "Shadow call stack must point to allocation");
ASSERT_EQ(false, is_kernel_address(tt->shadow_stack_base), "Shadow stack on user thread points to kernel memory");
ASSERT_NE(tt->stack_start, tt->shadow_stack_base, "Shadow stack on user thread aliases the regular stack");
vaddr_t past_last = (vaddr_t)tt->shadow_stack_base + tt->shadow_stack_size;
vaddr_t last_elem = past_last - sizeof(vaddr_t); /* a whole number of pages is allocated no matter the shadow stack size */
vaddr_t pre_first = last_elem - round_up(tt->shadow_stack_size, PAGE_SIZE);
vaddr_t elem_translated, ignored;
struct vmm_aspace* uspace = ta->aspace;
ASSERT_EQ(NO_ERROR,
translate_uspace_ptr(uspace, last_elem, &elem_translated), "Actual size of shadow stack differs from recorded size"); /* *Checkthattestappusesitsshadowstackasexpected.Theshadowcall *stackiszero-initializedandonceastackslotisuseditcannever *becomezeroagain.
*/ if (strcmp(ta->props.app_name, "userscs-default") == 0) {
EXPECT_EQ(0, *(vaddr_t*)elem_translated, "Expected last element of shadow stack to be zero " "(unused)");
ASSERT_EQ(NO_ERROR, translate_uspace_ptr(uspace, tt->shadow_stack_base,
&elem_translated)); /* *Thelinkregisterisinitiallyzerosowhenshadowcallstacksare *enabledforlibc,thesecondelementholdsthefirstnon-zeroentry
*/
EXPECT_NE(0, *(vaddr_t*)elem_translated + sizeof(vaddr_t), "Expected second element of shadow stack to be non-zero " "(used)");
}
ASSERT_EQ(ERR_NOT_FOUND, translate_uspace_ptr(uspace, past_last, &ignored), "Expected guard page after shadow stack on user thread");
ASSERT_EQ(ERR_NOT_FOUND, translate_uspace_ptr(uspace, pre_first, &ignored), "Expected guard page before shadow stack on user thread");
TEST(userscstest, FEATURE_GATED_TEST_NAME(user_threads_have_scs)) { int res = inspect_trusty_threads();
EXPECT_NE(-1, res, "There were no running apps with threads to inspect");
EXPECT_EQ(0, res, "One or more apps did not have the expected shadow call stack");
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.