Skip to content

Commit 507e413

Browse files
authored
[libunwind][NFC] Remove the CET keyword in shadow stack-related stuffs (#126663)
libunwind currently supports shadow stack based on the Intel CET and AArch64 GCS technology, but throughout related codes, the Intel-specific keyword, "CET", is used to refer to the generic concept of control-flow integrity/shadow stack. This patch replaces such wordings with architecture-neutral term "shadow stack" (abbr. "shstk") to allow future implementation to avoid using the Intel-specific "CET" term.
1 parent 2d6330f commit 507e413

File tree

5 files changed

+46
-43
lines changed

5 files changed

+46
-43
lines changed

libunwind/src/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ set(LIBUNWIND_HEADERS
3636
AddressSpace.hpp
3737
assembly.h
3838
CompactUnwinder.hpp
39-
cet_unwind.h
4039
config.h
4140
dwarf2.h
4241
DwarfInstructions.hpp
@@ -46,6 +45,7 @@ set(LIBUNWIND_HEADERS
4645
libunwind_ext.h
4746
Registers.hpp
4847
RWMutex.hpp
48+
shadow_stack_unwind.h
4949
Unwind-EHABI.h
5050
UnwindCursor.hpp
5151
../include/libunwind.h

libunwind/src/Registers.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
#include <stdint.h>
1616
#include <string.h>
1717

18-
#include "cet_unwind.h"
1918
#include "config.h"
2019
#include "libunwind.h"
20+
#include "shadow_stack_unwind.h"
2121

2222
namespace libunwind {
2323

@@ -48,7 +48,7 @@ class _LIBUNWIND_HIDDEN Registers_x86;
4848
extern "C" void __libunwind_Registers_x86_jumpto(Registers_x86 *);
4949

5050
#if defined(_LIBUNWIND_USE_CET)
51-
extern "C" void *__libunwind_cet_get_jump_target() {
51+
extern "C" void *__libunwind_shstk_get_jump_target() {
5252
return reinterpret_cast<void *>(&__libunwind_Registers_x86_jumpto);
5353
}
5454
#endif
@@ -268,7 +268,7 @@ class _LIBUNWIND_HIDDEN Registers_x86_64;
268268
extern "C" void __libunwind_Registers_x86_64_jumpto(Registers_x86_64 *);
269269

270270
#if defined(_LIBUNWIND_USE_CET)
271-
extern "C" void *__libunwind_cet_get_jump_target() {
271+
extern "C" void *__libunwind_shstk_get_jump_target() {
272272
return reinterpret_cast<void *>(&__libunwind_Registers_x86_64_jumpto);
273273
}
274274
#endif
@@ -1817,7 +1817,7 @@ class _LIBUNWIND_HIDDEN Registers_arm64;
18171817
extern "C" void __libunwind_Registers_arm64_jumpto(Registers_arm64 *);
18181818

18191819
#if defined(_LIBUNWIND_USE_GCS)
1820-
extern "C" void *__libunwind_cet_get_jump_target() {
1820+
extern "C" void *__libunwind_shstk_get_jump_target() {
18211821
return reinterpret_cast<void *>(&__libunwind_Registers_arm64_jumpto);
18221822
}
18231823
#endif

libunwind/src/UnwindCursor.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#ifndef __UNWINDCURSOR_HPP__
1212
#define __UNWINDCURSOR_HPP__
1313

14-
#include "cet_unwind.h"
14+
#include "shadow_stack_unwind.h"
1515
#include <stdint.h>
1616
#include <stdio.h>
1717
#include <stdlib.h>
@@ -3122,7 +3122,7 @@ bool UnwindCursor<A, R>::isReadableAddr(const pint_t addr) const {
31223122
#endif
31233123

31243124
#if defined(_LIBUNWIND_USE_CET) || defined(_LIBUNWIND_USE_GCS)
3125-
extern "C" void *__libunwind_cet_get_registers(unw_cursor_t *cursor) {
3125+
extern "C" void *__libunwind_shstk_get_registers(unw_cursor_t *cursor) {
31263126
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
31273127
return co->get_registers();
31283128
}

libunwind/src/UnwindLevel1.c

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -25,64 +25,67 @@
2525
#include <stdio.h>
2626
#include <string.h>
2727

28-
#include "cet_unwind.h"
2928
#include "config.h"
3029
#include "libunwind.h"
3130
#include "libunwind_ext.h"
31+
#include "shadow_stack_unwind.h"
3232
#include "unwind.h"
3333

3434
#if !defined(_LIBUNWIND_ARM_EHABI) && !defined(__USING_SJLJ_EXCEPTIONS__) && \
3535
!defined(__wasm__)
3636

3737
#ifndef _LIBUNWIND_SUPPORT_SEH_UNWIND
3838

39-
// When CET is enabled, each "call" instruction will push return address to
40-
// CET shadow stack, each "ret" instruction will pop current CET shadow stack
41-
// top and compare it with target address which program will return.
42-
// In exception handing, some stack frames will be skipped before jumping to
43-
// landing pad and we must adjust CET shadow stack accordingly.
44-
// _LIBUNWIND_POP_CET_SSP is used to adjust CET shadow stack pointer and we
45-
// directly jump to __libunwind_Registers_x86/x86_64_jumpto instead of using
46-
// a regular function call to avoid pushing to CET shadow stack again.
39+
// When shadow stack is enabled, a separate stack containing only return
40+
// addresses would be maintained. On function return, the return address would
41+
// be compared to the popped address from shadow stack to ensure the return
42+
// target is not tempered with. When unwinding, we're skipping the normal return
43+
// procedure for multiple frames and thus need to pop the return addresses of
44+
// the skipped frames from shadow stack to avoid triggering an exception (using
45+
// `_LIBUNWIND_POP_SHSTK_SSP()`). Also, some architectures, like the x86-family
46+
// CET, push the return adddresses onto shadow stack with common call
47+
// instructions, so for these architectures, normal function calls should be
48+
// avoided when invoking the `jumpto()` function. To do this, we use inline
49+
// assemblies to "goto" the `jumpto()` for these architectures.
4750
#if !defined(_LIBUNWIND_USE_CET) && !defined(_LIBUNWIND_USE_GCS)
4851
#define __unw_phase2_resume(cursor, fn) \
4952
do { \
5053
(void)fn; \
5154
__unw_resume((cursor)); \
5255
} while (0)
5356
#elif defined(_LIBUNWIND_TARGET_I386)
54-
#define __cet_ss_step_size 4
57+
#define __shstk_step_size (4)
5558
#define __unw_phase2_resume(cursor, fn) \
5659
do { \
57-
_LIBUNWIND_POP_CET_SSP((fn)); \
58-
void *cetRegContext = __libunwind_cet_get_registers((cursor)); \
59-
void *cetJumpAddress = __libunwind_cet_get_jump_target(); \
60+
_LIBUNWIND_POP_SHSTK_SSP((fn)); \
61+
void *shstkRegContext = __libunwind_shstk_get_registers((cursor)); \
62+
void *shstkJumpAddress = __libunwind_shstk_get_jump_target(); \
6063
__asm__ volatile("push %%edi\n\t" \
6164
"sub $4, %%esp\n\t" \
62-
"jmp *%%edx\n\t" :: "D"(cetRegContext), \
63-
"d"(cetJumpAddress)); \
65+
"jmp *%%edx\n\t" ::"D"(shstkRegContext), \
66+
"d"(shstkJumpAddress)); \
6467
} while (0)
6568
#elif defined(_LIBUNWIND_TARGET_X86_64)
66-
#define __cet_ss_step_size 8
69+
#define __shstk_step_size (8)
6770
#define __unw_phase2_resume(cursor, fn) \
6871
do { \
69-
_LIBUNWIND_POP_CET_SSP((fn)); \
70-
void *cetRegContext = __libunwind_cet_get_registers((cursor)); \
71-
void *cetJumpAddress = __libunwind_cet_get_jump_target(); \
72-
__asm__ volatile("jmpq *%%rdx\n\t" :: "D"(cetRegContext), \
73-
"d"(cetJumpAddress)); \
72+
_LIBUNWIND_POP_SHSTK_SSP((fn)); \
73+
void *shstkRegContext = __libunwind_shstk_get_registers((cursor)); \
74+
void *shstkJumpAddress = __libunwind_shstk_get_jump_target(); \
75+
__asm__ volatile("jmpq *%%rdx\n\t" ::"D"(shstkRegContext), \
76+
"d"(shstkJumpAddress)); \
7477
} while (0)
7578
#elif defined(_LIBUNWIND_TARGET_AARCH64)
76-
#define __cet_ss_step_size 8
79+
#define __shstk_step_size (8)
7780
#define __unw_phase2_resume(cursor, fn) \
7881
do { \
79-
_LIBUNWIND_POP_CET_SSP((fn)); \
80-
void *cetRegContext = __libunwind_cet_get_registers((cursor)); \
81-
void *cetJumpAddress = __libunwind_cet_get_jump_target(); \
82+
_LIBUNWIND_POP_SHSTK_SSP((fn)); \
83+
void *shstkRegContext = __libunwind_shstk_get_registers((cursor)); \
84+
void *shstkJumpAddress = __libunwind_shstk_get_jump_target(); \
8285
__asm__ volatile("mov x0, %0\n\t" \
8386
"br %1\n\t" \
8487
: \
85-
: "r"(cetRegContext), "r"(cetJumpAddress) \
88+
: "r"(shstkRegContext), "r"(shstkJumpAddress) \
8689
: "x0"); \
8790
} while (0)
8891
#endif
@@ -255,16 +258,16 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
255258
}
256259
#endif
257260

258-
// In CET enabled environment, we check return address stored in normal stack
259-
// against return address stored in CET shadow stack, if the 2 addresses don't
261+
// In shadow stack enabled environment, we check return address stored in normal
262+
// stack against return address stored in shadow stack, if the 2 addresses don't
260263
// match, it means return address in normal stack has been corrupted, we return
261264
// _URC_FATAL_PHASE2_ERROR.
262265
#if defined(_LIBUNWIND_USE_CET) || defined(_LIBUNWIND_USE_GCS)
263266
if (shadowStackTop != 0) {
264267
unw_word_t retInNormalStack;
265268
__unw_get_reg(cursor, UNW_REG_IP, &retInNormalStack);
266-
unsigned long retInShadowStack = *(
267-
unsigned long *)(shadowStackTop + __cet_ss_step_size * framesWalked);
269+
unsigned long retInShadowStack =
270+
*(unsigned long *)(shadowStackTop + __shstk_step_size * framesWalked);
268271
if (retInNormalStack != retInShadowStack)
269272
return _URC_FATAL_PHASE2_ERROR;
270273
}

libunwind/src/cet_unwind.h renamed to libunwind/src/shadow_stack_unwind.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
//
88
//===----------------------------------------------------------------------===//
99

10-
#ifndef LIBUNWIND_CET_UNWIND_H
11-
#define LIBUNWIND_CET_UNWIND_H
10+
#ifndef LIBUNWIND_SHADOW_STACK_UNWIND_H
11+
#define LIBUNWIND_SHADOW_STACK_UNWIND_H
1212

1313
#include "libunwind.h"
1414

@@ -21,7 +21,7 @@
2121
#include <cet.h>
2222
#include <immintrin.h>
2323

24-
#define _LIBUNWIND_POP_CET_SSP(x) \
24+
#define _LIBUNWIND_POP_SHSTK_SSP(x) \
2525
do { \
2626
unsigned long ssp = _get_ssp(); \
2727
if (ssp != 0) { \
@@ -46,7 +46,7 @@
4646
#define _LIBUNWIND_USE_GCS 1
4747
#endif
4848

49-
#define _LIBUNWIND_POP_CET_SSP(x) \
49+
#define _LIBUNWIND_POP_SHSTK_SSP(x) \
5050
do { \
5151
if (__chkfeat(_CHKFEAT_GCS)) { \
5252
unsigned tmp = (x); \
@@ -57,7 +57,7 @@
5757

5858
#endif
5959

60-
extern void *__libunwind_cet_get_registers(unw_cursor_t *);
61-
extern void *__libunwind_cet_get_jump_target(void);
60+
extern void *__libunwind_shstk_get_registers(unw_cursor_t *);
61+
extern void *__libunwind_shstk_get_jump_target(void);
6262

6363
#endif

0 commit comments

Comments
 (0)