Skip to content

Commit 25abf21

Browse files
jaidTwcinll5312
andcommitted
riscv/cfi: Support ucontext under CFI
This patches only make the ucontext library work while CFI is enabled. enabled. All security checks are skipped and should be implemented if correspoding interface are landed into the kernel. SSP is stored in the unused t3 slot in the sigcontext structure to avoid breaking the current structure. Co-authored-by: Nia Su <[email protected]>
1 parent ecb9f24 commit 25abf21

File tree

5 files changed

+85
-1
lines changed

5 files changed

+85
-1
lines changed

sysdeps/unix/sysv/linux/riscv/getcontext.S

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@
1717
<https://www.gnu.org/licenses/>. */
1818

1919
#include "ucontext-macros.h"
20+
#include <sysdep.h>
2021

2122
/* int getcontext (ucontext_t *ucp) */
2223

2324
.text
2425
LEAF (__getcontext)
26+
LPAD
2527
SAVE_INT_REG (ra, 0, a0)
2628
SAVE_INT_REG (ra, 1, a0)
2729
SAVE_INT_REG (sp, 2, a0)
@@ -58,6 +60,11 @@ LEAF (__getcontext)
5860
sw a1, MCONTEXT_FSR(a0)
5961
#endif /* __riscv_float_abi_soft */
6062

63+
#ifdef __riscv_zicfiss
64+
ssrdp t0
65+
SAVE_INT_REG (t0, 28, a0) /* We use t3 slot to store ssp */
66+
#endif
67+
6168
/* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */
6269
li a3, _NSIG8
6370
add a2, a0, UCONTEXT_SIGMASK

sysdeps/unix/sysv/linux/riscv/makecontext.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <sys/ucontext.h>
2222
#include <stdarg.h>
2323
#include <assert.h>
24+
#include <sys/mman.h>
2425

2526
void
2627
__makecontext (ucontext_t *ucp, void (*func) (void), int argc,
@@ -73,6 +74,25 @@ __makecontext (ucontext_t *ucp, void (*func) (void), int argc,
7374

7475
va_end (vl);
7576
}
77+
#ifdef __riscv_zicfiss
78+
/* Allocate shadow stack for the new context
79+
SSP is stored in t3 slot, SS base is stored in t4 slot */
80+
/* FIXME: we use user space as a temporary solution until
81+
kernel provides such interface */
82+
83+
unsigned long ss_size = ucp->uc_stack.ss_size >>
84+
STACK_SIZE_TO_SHADOW_STACK_SIZE_SHIFT;
85+
unsigned long ss_page = (ss_size + 4096 - 1) / 4096 + 2;
86+
ss_size = (ss_page - 2) * 4096;
87+
void *ssp = __mmap (NULL, ss_page * 4096, PROT_NONE,
88+
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
89+
unsigned long ss_base = (unsigned long) ssp + 4096;
90+
ucp->uc_mcontext.__gregs[REG_PC + 29] = ss_base;
91+
__mprotect ((void *) ss_base, ss_size,
92+
PROT_READ | PROT_WRITE);
93+
ucp->uc_mcontext.__gregs[REG_PC + 28] = ss_base + ss_size
94+
- sizeof (unsigned long);
95+
#endif
7696
}
7797

7898
weak_alias (__makecontext, makecontext)

sysdeps/unix/sysv/linux/riscv/setcontext.S

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
<https://www.gnu.org/licenses/>. */
1818

1919
#include "ucontext-macros.h"
20+
#include <sysdep.h>
2021

2122
/* int __setcontext (const ucontext_t *ucp)
2223

@@ -29,6 +30,7 @@
2930

3031
.text
3132
LEAF (__setcontext)
33+
LPAD
3234

3335
mv t0, a0 /* Save ucp into t0. */
3436

@@ -45,6 +47,17 @@ LEAF (__setcontext)
4547

4648
cfi_def_cfa (t0, 0)
4749

50+
#ifdef __riscv_zicfiss
51+
/* Skip if shadow stack is not enabled */
52+
ssrdp t2
53+
beqz t2, .Lfin
54+
/* We are safe to adjust shadow stack after the sanity check */
55+
RESTORE_INT_REG (t1, 28, t0)
56+
/* FIXME: We are skipping ANY security check for now */
57+
csrw ssp, t1
58+
.Lfin:
59+
#endif
60+
4861
#ifndef __riscv_float_abi_soft
4962
lw t1, MCONTEXT_FSR(t0)
5063

@@ -66,7 +79,11 @@ LEAF (__setcontext)
6679

6780
/* Note the contents of argument registers will be random
6881
unless makecontext() has been called. */
82+
#ifdef __riscv_zicfilp
83+
RESTORE_INT_REG (t2, 0, t0)
84+
#else
6985
RESTORE_INT_REG (t1, 0, t0)
86+
#endif
7087
RESTORE_INT_REG_CFI (ra, 1, t0)
7188
RESTORE_INT_REG (sp, 2, t0)
7289
RESTORE_INT_REG_CFI (s0, 8, t0)
@@ -90,7 +107,12 @@ LEAF (__setcontext)
90107
RESTORE_INT_REG_CFI (s10, 26, t0)
91108
RESTORE_INT_REG_CFI (s11, 27, t0)
92109

110+
#ifdef __riscv_zicfilp
111+
/* We need to use software-guared jump */
112+
jr t2
113+
#else
93114
jr t1
115+
#endif
94116

95117
99: tail __syscall_error
96118

@@ -99,12 +121,19 @@ libc_hidden_def (__setcontext)
99121
weak_alias (__setcontext, setcontext)
100122

101123
LEAF (__start_context)
124+
LPAD
102125

103126
/* Terminate call stack by noting ra == 0. Happily, s0 == 0 here. */
104127
cfi_register (ra, s0)
105128

106129
/* Call the function passed to makecontext. */
130+
#ifdef __riscv_zicfilp
131+
/* We need to use software-guared jump */
132+
mv t2, s1
133+
jalr t2
134+
#else
107135
jalr s1
136+
#endif
108137

109138
/* Invoke subsequent context if present, else exit(0). */
110139
mv a0, s2

sysdeps/unix/sysv/linux/riscv/swapcontext.S

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@
1717
<https://www.gnu.org/licenses/>. */
1818

1919
#include "ucontext-macros.h"
20+
#include <sysdep.h>
2021

2122
/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */
2223

2324
LEAF (__swapcontext)
25+
LPAD
2426
mv t0, a1 /* Save ucp into t0. */
2527

2628
SAVE_INT_REG (ra, 0, a0)
@@ -59,6 +61,11 @@ LEAF (__swapcontext)
5961
sw a1, MCONTEXT_FSR(a0)
6062
#endif /* __riscv_float_abi_soft */
6163

64+
#ifdef __riscv_zicfiss
65+
ssrdp t1
66+
SAVE_INT_REG (t1, 28, a0)
67+
#endif
68+
6269
/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, &oucp->uc_sigmask, _NSIG8) */
6370
li a3, _NSIG8
6471
add a2, a0, UCONTEXT_SIGMASK
@@ -70,6 +77,17 @@ LEAF (__swapcontext)
7077

