x86: Add ENDBR at function entries
Intel Control-flow Enforcement Technology (CET): https://software.intel.com/en-us/articles/intel-sdm contains shadow stack (SHSTK) and indirect branch tracking (IBT). When CET is enabled, ELF object files must be marked with .note.gnu.property section. Also when IBT is enabled, all indirect branch targets must start with ENDBR instruction which is NOP on non-CET processors. This fixes: https://gitlab.freedesktop.org/glvnd/libglvnd/issues/202
This commit is contained in:
parent
cb7b1fb019
commit
f96f6bde04
|
@ -39,4 +39,14 @@
|
|||
extern char public_entry_start[];
|
||||
extern char public_entry_end[];
|
||||
|
||||
#ifdef __CET__
|
||||
#ifdef __x86_64__
|
||||
#define ENDBR "endbr64\n\t"
|
||||
#else
|
||||
#define ENDBR "endbr32\n\t"
|
||||
#endif
|
||||
#else
|
||||
#define ENDBR
|
||||
#endif
|
||||
|
||||
#endif // ENTRY_COMMON_H
|
||||
|
|
|
@ -58,6 +58,7 @@ __asm__(".balign " U_STRINGIFY(GLDISPATCH_PAGE_SIZE) "\n"
|
|||
#ifdef __ILP32__
|
||||
|
||||
#define STUB_ASM_CODE(slot) \
|
||||
ENDBR \
|
||||
"movq _glapi_tls_Current@GOTTPOFF(%rip), %rax\n\t" \
|
||||
"movl %fs:(%rax), %r11d\n\t" \
|
||||
"movl 4*" slot "(%r11d), %r11d\n\t" \
|
||||
|
@ -66,6 +67,7 @@ __asm__(".balign " U_STRINGIFY(GLDISPATCH_PAGE_SIZE) "\n"
|
|||
#else // __ILP32__
|
||||
|
||||
#define STUB_ASM_CODE(slot) \
|
||||
ENDBR \
|
||||
"movq _glapi_tls_Current@GOTTPOFF(%rip), %rax\n\t" \
|
||||
"movq %fs:(%rax), %r11\n\t" \
|
||||
"jmp *(8 * " slot ")(%r11)"
|
||||
|
|
|
@ -69,6 +69,7 @@ __asm__(".balign " U_STRINGIFY(GLDISPATCH_PAGE_SIZE) "\n"
|
|||
* assume that they're within 2GB of %rip.
|
||||
*/
|
||||
#define STUB_ASM_CODE(slot) \
|
||||
ENDBR \
|
||||
"movq _glapi_Current@GOTPCREL(%rip), %rax\n\t" \
|
||||
"movq (%rax), %rax\n" \
|
||||
"test %rax, %rax\n\t" \
|
||||
|
|
|
@ -56,6 +56,7 @@ __asm__(".balign " U_STRINGIFY(GLDISPATCH_PAGE_SIZE) "\n"
|
|||
func ":\n"
|
||||
|
||||
#define STUB_ASM_CODE(slot) \
|
||||
ENDBR \
|
||||
"call 1f\n\t" \
|
||||
"1:\n\t" \
|
||||
"popl %eax\n\t" \
|
||||
|
|
|
@ -56,6 +56,7 @@ __asm__(".balign " U_STRINGIFY(GLDISPATCH_PAGE_SIZE) "\n"
|
|||
func ":\n"
|
||||
|
||||
#define STUB_ASM_CODE(slot) \
|
||||
ENDBR \
|
||||
"call 1f\n" \
|
||||
"1:\n" \
|
||||
"popl %ecx\n" \
|
||||
|
|
|
@ -44,6 +44,7 @@ static void patch_x86_64(char *writeEntry, const char *execEntry,
|
|||
// that it's the right size for either build.
|
||||
uint64_t incrementAddr = (uint64_t) ((uintptr_t) incrementPtr);
|
||||
const char tmpl[] = {
|
||||
0xf3, 0x0f, 0x1e, 0xfa, // endbr64
|
||||
0xa1, 0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12, // movabs 0x123456789abcdef0, %eax
|
||||
0x83, 0xc0, 0x01, // add $0x1,%eax
|
||||
0xa3, 0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12, // movabs %eax,0x123456789abcdef0
|
||||
|
@ -55,8 +56,8 @@ static void patch_x86_64(char *writeEntry, const char *execEntry,
|
|||
}
|
||||
|
||||
memcpy(writeEntry, tmpl, sizeof(tmpl));
|
||||
memcpy(writeEntry + 1, &incrementAddr, sizeof(incrementAddr));
|
||||
memcpy(writeEntry + 13, &incrementAddr, sizeof(incrementAddr));
|
||||
memcpy(writeEntry + 5, &incrementAddr, sizeof(incrementAddr));
|
||||
memcpy(writeEntry + 17, &incrementAddr, sizeof(incrementAddr));
|
||||
|
||||
#else
|
||||
assert(0); // Should not be calling this
|
||||
|
@ -70,6 +71,7 @@ static void patch_x86(char *writeEntry, const char *execEntry,
|
|||
#if defined(__i386__)
|
||||
uintptr_t *p;
|
||||
char tmpl[] = {
|
||||
0xf3, 0x0f, 0x1e, 0xfb, // endbr32
|
||||
0xa1, 0x0, 0x0, 0x0, 0x0, // mov 0x0, %eax
|
||||
0x83, 0xc0, 0x01, // add $0x1, %eax
|
||||
0xa3, 0x0, 0x0, 0x0, 0x0, // mov %eax, 0x0
|
||||
|
@ -83,10 +85,10 @@ static void patch_x86(char *writeEntry, const char *execEntry,
|
|||
}
|
||||
|
||||
// Patch the address of the incrementPtr variable.
|
||||
p = (uintptr_t *)&tmpl[1];
|
||||
p = (uintptr_t *)&tmpl[5];
|
||||
*p = (uintptr_t) incrementPtr;
|
||||
|
||||
p = (uintptr_t *)&tmpl[9];
|
||||
p = (uintptr_t *)&tmpl[13];
|
||||
*p = (uintptr_t) incrementPtr;
|
||||
|
||||
memcpy(writeEntry, tmpl, sizeof(tmpl));
|
||||
|
|
Loading…
Reference in a new issue