FILE
gcs_write_fault.c
File preview with syntax highlighting.
linux-6.19.14/tools/testing/selftests/arm64/signal/testcases/gcs_write_fault.c
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) 2023 ARM Limited 4 */ 5 6#include <errno.h> 7#include <signal.h> 8#include <unistd.h> 9 10#include <sys/mman.h> 11#include <sys/prctl.h> 12 13#include "test_signals_utils.h" 14#include "testcases.h" 15 16static uint64_t *gcs_page; 17 18#ifndef __NR_map_shadow_stack 19#define __NR_map_shadow_stack 453 20#endif 21 22static bool alloc_gcs(struct tdescr *td) 23{ 24 long page_size = sysconf(_SC_PAGE_SIZE); 25 26 gcs_page = (void *)syscall(__NR_map_shadow_stack, 0, 27 page_size, 0); 28 if (gcs_page == MAP_FAILED) { 29 fprintf(stderr, "Failed to map %ld byte GCS: %d\n", 30 page_size, errno); 31 return false; 32 } 33 34 return true; 35} 36 37static int gcs_write_fault_trigger(struct tdescr *td) 38{ 39 /* Verify that the page is readable (ie, not completely unmapped) */ 40 fprintf(stderr, "Read value 0x%lx\n", gcs_page[0]); 41 42 /* A regular write should trigger a fault */ 43 gcs_page[0] = EINVAL; 44 45 return 0; 46} 47 48static int gcs_write_fault_signal(struct tdescr *td, siginfo_t *si, 49 ucontext_t *uc) 50{ 51 ASSERT_GOOD_CONTEXT(uc); 52 53 return 1; 54} 55 56 57struct tdescr tde = { 58 .name = "GCS write fault", 59 .descr = "Normal writes to a GCS segfault", 60 .feats_required = FEAT_GCS, 61 .timeout = 3, 62 .sig_ok = SIGSEGV, 63 .sanity_disabled = true, 64 .init = alloc_gcs, 65 .trigger = gcs_write_fault_trigger, 66 .run = gcs_write_fault_signal, 67};
~/
Read-only file preview.