]> Git Repo - J-linux.git/blob - tools/testing/selftests/mm/mdwe_test.c
Merge tag 'amd-drm-next-6.5-2023-06-09' of https://gitlab.freedesktop.org/agd5f/linux...
[J-linux.git] / tools / testing / selftests / mm / mdwe_test.c
1 // SPDX-License-Identifier: GPL-2.0
2
3 #ifdef __aarch64__
4 #include <asm/hwcap.h>
5 #endif
6
7 #include <linux/mman.h>
8 #include <linux/prctl.h>
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <sys/auxv.h>
13 #include <sys/prctl.h>
14 #include <sys/wait.h>
15 #include <unistd.h>
16
17 #include "../kselftest_harness.h"
18
19 #ifndef __aarch64__
20 # define PROT_BTI       0
21 #endif
22
23 TEST(prctl_flags)
24 {
25         EXPECT_LT(prctl(PR_SET_MDWE, 7L, 0L, 0L, 0L), 0);
26         EXPECT_LT(prctl(PR_SET_MDWE, 0L, 7L, 0L, 0L), 0);
27         EXPECT_LT(prctl(PR_SET_MDWE, 0L, 0L, 7L, 0L), 0);
28         EXPECT_LT(prctl(PR_SET_MDWE, 0L, 0L, 0L, 7L), 0);
29
30         EXPECT_LT(prctl(PR_GET_MDWE, 7L, 0L, 0L, 0L), 0);
31         EXPECT_LT(prctl(PR_GET_MDWE, 0L, 7L, 0L, 0L), 0);
32         EXPECT_LT(prctl(PR_GET_MDWE, 0L, 0L, 7L, 0L), 0);
33         EXPECT_LT(prctl(PR_GET_MDWE, 0L, 0L, 0L, 7L), 0);
34 }
35
36 FIXTURE(mdwe)
37 {
38         void *p;
39         int flags;
40         size_t size;
41         pid_t pid;
42 };
43
44 FIXTURE_VARIANT(mdwe)
45 {
46         bool enabled;
47         bool forked;
48 };
49
50 FIXTURE_VARIANT_ADD(mdwe, stock)
51 {
52         .enabled = false,
53         .forked = false,
54 };
55
56 FIXTURE_VARIANT_ADD(mdwe, enabled)
57 {
58         .enabled = true,
59         .forked = false,
60 };
61
62 FIXTURE_VARIANT_ADD(mdwe, forked)
63 {
64         .enabled = true,
65         .forked = true,
66 };
67
68 FIXTURE_SETUP(mdwe)
69 {
70         int ret, status;
71
72         self->p = NULL;
73         self->flags = MAP_SHARED | MAP_ANONYMOUS;
74         self->size = getpagesize();
75
76         if (!variant->enabled)
77                 return;
78
79         ret = prctl(PR_SET_MDWE, PR_MDWE_REFUSE_EXEC_GAIN, 0L, 0L, 0L);
80         ASSERT_EQ(ret, 0) {
81                 TH_LOG("PR_SET_MDWE failed or unsupported");
82         }
83
84         ret = prctl(PR_GET_MDWE, 0L, 0L, 0L, 0L);
85         ASSERT_EQ(ret, 1);
86
87         if (variant->forked) {
88                 self->pid = fork();
89                 ASSERT_GE(self->pid, 0) {
90                         TH_LOG("fork failed\n");
91                 }
92
93                 if (self->pid > 0) {
94                         ret = waitpid(self->pid, &status, 0);
95                         ASSERT_TRUE(WIFEXITED(status));
96                         exit(WEXITSTATUS(status));
97                 }
98         }
99 }
100
101 FIXTURE_TEARDOWN(mdwe)
102 {
103         if (self->p && self->p != MAP_FAILED)
104                 munmap(self->p, self->size);
105 }
106
107 TEST_F(mdwe, mmap_READ_EXEC)
108 {
109         self->p = mmap(NULL, self->size, PROT_READ | PROT_EXEC, self->flags, 0, 0);
110         EXPECT_NE(self->p, MAP_FAILED);
111 }
112
113 TEST_F(mdwe, mmap_WRITE_EXEC)
114 {
115         self->p = mmap(NULL, self->size, PROT_WRITE | PROT_EXEC, self->flags, 0, 0);
116         if (variant->enabled) {
117                 EXPECT_EQ(self->p, MAP_FAILED);
118         } else {
119                 EXPECT_NE(self->p, MAP_FAILED);
120         }
121 }
122
123 TEST_F(mdwe, mprotect_stay_EXEC)
124 {
125         int ret;
126
127         self->p = mmap(NULL, self->size, PROT_READ | PROT_EXEC, self->flags, 0, 0);
128         ASSERT_NE(self->p, MAP_FAILED);
129
130         ret = mprotect(self->p, self->size, PROT_READ | PROT_EXEC);
131         EXPECT_EQ(ret, 0);
132 }
133
134 TEST_F(mdwe, mprotect_add_EXEC)
135 {
136         int ret;
137
138         self->p = mmap(NULL, self->size, PROT_READ, self->flags, 0, 0);
139         ASSERT_NE(self->p, MAP_FAILED);
140
141         ret = mprotect(self->p, self->size, PROT_READ | PROT_EXEC);
142         if (variant->enabled) {
143                 EXPECT_LT(ret, 0);
144         } else {
145                 EXPECT_EQ(ret, 0);
146         }
147 }
148
149 TEST_F(mdwe, mprotect_WRITE_EXEC)
150 {
151         int ret;
152
153         self->p = mmap(NULL, self->size, PROT_WRITE, self->flags, 0, 0);
154         ASSERT_NE(self->p, MAP_FAILED);
155
156         ret = mprotect(self->p, self->size, PROT_WRITE | PROT_EXEC);
157         if (variant->enabled) {
158                 EXPECT_LT(ret, 0);
159         } else {
160                 EXPECT_EQ(ret, 0);
161         }
162 }
163
164 TEST_F(mdwe, mmap_FIXED)
165 {
166         void *p;
167
168         self->p = mmap(NULL, self->size, PROT_READ, self->flags, 0, 0);
169         ASSERT_NE(self->p, MAP_FAILED);
170
171         p = mmap(self->p + self->size, self->size, PROT_READ | PROT_EXEC,
172                  self->flags | MAP_FIXED, 0, 0);
173         if (variant->enabled) {
174                 EXPECT_EQ(p, MAP_FAILED);
175         } else {
176                 EXPECT_EQ(p, self->p);
177         }
178 }
179
180 TEST_F(mdwe, arm64_BTI)
181 {
182         int ret;
183
184 #ifdef __aarch64__
185         if (!(getauxval(AT_HWCAP2) & HWCAP2_BTI))
186 #endif
187                 SKIP(return, "HWCAP2_BTI not supported");
188
189         self->p = mmap(NULL, self->size, PROT_EXEC, self->flags, 0, 0);
190         ASSERT_NE(self->p, MAP_FAILED);
191
192         ret = mprotect(self->p, self->size, PROT_EXEC | PROT_BTI);
193         EXPECT_EQ(ret, 0);
194 }
195
196 TEST_HARNESS_MAIN
This page took 0.036387 seconds and 4 git commands to generate.