[PATCH v2 10/14] riscv/cfi: Adjust setjmp/longjmp for shadow stack to work
Jesse Huang
jesse.huang@sifive.com
Wed Jul 23 07:23:34 GMT 2025
Yeah, it make sense, I will fix it.
2025年7月23日(水) 5:50 Deepak Gupta <debug@rivosinc.com>:
> On Fri, Jul 11, 2025 at 06:52:51AM -0700, Jesse Huang wrote:
> >Since longjmp to a previous setjmp'ed state could change the stack
> >frame and involves stack frame unwinding, shadow stacks is also required
> >to be unwinded.
> >
> >The unwinding is implemented according to the zicfiss spec by increasing
> >the ssp by a page size (4K) at most, to prevent from accidentally point
> >to another legal shadow stack page after the adjustment.
> >---
> > sysdeps/riscv/__longjmp.S | 28 ++++++++++++++++++++++++++++
> > sysdeps/riscv/bits/setjmp.h | 4 ++++
> > sysdeps/riscv/setjmp.S | 10 ++++++++++
> > 3 files changed, 42 insertions(+)
> >
> >diff --git a/sysdeps/riscv/__longjmp.S b/sysdeps/riscv/__longjmp.S
> >index 47ff3aa09e..1aa8a235d7 100644
> >--- a/sysdeps/riscv/__longjmp.S
> >+++ b/sysdeps/riscv/__longjmp.S
> >@@ -51,6 +51,34 @@ ENTRY (__longjmp)
> > FREG_L fs11,14*SZREG+11*SZFREG(a0)
> > #endif
> >
> >+#ifdef __riscv_shadow_stack
> >+ /* skip unwinding if ss is not enabled */
> >+ ssrdp t0
> >+ beqz t0, .Lunwind_fin
> >+# ifndef __riscv_float_abi_soft
> >+ REG_L t1, 14*SZREG+12*SZFREG(a0)
> >+# else
> >+ REG_L t1, 14*SZREG(a0)
> >+# endif
> >+.Lunwind:
> >+ bleu t1, t0, .Lunwind_fin
> >+ /* Increase ssp by at most a page size to ensure always run into a
> >+ guard page before accidentally point to another legal shadow
> stack
> >+ page */
> >+ /* t0 = (t1 - t0 >= 4096) ? t0 + 4096 : t1 */
> >+ lui a0, 1
> >+ add t0, t0, a0
> >+ bleu t0, t1, 1f
> >+ mv t0, t1
> >+1:
> >+ csrw ssp, t0
> >+ /* Test if the location pointed by ssp is legal */
> >+ sspush x5
> >+ sspopchk x5
> >+ j .Lunwind
> >+.Lunwind_fin:
> >+#endif
> >+
> > seqz a0, a1
> > add a0, a0, a1 # a0 = (a1 == 0) ? 1 : a1
> > ret
> >diff --git a/sysdeps/riscv/bits/setjmp.h b/sysdeps/riscv/bits/setjmp.h
> >index 5ebbec393a..5cbc12fa3d 100644
> >--- a/sysdeps/riscv/bits/setjmp.h
> >+++ b/sysdeps/riscv/bits/setjmp.h
> >@@ -33,6 +33,10 @@ typedef struct __jmp_buf_internal_tag
> > double __fpregs[12];
> > #elif !defined __riscv_float_abi_soft
> > # error unsupported FLEN
> >+#endif
> >+#ifdef __riscv_shadow_stack
> >+ /* Shadow stack pointer. */
> >+ long int __ssp;
> > #endif
>
> Why conditionally change size of this structure?
> I think we should keep size of jmp_buf static in nature as far as ssp
> is concerned.
>
>
> > } __jmp_buf[1];
> >
> >diff --git a/sysdeps/riscv/setjmp.S b/sysdeps/riscv/setjmp.S
> >index df048cb544..f547bc0238 100644
> >--- a/sysdeps/riscv/setjmp.S
> >+++ b/sysdeps/riscv/setjmp.S
> >@@ -61,6 +61,16 @@ ENTRY (__sigsetjmp)
> > FREG_S fs11,14*SZREG+11*SZFREG(a0)
> > #endif
> >
> >+#ifdef __riscv_shadow_stack
> >+ /* read ssp into t0 */
> >+ ssrdp t0
> >+# ifndef __riscv_float_abi_soft
> >+ REG_S t0, 14*SZREG+12*SZFREG(a0)
> >+# else
> >+ REG_S t0, 14*SZREG(a0)
> >+# endif
> >+#endif
> >+
> > #if !IS_IN (libc) && IS_IN (rtld)
> > /* In ld.so we never save the signal mask. */
> > li a0, 0
> >--
> >2.39.3
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://sourceware.org/pipermail/libc-alpha/attachments/20250723/b3e36b29/attachment.htm>
More information about the Libc-alpha
mailing list