Skip to content

Commit 6e1e1b1

Browse files
committed
Implement pkey alloc/free/get/set/mprotect for x86_64 linux
1 parent 605e2d1 commit 6e1e1b1

File tree

22 files changed

+874
-0
lines changed

22 files changed

+874
-0
lines changed

libc/config/linux/x86_64/entrypoints.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,11 @@ set(TARGET_LIBC_ENTRYPOINTS
264264
libc.src.sys.mman.munlock
265265
libc.src.sys.mman.munlockall
266266
libc.src.sys.mman.munmap
267+
libc.src.sys.mman.pkey_alloc
268+
libc.src.sys.mman.pkey_free
269+
libc.src.sys.mman.pkey_get
270+
libc.src.sys.mman.pkey_mprotect
271+
libc.src.sys.mman.pkey_set
267272
libc.src.sys.mman.remap_file_pages
268273
libc.src.sys.mman.posix_madvise
269274
libc.src.sys.mman.shm_open

libc/src/sys/mman/CMakeLists.txt

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,41 @@ add_entrypoint_object(
8686
.${LIBC_TARGET_OS}.msync
8787
)
8888

89+
add_entrypoint_object(
90+
pkey_alloc
91+
ALIAS
92+
DEPENDS
93+
.${LIBC_TARGET_OS}.pkey_alloc
94+
)
95+
96+
add_entrypoint_object(
97+
pkey_free
98+
ALIAS
99+
DEPENDS
100+
.${LIBC_TARGET_OS}.pkey_free
101+
)
102+
103+
add_entrypoint_object(
104+
pkey_get
105+
ALIAS
106+
DEPENDS
107+
.${LIBC_TARGET_OS}.pkey_get
108+
)
109+
110+
add_entrypoint_object(
111+
pkey_mprotect
112+
ALIAS
113+
DEPENDS
114+
.${LIBC_TARGET_OS}.pkey_mprotect
115+
)
116+
117+
add_entrypoint_object(
118+
pkey_set
119+
ALIAS
120+
DEPENDS
121+
.${LIBC_TARGET_OS}.pkey_set
122+
)
123+
89124
add_entrypoint_object(
90125
remap_file_pages
91126
ALIAS

libc/src/sys/mman/linux/CMakeLists.txt

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
add_subdirectory(generic)
2+
set(ARCH_SUBDIRECTORY generic)
3+
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_ARCHITECTURE})
4+
add_subdirectory(${LIBC_TARGET_ARCHITECTURE})
5+
set(ARCH_SUBDIRECTORY ${LIBC_TARGET_ARCHITECTURE})
6+
endif()
7+
18
add_entrypoint_object(
29
madvise
310
SRCS
@@ -166,6 +173,74 @@ add_entrypoint_object(
166173
libc.src.errno.errno
167174
)
168175

176+
add_entrypoint_object(
177+
pkey_alloc
178+
SRCS
179+
pkey_alloc.cpp
180+
HDRS
181+
../pkey_alloc.h
182+
DEPENDS
183+
libc.include.sys_mman
184+
libc.include.sys_syscall
185+
libc.src.__support.OSUtil.osutil
186+
libc.src.errno.errno
187+
)
188+
189+
add_entrypoint_object(
190+
pkey_free
191+
SRCS
192+
pkey_free.cpp
193+
HDRS
194+
../pkey_free.h
195+
DEPENDS
196+
libc.include.sys_mman
197+
libc.include.sys_syscall
198+
libc.src.__support.OSUtil.osutil
199+
libc.src.errno.errno
200+
)
201+
202+
add_entrypoint_object(
203+
pkey_get
204+
SRCS
205+
pkey_get.cpp
206+
HDRS
207+
../pkey_get.h
208+
DEPENDS
209+
libc.include.sys_mman
210+
libc.include.sys_syscall
211+
libc.src.__support.OSUtil.osutil
212+
libc.src.errno.errno
213+
.${ARCH_SUBDIRECTORY}.pkey_common
214+
)
215+
216+
add_entrypoint_object(
217+
pkey_mprotect
218+
SRCS
219+
pkey_mprotect.cpp
220+
HDRS
221+
../pkey_mprotect.h
222+
DEPENDS
223+
libc.include.sys_mman
224+
libc.include.sys_syscall
225+
libc.src.__support.OSUtil.osutil
226+
libc.src.sys.mman.mprotect
227+
libc.src.errno.errno
228+
)
229+
230+
add_entrypoint_object(
231+
pkey_set
232+
SRCS
233+
pkey_set.cpp
234+
HDRS
235+
../pkey_set.h
236+
DEPENDS
237+
libc.include.sys_mman
238+
libc.include.sys_syscall
239+
libc.src.__support.OSUtil.osutil
240+
libc.src.errno.errno
241+
.${ARCH_SUBDIRECTORY}.pkey_common
242+
)
243+
169244
add_entrypoint_object(
170245
remap_file_pages
171246
SRCS
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
add_header_library(
2+
pkey_common
3+
HDRS
4+
pkey_common.h
5+
DEPENDS
6+
libc.hdr.errno_macros
7+
libc.src.__support.common
8+
libc.src.__support.error_or
9+
)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#ifndef LLVM_SYS_MMAN_LINUX_GENERIC_PKEY_COMMON_H_
2+
#define LLVM_SYS_MMAN_LINUX_GENERIC_PKEY_COMMON_H_
3+
4+
#include "hdr/errno_macros.h" // For ENOSYS
5+
#include "src/__support/common.h"
6+
#include "src/__support/error_or.h"
7+
8+
namespace LIBC_NAMESPACE_DECL {
9+
namespace pkey_common {
10+
11+
LIBC_INLINE ErrorOr<int> pkey_get(int pkey) {
12+
(void)pkey;
13+
return Error(ENOSYS);
14+
}
15+
16+
LIBC_INLINE ErrorOr<int> pkey_set(int pkey, unsigned int access_rights) {
17+
(void)pkey;
18+
(void)access_rights;
19+
return Error(ENOSYS);
20+
}
21+
22+
} // namespace pkey_common
23+
} // namespace LIBC_NAMESPACE_DECL
24+
25+
#endif // LLVM_SYS_MMAN_LINUX_GENERIC_PKEY_COMMON_H_
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//===---------- Linux implementation of the Linux pkey_alloc function -----===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "src/sys/mman/pkey_alloc.h"
10+
11+
#include "hdr/errno_macros.h" // For ENOSYS
12+
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
13+
#include "src/__support/common.h"
14+
#include "src/__support/libc_errno.h"
15+
#include "src/__support/macros/config.h"
16+
17+
#include <sys/syscall.h> // For syscall numbers.
18+
19+
namespace LIBC_NAMESPACE_DECL {
20+
21+
LLVM_LIBC_FUNCTION(int, pkey_alloc,
22+
(unsigned int flags, unsigned int access_rights)) {
23+
#if !defined(SYS_pkey_alloc)
24+
libc_errno = ENOSYS;
25+
return -1;
26+
#else
27+
int ret =
28+
LIBC_NAMESPACE::syscall_impl<int>(SYS_pkey_alloc, flags, access_rights);
29+
if (ret < 0) {
30+
libc_errno = static_cast<int>(-ret);
31+
return -1;
32+
}
33+
return static_cast<int>(ret);
34+
#endif
35+
}
36+
37+
} // namespace LIBC_NAMESPACE_DECL
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//===---------- Linux implementation of the Linux pkey_free function ------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "src/sys/mman/pkey_free.h"
10+
11+
#include "hdr/errno_macros.h" // For ENOSYS
12+
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
13+
#include "src/__support/common.h"
14+
#include "src/__support/libc_errno.h"
15+
#include "src/__support/macros/config.h"
16+
17+
#include <sys/syscall.h> // For syscall numbers.
18+
19+
namespace LIBC_NAMESPACE_DECL {
20+
21+
LLVM_LIBC_FUNCTION(int, pkey_free, (int pkey)) {
22+
#if !defined(SYS_pkey_free)
23+
libc_errno = ENOSYS;
24+
return -1;
25+
#else
26+
int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_pkey_free, pkey);
27+
if (ret < 0) {
28+
libc_errno = static_cast<int>(-ret);
29+
return -1;
30+
}
31+
return 0;
32+
#endif
33+
}
34+
35+
} // namespace LIBC_NAMESPACE_DECL
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//===---------- Linux implementation of the Linux pkey_mprotect function --===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "src/sys/mman/pkey_get.h"
10+
11+
#include "hdr/errno_macros.h" // For ENOSYS
12+
#include "src/__support/common.h"
13+
#include "src/__support/error_or.h"
14+
#include "src/__support/libc_errno.h"
15+
#include "src/__support/macros/config.h"
16+
#include "src/__support/macros/properties/architectures.h"
17+
18+
#if defined(LIBC_TARGET_ARCH_IS_X86_64)
19+
#include "src/sys/mman/linux/x86_64/pkey_common.h"
20+
#else
21+
#include "src/sys/mman/linux/generic/pkey_common.h"
22+
#endif
23+
24+
namespace LIBC_NAMESPACE_DECL {
25+
26+
LLVM_LIBC_FUNCTION(int, pkey_get, (int pkey)) {
27+
ErrorOr<int> ret = LIBC_NAMESPACE::pkey_common::pkey_get(pkey);
28+
if (!ret.has_value()) {
29+
libc_errno = ret.error();
30+
return -1;
31+
}
32+
return ret.value();
33+
}
34+
35+
} // namespace LIBC_NAMESPACE_DECL
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//===---------- Linux implementation of the Linux pkey_mprotect function --===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "src/sys/mman/pkey_mprotect.h"
10+
11+
#include "hdr/errno_macros.h" // For ENOSYS
12+
#include "hdr/types/size_t.h"
13+
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
14+
#include "src/__support/common.h"
15+
#include "src/__support/libc_errno.h"
16+
#include "src/__support/macros/config.h"
17+
#include "src/sys/mman/mprotect.h"
18+
19+
#include <sys/syscall.h> // For syscall numbers.
20+
21+
namespace LIBC_NAMESPACE_DECL {
22+
23+
LLVM_LIBC_FUNCTION(int, pkey_mprotect,
24+
(void *addr, size_t len, int prot, int pkey)) {
25+
// Fall back to mprotect if pkey is -1
26+
// to maintain compatibility with kernel versions that don't support pkey.
27+
if (pkey == -1) {
28+
return LIBC_NAMESPACE::mprotect(addr, len, prot);
29+
}
30+
31+
#if !defined(SYS_pkey_mprotect)
32+
libc_errno = ENOSYS;
33+
return -1;
34+
#else
35+
int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_pkey_mprotect, addr, len,
36+
prot, pkey);
37+
if (ret < 0) {
38+
libc_errno = -ret;
39+
return -1;
40+
}
41+
return 0;
42+
#endif
43+
}
44+
45+
} // namespace LIBC_NAMESPACE_DECL
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//===---------- Linux implementation of the Linux pkey_mprotect function --===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "src/sys/mman/pkey_set.h"
10+
11+
#include "hdr/errno_macros.h" // For ENOSYS
12+
#include "src/__support/common.h"
13+
#include "src/__support/error_or.h"
14+
#include "src/__support/libc_errno.h"
15+
#include "src/__support/macros/attributes.h"
16+
#include "src/__support/macros/config.h"
17+
18+
#if defined(LIBC_TARGET_ARCH_IS_X86_64)
19+
#include "src/sys/mman/linux/x86_64/pkey_common.h"
20+
#else
21+
#include "src/sys/mman/linux/generic/pkey_common.h"
22+
#endif
23+
24+
namespace LIBC_NAMESPACE_DECL {
25+
26+
LLVM_LIBC_FUNCTION(int, pkey_set, (int pkey, unsigned int access_rights)) {
27+
ErrorOr<int> ret = LIBC_NAMESPACE::pkey_common::pkey_set(pkey, access_rights);
28+
if (!ret.has_value()) {
29+
libc_errno = ret.error();
30+
return -1;
31+
}
32+
return ret.value();
33+
}
34+
35+
} // namespace LIBC_NAMESPACE_DECL

0 commit comments

Comments
 (0)