// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2023 ARM Limited */ #include #include #include #include #include #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, };