Skip to content

Commit 33dc279

Browse files
committed
ucontext wip
1 parent 6850f7e commit 33dc279

File tree

4 files changed

+51
-11
lines changed

4 files changed

+51
-11
lines changed

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

Lines changed: 20 additions & 2 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 "tcb-offsets.h"
2021

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

@@ -60,8 +61,25 @@ LEAF (__getcontext)
6061
#endif /* __riscv_float_abi_soft */
6162

6263
#ifdef __riscv_shadow_stack
63-
ssrdp t0
64-
SAVE_INT_REG (t0, 28, a0) /* We use t3 slot to store ssp */
64+
ssrdp t0
65+
beqz t0, .Lskip_ss
66+
/* Read ssp_base from TLS */
67+
ld t1, SSP_BASE_OFFSET(tp)
68+
69+
bnez t1, .Lbase_saved
70+
/* if not found, use current ssp as the marker */
71+
mv t1, t0
72+
sd t1, SSP_BASE_OFFSET(tp)
73+
74+
.Lbase_saved:
75+
/* Save caller's ssp and base marker to ucontext */
76+
REG_S t1, UCONTEXT_SSP_BASE(a0)
77+
REG_S t0, UCONTEXT_SSP(a0)
78+
79+
/* clean up */
80+
xor t0, t0, t0
81+
xor t1, t1, t1
82+
.Lskip_ss:
6583
#endif
6684

6785
/* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */

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

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,11 @@ __makecontext (ucontext_t *ucp, void (*func) (void), int argc,
8484
STACK_SIZE_TO_SHADOW_STACK_SIZE_SHIFT;
8585
unsigned long ss_page = (ss_size + 4096 - 1) / 4096 + 2;
8686
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, PROT_READ | PROT_WRITE);
92-
ucp->uc_mcontext.__gregs[REG_PC + 28] = ss_base + ss_size
93-
- sizeof (unsigned long);
87+
void *ss_start = __mmap (NULL, ss_page * 4096, PROT_NONE,
88+
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
89+
ucp->uc_ssp_base = (unsigned long long) ss_start + 4096;
90+
ucp->uc_ssp = ucp->uc_ssp_base + ss_size - sizeof (unsigned long long);
91+
__mprotect ((void *) ucp->uc_ssp_base, ss_size, PROT_READ | PROT_WRITE);
9492
#endif
9593
}
9694

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

Lines changed: 25 additions & 2 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 "tcb-offsets.h"
2021

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

@@ -51,9 +52,31 @@ LEAF (__setcontext)
5152
ssrdp t2
5253
beqz t2, .Lfin
5354
/* We are safe to adjust shadow stack after the sanity check */
54-
RESTORE_INT_REG (t1, 28, t0)
55+
REG_L a0, UCONTEXT_SSP_BASE(t0)
56+
REG_L t0, SSP_BASE_OFFSET(tp)
57+
REG_L a1, UCONTEXT_SSP(t0)
58+
bne a0, t0, .Lstack_switch
59+
60+
.Lunwind:
61+
bleu a1, t2, .Lfin
62+
/* increase ssp by at most a page size to ensure always run into
63+
a guard page before accidentally point to another legal shadow
64+
stack page */
65+
/* t2 = (a1 - t2 >= 4096) ? t2 + 4096 : a1 */
66+
lui a3, 1
67+
add t2, t2, a3
68+
bleu t2, a1, 1f
69+
mv t2, a1
70+
1:
71+
csrw ssp, t2
72+
/* Test if the location pointed by ssp is legal */
73+
sspush x5
74+
sspopchk x5
75+
j .Lunwind
76+
77+
.Lstack_switch:
5578
/* FIXME: We are skipping ANY security check for now */
56-
csrw ssp, t1
79+
csrw ssp, a1
5780
.Lfin:
5881
#endif
5982

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

Lines changed: 1 addition & 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 "tcb-offsets.h"
2021

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

0 commit comments

Comments
 (0)