1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2019 ARM Limited
4  *
5  * Place a fake sigframe on the stack missing the mandatory FPSIMD
6  * record: on sigreturn Kernel must spot this attempt and the test
7  * case is expected to be terminated via SEGV.
8  */
9 
10 #include <stdio.h>
11 #include <signal.h>
12 #include <ucontext.h>
13 
14 #include "test_signals_utils.h"
15 #include "testcases.h"
16 
17 struct fake_sigframe sf;
18 
19 static int fake_sigreturn_missing_fpsimd_run(struct tdescr *td,
20 					     siginfo_t *si, ucontext_t *uc)
21 {
22 	size_t resv_sz, offset;
23 	struct _aarch64_ctx *head = GET_SF_RESV_HEAD(sf);
24 
25 	/* just to fill the ucontext_t with something real */
26 	if (!get_current_context(td, &sf.uc, sizeof(sf.uc)))
27 		return 1;
28 
29 	resv_sz = GET_SF_RESV_SIZE(sf);
30 	head = get_header(head, FPSIMD_MAGIC, resv_sz, &offset);
31 	if (head && resv_sz - offset >= HDR_SZ) {
32 		fprintf(stderr, "Mangling template header. Spare space:%zd\n",
33 			resv_sz - offset);
34 		/* Just overwrite fpsmid_context */
35 		write_terminator_record(head);
36 
37 		ASSERT_BAD_CONTEXT(&sf.uc);
38 		fake_sigreturn(&sf, sizeof(sf), 0);
39 	}
40 
41 	return 1;
42 }
43 
44 struct tdescr tde = {
45 		.name = "FAKE_SIGRETURN_MISSING_FPSIMD",
46 		.descr = "Triggers a sigreturn with a missing fpsimd_context",
47 		.sig_ok = SIGSEGV,
48 		.timeout = 3,
49 		.run = fake_sigreturn_missing_fpsimd_run,
50 };
51