1 /* Linux/x86-64 CET initializers function.
2 Copyright (C) 2023-2024 Free Software Foundation, Inc.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <https://www.gnu.org/licenses/>. */
18 #include <sys/prctl.h>
19 #include <asm/prctl.h>
20 #include <features-offsets.h>
22 static __always_inline
int
23 dl_cet_disable_cet (unsigned int cet_feature
)
25 if (cet_feature
!= GNU_PROPERTY_X86_FEATURE_1_SHSTK
)
27 long long int kernel_feature
= ARCH_SHSTK_SHSTK
;
28 return (int) INTERNAL_SYSCALL_CALL (arch_prctl
, ARCH_SHSTK_DISABLE
,
32 static __always_inline
int
33 dl_cet_lock_cet (unsigned int cet_feature
)
35 if (cet_feature
!= GNU_PROPERTY_X86_FEATURE_1_SHSTK
)
37 /* Lock all SHSTK features. */
38 long long int kernel_feature
= -1;
39 return (int) INTERNAL_SYSCALL_CALL (arch_prctl
, ARCH_SHSTK_LOCK
,
43 static __always_inline
unsigned int
44 dl_cet_get_cet_status (void)
46 unsigned long long kernel_feature
;
47 unsigned int status
= 0;
48 if (INTERNAL_SYSCALL_CALL (arch_prctl
, ARCH_SHSTK_STATUS
,
49 &kernel_feature
) == 0)
51 if ((kernel_feature
& ARCH_SHSTK_SHSTK
) != 0)
52 status
= GNU_PROPERTY_X86_FEATURE_1_SHSTK
;
57 static __always_inline
bool
58 dl_cet_ibt_enabled (void)
60 unsigned int feature_1
= THREAD_GETMEM (THREAD_SELF
,
62 return (feature_1
& GNU_PROPERTY_X86_FEATURE_1_IBT
) != 0;
65 /* Enable shadow stack with a macro to avoid shadow stack underflow. */
66 #define ENABLE_X86_CET(cet_feature) \
67 if ((cet_feature & GNU_PROPERTY_X86_FEATURE_1_SHSTK)) \
69 long long int kernel_feature = ARCH_SHSTK_SHSTK; \
70 INTERNAL_SYSCALL_CALL (arch_prctl, ARCH_SHSTK_ENABLE, \
74 #define X86_STRINGIFY_1(x) #x
75 #define X86_STRINGIFY(x) X86_STRINGIFY_1 (x)
77 /* Enable shadow stack before calling _dl_init if it is enabled in
78 GL(dl_x86_feature_1). Call _dl_setup_x86_features to setup shadow
80 #define RTLD_START_ENABLE_X86_FEATURES \
82 # Check if shadow stack is enabled in GL(dl_x86_feature_1).\n\
83 movl _rtld_local+" X86_STRINGIFY (RTLD_GLOBAL_DL_X86_FEATURE_1_OFFSET) "(%rip), %edx\n\
84 testl $" X86_STRINGIFY (X86_FEATURE_1_SHSTK) ", %edx\n\
86 # Enable shadow stack if enabled in GL(dl_x86_feature_1).\n\
87 movl $" X86_STRINGIFY (ARCH_SHSTK_SHSTK) ", %esi\n\
88 movl $" X86_STRINGIFY (ARCH_SHSTK_ENABLE) ", %edi\n\
89 movl $" X86_STRINGIFY (__NR_arch_prctl) ", %eax\n\
92 # Pass GL(dl_x86_feature_1) to _dl_cet_setup_features.\n\
94 # Align stack for the _dl_cet_setup_features call.\n\
96 call _dl_cet_setup_features\n\
97 # Restore %rax and %rsp from %r12 and %r13.\n\