File Index
Files and directories
Sign in
FILE

gcs_write_fault.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/arm64/signal/testcases/gcs_write_fault.c 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.