Skip to content

Commit

Permalink
allocator-test: probe revocation in more places
Browse files Browse the repository at this point in the history
  • Loading branch information
nwf committed Jan 15, 2025
1 parent f485b5d commit 1c86f8d
Showing 1 changed file with 75 additions and 0 deletions.
75 changes: 75 additions & 0 deletions tests/allocator-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,84 @@ namespace
*/
__noinline void test_revoke(const size_t HeapSize)
{
#ifdef TEMPORAL_SAFETY
{
static cheriot::atomic<int> state = 2;
int sleeps;

void *volatile p_stack = malloc(16);
TEST(__builtin_cheri_tag_get(p_stack),
"Failed to allocate for test");

static void *volatile p_global = malloc(16);
TEST(__builtin_cheri_tag_get(p_global),
"Failed to allocate for test");

/*
* Check that trusted stacks are swept. This one is fun: we need to
* somehow ensure that a freed pointer is in the register file of an
* off-core thread. async() and inline asm it is!
*/
async([=]() {
int ptag, scratch;

// Tell the main thread to go
state = 0;

/*
* Busy spin, ensuring that our test pointer is in a register
* throughout, then get its tag.
*/
__asm__ volatile("1:\n"
"clw %[scratch], 0(%[state])\n"
"beqz %[scratch], 1b\n"
"cgettag %[out], %[p]\n"
: [out] "+&r"(ptag), [scratch] "=&r"(scratch)
: [p] "C"(p_global), [state] "C"(&state));

TEST(ptag == 0, "Revoker failed to sweep trusted stack");

/* Release the main thread */
state = 3;
});

sleeps = 0;
while (state.load() != 0)
{
TEST(sleep(1) >= 0, "Failed to sleep");
TEST(sleeps++ < 100, "Background thread not ready");
}

free(p_stack);
free(p_global);
heap_quarantine_empty();

state = 1;

/* Check that globals are swept */
TEST(!__builtin_cheri_tag_get_temporal(p_global),
"Revoker failed to sweep globals");

/* Check that the stack is swept */
TEST(!__builtin_cheri_tag_get_temporal(p_stack),
"Revoker failed to sweep stack");

/* Wait for the async thread to have performed its test */
sleeps = 0;
while (state.load() != 3)
{
TEST(sleep(1) >= 0, "Failed to sleep");
TEST(sleeps++ < 100, "Background thread not finished");
}
}
#else
debug_log("Skipping temporal safety checks");
#endif

const size_t AllocSize = HeapSize / (MaxAllocCount + 2);
debug_log("test_revoke using {}-byte objects", AllocSize);

/* Repeatedly cycle quarantine */
allocations.resize(MaxAllocCount);
for (size_t i = 0; i < TestIterations; ++i)
{
Expand Down

0 comments on commit 1c86f8d

Please sign in to comment.