68 lines
1.3 KiB
C
68 lines
1.3 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Copyright (C) 2023 ARM Limited
|
|
*/
|
|
|
|
#include <errno.h>
|
|
#include <signal.h>
|
|
#include <unistd.h>
|
|
|
|
#include <sys/mman.h>
|
|
#include <sys/prctl.h>
|
|
|
|
#include "test_signals_utils.h"
|
|
#include "testcases.h"
|
|
|
|
static uint64_t *gcs_page;
|
|
|
|
#ifndef __NR_map_shadow_stack
|
|
#define __NR_map_shadow_stack 453
|
|
#endif
|
|
|
|
static bool alloc_gcs(struct tdescr *td)
|
|
{
|
|
long page_size = sysconf(_SC_PAGE_SIZE);
|
|
|
|
gcs_page = (void *)syscall(__NR_map_shadow_stack, 0,
|
|
page_size, 0);
|
|
if (gcs_page == MAP_FAILED) {
|
|
fprintf(stderr, "Failed to map %ld byte GCS: %d\n",
|
|
page_size, errno);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static int gcs_write_fault_trigger(struct tdescr *td)
|
|
{
|
|
/* Verify that the page is readable (ie, not completely unmapped) */
|
|
fprintf(stderr, "Read value 0x%lx\n", gcs_page[0]);
|
|
|
|
/* A regular write should trigger a fault */
|
|
gcs_page[0] = EINVAL;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int gcs_write_fault_signal(struct tdescr *td, siginfo_t *si,
|
|
ucontext_t *uc)
|
|
{
|
|
ASSERT_GOOD_CONTEXT(uc);
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
struct tdescr tde = {
|
|
.name = "GCS write fault",
|
|
.descr = "Normal writes to a GCS segfault",
|
|
.feats_required = FEAT_GCS,
|
|
.timeout = 3,
|
|
.sig_ok = SIGSEGV,
|
|
.sanity_disabled = true,
|
|
.init = alloc_gcs,
|
|
.trigger = gcs_write_fault_trigger,
|
|
.run = gcs_write_fault_signal,
|
|
};
|