7178
bltz a0, 99f
7279

80+
#ifdef __riscv_zicfiss
81+
/* Skip if shadow stack is not enabled */
82+
ssrdp t2
83+
beqz t2, .Lfin
84+
/* We are safe to adjust shadow stack after the sanity check */
85+
RESTORE_INT_REG (t1, 28, t0)
86+
/* FIXME: We are skipping ANY security check for now */
87+
csrw ssp, t1
88+
.Lfin:
89+
#endif
90+
7391
#ifndef __riscv_float_abi_soft
7492
lw t1, MCONTEXT_FSR(t0)
7593

@@ -91,7 +109,11 @@ LEAF (__swapcontext)
91109

92110
/* Note the contents of argument registers will be random
93111
unless makecontext() has been called. */
112+
#ifdef __riscv_zicfilp
113+
RESTORE_INT_REG (t2, 0, t0)
114+
#else
94115
RESTORE_INT_REG (t1, 0, t0)
116+
#endif
95117
RESTORE_INT_REG (ra, 1, t0)
96118
RESTORE_INT_REG (sp, 2, t0)
97119
RESTORE_INT_REG (s0, 8, t0)
@@ -115,8 +137,12 @@ LEAF (__swapcontext)
115137
RESTORE_INT_REG (s10, 26, t0)
116138
RESTORE_INT_REG (s11, 27, t0)
117139

140+
#ifdef __riscv_zicfilp
141+
/* We need to use software-guared jump */
142+
jr t2
143+
#else
118144
jr t1
119-
145+
#endif
120146

121147
99: tail __syscall_error
122148

sysdeps/unix/sysv/linux/riscv/sysdep.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,8 @@ GNU_PROPERTY (FEATURE_1_AND, __VALUE_FOR_FEATURE_1_AND)
201201

202202
#else /* !__ASSEMBLER__ */
203203

204+
# define STACK_SIZE_TO_SHADOW_STACK_SIZE_SHIFT 5
205+
204206
# if __WORDSIZE == 64
205207
# define VDSO_NAME "LINUX_4.15"
206208
# define VDSO_HASH 182943605

0 commit comments

Comments
 (0)