-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest_mte_stack2.cpp
113 lines (94 loc) · 3.87 KB
/
test_mte_stack2.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <cstdlib>
#include <unistd.h>
#include <sys/auxv.h>
#include <sys/mman.h>
#include <sys/prctl.h>
#include <sys/types.h>
/*
* From arch/arm64/include/uapi/asm/hwcap.h
*/
#define HWCAP2_MTE (1 << 18)
/*
* From arch/arm64/include/uapi/asm/mman.h
*/
#define PROT_MTE 0x20
/*
* From include/uapi/linux/prctl.h
*/
#define PR_SET_TAGGED_ADDR_CTRL 55
#define PR_GET_TAGGED_ADDR_CTRL 56
# define PR_TAGGED_ADDR_ENABLE (1UL << 0)
# define PR_MTE_TCF_SHIFT 1
# define PR_MTE_TCF_NONE (0UL << PR_MTE_TCF_SHIFT)
# define PR_MTE_TCF_SYNC (1UL << PR_MTE_TCF_SHIFT)
# define PR_MTE_TCF_ASYNC (2UL << PR_MTE_TCF_SHIFT)
# define PR_MTE_TCF_MASK (3UL << PR_MTE_TCF_SHIFT)
# define PR_MTE_TAG_SHIFT 3
# define PR_MTE_TAG_MASK (0xffffUL << PR_MTE_TAG_SHIFT)
#define INT_TAG_SUBTRACT_ONE 0x0040000000000000 // to subtract 1 from tag of an int*
void test2(int* ta, int ind)
{
printf("IN_test2_func: Input ta: %p value: %i, stored at %p | ind: %i, addr: %p \n", ta, *ta, &ta, ind, &ind);
*ta = -101;
int* ta_prev_tag = (ta - INT_TAG_SUBTRACT_ONE);
printf("Modified ta's tag, new ptr: %p \n", ta_prev_tag);
printf("Accessing ta[2] (extra space in ta's granule) %i \n", ta[2]);
// printf("Accessing ta_prev_tag[2] (extra space in ta's granule) %i \n", ta_prev_tag[2]);
printf("Accessing ta_prev_tag[ind]: (overflowing into arr2, with modified tag): %p %i \n",
&(ta_prev_tag[ind]), ta_prev_tag[ind]);
printf("Accessing ta[ind]: (overflowing into arr2, with wrong tag): %p %i \n", &(ta[ind]), ta[ind]);
}
void test(int ind)
{
int arr1[4];
int arr2[12];
int a = 101;
printf("IN_test_func: Input ind: %i stored at: %p | arr1 addr: %p | arr2 addr: %p %p | int a: %i addr: %p \n", ind, &ind, arr1, arr2, &arr2, a, &a);
for (int i1 = 0; i1 < 4; i1++)
arr1[i1] = i1 - 7;
for (int i2 = 0; i2 < 12; i2++)
arr2[i2] = i2 + 204;
// printf("Accessing arr2[ind] (intra-stack overflow into arr1): %i \n", arr2[ind]);
printf("Accessing (arr2 tag-1)[ind] (intra-stack overflow into arr1): %i \n", (arr2- INT_TAG_SUBTRACT_ONE)[ind]);
test2(&a, ind);
printf("Finished test2, a: %i \n", a);
}
__attribute__((constructor)) void prep_main_stack(int argc, char **argv) {
printf("####### EXECUTING prep_main_stack function!!!! \n");
prctl(PR_SET_TAGGED_ADDR_CTRL,
PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_SYNC |
(0xfffe << PR_MTE_TAG_SHIFT),
0, 0, 0);
mprotect((void *)(((unsigned long)argv) & ~0xFFF), 4096,
PROT_READ | PROT_WRITE | PROT_MTE | PROT_GROWSDOWN);
}
int main(int argc, char const *argv[])
{
printf("####### EXECUTING main function!! \n");
unsigned long hwcap2 = getauxval(AT_HWCAP2);
/* check if MTE is present */
if (!(hwcap2 & HWCAP2_MTE))
return EXIT_FAILURE;
/*
* Enable the tagged address ABI [for this thread], synchronous or asynchronous MTE
* tag check faults (based on per-CPU preference) and allow all
* non-zero tags in the randomly generated set.
*/
if (prctl(PR_SET_TAGGED_ADDR_CTRL,
PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_SYNC | PR_MTE_TCF_ASYNC |
(0xfffe << PR_MTE_TAG_SHIFT),
0, 0, 0)) {
perror("prctl() failed");
return EXIT_FAILURE;
}
int arr[10];
int ind = atoi(argv[1]);
printf("IN_main_func: hwcap2: %lu addr: %p | arr addr: %p %p | ind: %i addr: %p | will access arr[ind now] \n", hwcap2, &hwcap2, arr, &arr, ind, &ind);
// printf("Accessing arr[ind] (intra-stack overflow): %i \n", arr[ind]);
printf("Accessing (arr tag-1)[ind] : %i \n", (arr - INT_TAG_SUBTRACT_ONE)[ind] );
test( ind );
return 0;
}