NEWS: Add advisories.
[glibc.git] / sysdeps / unix / sysv / linux / x86_64 / dl-cet.h
blob1fe313340611d9c569b7761bf8670337efc22b7b
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)
26 return -1;
27 long long int kernel_feature = ARCH_SHSTK_SHSTK;
28 return (int) INTERNAL_SYSCALL_CALL (arch_prctl, ARCH_SHSTK_DISABLE,
29 kernel_feature);
32 static __always_inline int
33 dl_cet_lock_cet (unsigned int cet_feature)
35 if (cet_feature != GNU_PROPERTY_X86_FEATURE_1_SHSTK)
36 return -1;
37 /* Lock all SHSTK features. */
38 long long int kernel_feature = -1;
39 return (int) INTERNAL_SYSCALL_CALL (arch_prctl, ARCH_SHSTK_LOCK,
40 kernel_feature);
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;
54 return status;
57 static __always_inline bool
58 dl_cet_ibt_enabled (void)
60 unsigned int feature_1 = THREAD_GETMEM (THREAD_SELF,
61 header.feature_1);
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)) \
68 { \
69 long long int kernel_feature = ARCH_SHSTK_SHSTK; \
70 INTERNAL_SYSCALL_CALL (arch_prctl, ARCH_SHSTK_ENABLE, \
71 kernel_feature); \
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
79 stack. */
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\
85 jz 1f\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\
90 syscall\n\
91 1:\n\
92 # Pass GL(dl_x86_feature_1) to _dl_cet_setup_features.\n\
93 movl %edx, %edi\n\
94 # Align stack for the _dl_cet_setup_features call.\n\
95 andq $-16, %rsp\n\
96 call _dl_cet_setup_features\n\
97 # Restore %rax and %rsp from %r12 and %r13.\n\
98 movq %r12, %rax\n\
99 movq %r13, %rsp\n\