Skip to content

Commit db71cc5

Browse files
authored
[libc] Implement pkey_alloc/free/get/set/mprotect for x86_64 linux (#162362)
This patch provides definitions for `pkey_*` functions for linux x86_64. `pkey_alloc`, `pkey_free`, and `pkey_mprotect` are simple syscall wrappers. `pkey_set` and `pkey_get` modify architecture-specific registers. The logic for these live in architecture specific directories: * `libc/src/sys/mman/linux/x86_64/pkey_common.h` has a real implementation * `libc/src/sys/mman/linux/generic/pkey_common.h` contains stubs that just return `ENOSYS`.
1 parent 6665642 commit db71cc5

File tree

26 files changed

+1007
-12
lines changed

26 files changed

+1007
-12
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/include/sys/mman.yaml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,41 @@ functions:
101101
arguments:
102102
- type: void *
103103
- type: size_t
104+
- name: pkey_alloc
105+
standards:
106+
- Linux
107+
return_type: int
108+
arguments:
109+
- type: unsigned int
110+
- type: unsigned int
111+
- name: pkey_free
112+
standards:
113+
- Linux
114+
return_type: int
115+
arguments:
116+
- type: int
117+
- name: pkey_get
118+
standards:
119+
- GNU
120+
return_type: int
121+
arguments:
122+
- type: int
123+
- name: pkey_mprotect
124+
standards:
125+
- Linux
126+
return_type: int
127+
arguments:
128+
- type: void *
129+
- type: size_t
130+
- type: int
131+
- type: int
132+
- name: pkey_set
133+
standards:
134+
- GNU
135+
return_type: int
136+
arguments:
137+
- type: int
138+
- type: unsigned int
104139
- name: posix_madvise
105140
standards:
106141
- POSIX

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: 95 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
@@ -50,6 +57,17 @@ add_entrypoint_object(
5057
libc.src.errno.errno
5158
)
5259

60+
add_header_library(
61+
mprotect_common
62+
HDRS
63+
mprotect_common.h
64+
DEPENDS
65+
libc.include.sys_syscall
66+
libc.src.__support.OSUtil.osutil
67+
libc.src.errno.errno
68+
libc.src.__support.error_or
69+
)
70+
5371
add_entrypoint_object(
5472
mprotect
5573
SRCS
@@ -61,6 +79,7 @@ add_entrypoint_object(
6179
libc.include.sys_syscall
6280
libc.src.__support.OSUtil.osutil
6381
libc.src.errno.errno
82+
.mprotect_common
6483
)
6584

6685
add_entrypoint_object(
@@ -166,6 +185,82 @@ add_entrypoint_object(
166185
libc.src.errno.errno
167186
)
168187

188+
add_entrypoint_object(
189+
pkey_alloc
190+
SRCS
191+
pkey_alloc.cpp
192+
HDRS
193+
../pkey_alloc.h
194+
DEPENDS
195+
libc.include.sys_mman
196+
libc.include.sys_syscall
197+
libc.src.__support.OSUtil.osutil
198+
libc.src.errno.errno
199+
)
200+
201+
add_header_library(
202+
pkey_common
203+
HDRS
204+
pkey_common.h
205+
DEPENDS
206+
.${ARCH_SUBDIRECTORY}.pkey_common
207+
)
208+
209+
add_entrypoint_object(
210+
pkey_free
211+
SRCS
212+
pkey_free.cpp
213+
HDRS
214+
../pkey_free.h
215+
DEPENDS
216+
libc.include.sys_mman
217+
libc.include.sys_syscall
218+
libc.src.__support.OSUtil.osutil
219+
libc.src.errno.errno
220+
)
221+
222+
add_entrypoint_object(
223+
pkey_get
224+
SRCS
225+
pkey_get.cpp
226+
HDRS
227+
../pkey_get.h
228+
DEPENDS
229+
libc.include.sys_mman
230+
libc.include.sys_syscall
231+
libc.src.__support.OSUtil.osutil
232+
libc.src.errno.errno
233+
.pkey_common
234+
)
235+
236+
add_entrypoint_object(
237+
pkey_mprotect
238+
SRCS
239+
pkey_mprotect.cpp
240+
HDRS
241+
../pkey_mprotect.h
242+
DEPENDS
243+
libc.include.sys_mman
244+
libc.include.sys_syscall
245+
libc.src.__support.OSUtil.osutil
246+
libc.src.errno.errno
247+
.mprotect_common
248+
)
249+
250+
add_entrypoint_object(
251+
pkey_set
252+
SRCS
253+
pkey_set.cpp
254+
HDRS
255+
../pkey_set.h
256+
DEPENDS
257+
libc.include.sys_mman
258+
libc.include.sys_syscall
259+
libc.src.__support.OSUtil.osutil
260+
libc.src.errno.errno
261+
.pkey_common
262+
)
263+
169264
add_entrypoint_object(
170265
remap_file_pages
171266
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: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//===---------- Generic stub implementations for pkey functionality. ------===//
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+
#ifndef LLVM_SYS_MMAN_LINUX_GENERIC_PKEY_COMMON_H_
10+
#define LLVM_SYS_MMAN_LINUX_GENERIC_PKEY_COMMON_H_
11+
12+
#include "hdr/errno_macros.h" // For ENOSYS
13+
#include "src/__support/common.h"
14+
#include "src/__support/error_or.h"
15+
16+
namespace LIBC_NAMESPACE_DECL {
17+
namespace pkey_common {
18+
19+
LIBC_INLINE ErrorOr<int> pkey_get([[maybe_unused]] int pkey) {
20+
return Error(ENOSYS);
21+
}
22+
23+
LIBC_INLINE ErrorOr<int> pkey_set([[maybe_unused]] int pkey,
24+
[[maybe_unused]] unsigned int access_rights) {
25+
return Error(ENOSYS);
26+
}
27+
28+
} // namespace pkey_common
29+
} // namespace LIBC_NAMESPACE_DECL
30+
31+
#endif // LLVM_SYS_MMAN_LINUX_GENERIC_PKEY_COMMON_H_

libc/src/sys/mman/linux/mprotect.cpp

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,22 @@
1111
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
1212
#include "src/__support/common.h"
1313

14+
#include "src/__support/error_or.h"
1415
#include "src/__support/libc_errno.h"
1516
#include "src/__support/macros/config.h"
17+
#include "src/sys/mman/linux/mprotect_common.h"
1618
#include <sys/syscall.h> // For syscall numbers.
1719

1820
namespace LIBC_NAMESPACE_DECL {
1921

20-
// This function is currently linux only. It has to be refactored suitably if
21-
// mprotect is to be supported on non-linux operating systems also.
2222
LLVM_LIBC_FUNCTION(int, mprotect, (void *addr, size_t size, int prot)) {
23-
int ret = LIBC_NAMESPACE::syscall_impl<int>(
24-
SYS_mprotect, reinterpret_cast<long>(addr), size, prot);
25-
26-
// A negative return value indicates an error with the magnitude of the
27-
// value being the error code.
28-
if (ret < 0) {
29-
libc_errno = -ret;
23+
ErrorOr<int> result =
24+
LIBC_NAMESPACE::mprotect_common::mprotect_impl(addr, size, prot);
25+
if (!result.has_value()) {
26+
libc_errno = result.error();
3027
return -1;
3128
}
32-
33-
return 0;
29+
return result.value();
3430
}
3531

3632
} // namespace LIBC_NAMESPACE_DECL
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//===---------- Shared Linux implementation of POSIX mprotect. ------------===//
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/__support/OSUtil/syscall.h" // For internal syscall function.
10+
#include "src/__support/common.h"
11+
#include "src/__support/error_or.h"
12+
#include "src/__support/libc_errno.h"
13+
#include "src/__support/macros/attributes.h"
14+
#include "src/__support/macros/config.h"
15+
#include <sys/syscall.h> // For syscall numbers.
16+
17+
namespace LIBC_NAMESPACE_DECL {
18+
19+
namespace mprotect_common {
20+
21+
// This function is currently linux only. It has to be refactored suitably if
22+
// mprotect is to be supported on non-linux operating systems also.
23+
LIBC_INLINE ErrorOr<int> mprotect_impl(void *addr, size_t size, int prot) {
24+
int ret = LIBC_NAMESPACE::syscall_impl<int>(
25+
SYS_mprotect, reinterpret_cast<long>(addr), size, prot);
26+
27+
// A negative return value indicates an error with the magnitude of the
28+
// value being the error code.
29+
if (ret < 0) {
30+
return Error(-ret);
31+
}
32+
33+
return 0;
34+
}
35+
36+
} // namespace mprotect_common
37+
38+
} // namespace LIBC_NAMESPACE_DECL
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 = -ret;
31+
return -1;
32+
}
33+
return static_cast<int>(ret);
34+
#endif
35+
}
36+
37+
} // namespace LIBC_NAMESPACE_DECL
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
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/__support/macros/properties/architectures.h"
10+
11+
#if defined(LIBC_TARGET_ARCH_IS_X86_64)
12+
#include "src/sys/mman/linux/x86_64/pkey_common.h"
13+
#else
14+
#include "src/sys/mman/linux/generic/pkey_common.h"
15+
#endif

0 commit comments

Comments
 (0)