1 // SPDX-License-Identifier: GPL-2.0
7 #include <linux/mman.h>
8 #include <linux/prctl.h>
13 #include <sys/prctl.h>
17 #include "../kselftest_harness.h"
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);
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);
50 FIXTURE_VARIANT_ADD(mdwe, stock)
56 FIXTURE_VARIANT_ADD(mdwe, enabled)
62 FIXTURE_VARIANT_ADD(mdwe, forked)
73 self->flags = MAP_SHARED | MAP_ANONYMOUS;
74 self->size = getpagesize();
76 if (!variant->enabled)
79 ret = prctl(PR_SET_MDWE, PR_MDWE_REFUSE_EXEC_GAIN, 0L, 0L, 0L);
81 TH_LOG("PR_SET_MDWE failed or unsupported");
84 ret = prctl(PR_GET_MDWE, 0L, 0L, 0L, 0L);
87 if (variant->forked) {
89 ASSERT_GE(self->pid, 0) {
90 TH_LOG("fork failed\n");
94 ret = waitpid(self->pid, &status, 0);
95 ASSERT_TRUE(WIFEXITED(status));
96 exit(WEXITSTATUS(status));
101 FIXTURE_TEARDOWN(mdwe)
103 if (self->p && self->p != MAP_FAILED)
104 munmap(self->p, self->size);
107 TEST_F(mdwe, mmap_READ_EXEC)
109 self->p = mmap(NULL, self->size, PROT_READ | PROT_EXEC, self->flags, 0, 0);
110 EXPECT_NE(self->p, MAP_FAILED);
113 TEST_F(mdwe, mmap_WRITE_EXEC)
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);
119 EXPECT_NE(self->p, MAP_FAILED);
123 TEST_F(mdwe, mprotect_stay_EXEC)
127 self->p = mmap(NULL, self->size, PROT_READ | PROT_EXEC, self->flags, 0, 0);
128 ASSERT_NE(self->p, MAP_FAILED);
130 ret = mprotect(self->p, self->size, PROT_READ | PROT_EXEC);
134 TEST_F(mdwe, mprotect_add_EXEC)
138 self->p = mmap(NULL, self->size, PROT_READ, self->flags, 0, 0);
139 ASSERT_NE(self->p, MAP_FAILED);
141 ret = mprotect(self->p, self->size, PROT_READ | PROT_EXEC);
142 if (variant->enabled) {
149 TEST_F(mdwe, mprotect_WRITE_EXEC)
153 self->p = mmap(NULL, self->size, PROT_WRITE, self->flags, 0, 0);
154 ASSERT_NE(self->p, MAP_FAILED);
156 ret = mprotect(self->p, self->size, PROT_WRITE | PROT_EXEC);
157 if (variant->enabled) {
164 TEST_F(mdwe, mmap_FIXED)
168 self->p = mmap(NULL, self->size, PROT_READ, self->flags, 0, 0);
169 ASSERT_NE(self->p, MAP_FAILED);
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);
176 EXPECT_EQ(p, self->p);
180 TEST_F(mdwe, arm64_BTI)
185 if (!(getauxval(AT_HWCAP2) & HWCAP2_BTI))
187 SKIP(return, "HWCAP2_BTI not supported");
189 self->p = mmap(NULL, self->size, PROT_EXEC, self->flags, 0, 0);
190 ASSERT_NE(self->p, MAP_FAILED);
192 ret = mprotect(self->p, self->size, PROT_EXEC | PROT_BTI);