master
c 49 lines 1.1 KB
Raw
1 /*
2 * Memory tagging, write-only tag checking
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7 #include "mte.h"
8
9 void pass(int sig, siginfo_t *info, void *uc)
10 {
11 exit(0);
12 }
13
14 int main(int ac, char **av)
15 {
16 struct sigaction sa;
17 int *p0, *p1, *p2;
18 long excl = 1;
19
20 enable_mte(PR_MTE_TCF_SYNC | PR_MTE_STORE_ONLY);
21 p0 = alloc_mte_mem(sizeof(*p0));
22
23 /* Create two differently tagged pointers. */
24 asm("irg %0,%1,%2" : "=r"(p1) : "r"(p0), "r"(excl));
25 asm("gmi %0,%1,%0" : "+r"(excl) : "r" (p1));
26 assert(excl != 1);
27 asm("irg %0,%1,%2" : "=r"(p2) : "r"(p0), "r"(excl));
28 assert(p1 != p2);
29
30 /* Store the tag from the first pointer. */
31 asm("stg %0, [%0]" : : "r"(p1));
32
33 /*
34 * We write to p1 (stg above makes this check pass) and read from
35 * p2 (improperly tagged, but since it's a read, we don't care).
36 */
37 *p1 = *p2;
38
39 /* enable handler */
40 memset(&sa, 0, sizeof(sa));
41 sa.sa_sigaction = pass;
42 sa.sa_flags = SA_SIGINFO;
43 sigaction(SIGSEGV, &sa, NULL);
44
45 /* now we write to badly tagged p2, should fault. */
46 *p2 = 0;
47
48 abort();
49 }