If a signal handler is installed using the sigaction(2) SA_SIGINFO flag, then the signal-related context is accessible to the userspace via the ucontext_t object. This object contains: + the program counter register (i.e., the address of the next instruction in the main program that should be executed when the signal handler returns);
+ architecture-specific register state required for resuming the interrupted program;
+ the thread's current signal mask;
+ the thread's alternate signal stack settings.
Therefore, the signal handler can alter the PC and PSTATE. If Morello is supported, ensure that PC's LSB is cleared and PSTATE.C64 is set if the PC was set using C64 ISA.
Cc: Harry Ramsey harry.ramsey@arm.com Signed-off-by: Tudor Cretu tudor.cretu@arm.com ---
Many thanks to Harry (CC'ed) for finding an use case where sigreturn didn't behave as expected. Tested with Musl signal tests. Unfortunetaly, these is no LTP test that touches this functionality.
Review branch: https://git.morello-project.org/tudcre01/linux/-/commits/sigreturn_fix_v1
--- arch/arm64/kernel/signal.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c index 1dd040c72630..e2527df334a9 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -669,6 +669,9 @@ COMPAT_SYSCALL_DEFINE0(rt_sigreturn) if (restore_altstack(&frame->uc.uc_stack)) goto badframe;
+ if (system_supports_morello()) + morello_setup_signal_return(regs); + #if defined(CONFIG_CHERI_PURECAP_UABI) && !defined(SIGNAL_COMPAT64) return regs->cregs[0]; #else
On 14/10/2022 19:45, Tudor Cretu wrote:
If a signal handler is installed using the sigaction(2) SA_SIGINFO flag, then the signal-related context is accessible to the userspace via the ucontext_t object. This object contains:
the program counter register (i.e., the address of the next instruction in the main program that should be executed when the signal handler returns);
architecture-specific register state required for resuming the interrupted program;
the thread's current signal mask;
the thread's alternate signal stack settings.
Therefore, the signal handler can alter the PC and PSTATE. If Morello is supported, ensure that PC's LSB is cleared and PSTATE.C64 is set if the PC was set using C64 ISA.
The fact that setting the saved PCC to a C64 function pointer doesn't "just work" is documented in [1]. I am not entirely convinced we should change that, because it is expected when restoring that registers are in the same "format" as when they are saved, and PCC itself never has the LSB set. Handling the LSB of the saved PCC as if it were a function pointer starts looking like explicit support for signal handlers doing such things and I'm wary of that. In fact, a purecap function pointer is a sentry, so if we go down this route we shouldn't stop half-way and also unseal the capability if it's a sentry.
That said, if there is a clear use-case for this (where handling the function pointer manually is not reasonable), this could be reconsidered.
[1] https://git.morello-project.org/morello/kernel/linux/-/blob/morello/master/D...
Cc: Harry Ramsey harry.ramsey@arm.com Signed-off-by: Tudor Cretu tudor.cretu@arm.com
Many thanks to Harry (CC'ed) for finding an use case where sigreturn didn't behave as expected. Tested with Musl signal tests. Unfortunetaly, these is no LTP test that touches this functionality.
Review branch: https://git.morello-project.org/tudcre01/linux/-/commits/sigreturn_fix_v1
arch/arm64/kernel/signal.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c index 1dd040c72630..e2527df334a9 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -669,6 +669,9 @@ COMPAT_SYSCALL_DEFINE0(rt_sigreturn) if (restore_altstack(&frame->uc.uc_stack)) goto badframe;
- if (system_supports_morello())
morello_setup_signal_return(regs);
This does way more than you intend, for instance it unconditionally sets CLR, and in compat64 PCC as well.
Kevin
- #if defined(CONFIG_CHERI_PURECAP_UABI) && !defined(SIGNAL_COMPAT64) return regs->cregs[0]; #else
On 17-10-2022 10:10, Kevin Brodsky wrote:
On 14/10/2022 19:45, Tudor Cretu wrote:
If a signal handler is installed using the sigaction(2) SA_SIGINFO flag, then the signal-related context is accessible to the userspace via the ucontext_t object. This object contains: + the program counter register (i.e., the address of the next instruction in the main program that should be executed when the signal handler returns);
+ architecture-specific register state required for resuming the interrupted program;
+ the thread's current signal mask;
+ the thread's alternate signal stack settings.
Therefore, the signal handler can alter the PC and PSTATE. If Morello is supported, ensure that PC's LSB is cleared and PSTATE.C64 is set if the PC was set using C64 ISA.
The fact that setting the saved PCC to a C64 function pointer doesn't "just work" is documented in [1]. I am not entirely convinced we should change that, because it is expected when restoring that registers are in the same "format" as when they are saved, and PCC itself never has the LSB set. Handling the LSB of the saved PCC as if it were a function pointer starts looking like explicit support for signal handlers doing such things and I'm wary of that. In fact, a purecap function pointer is a sentry, so if we go down this route we shouldn't stop half-way and also unseal the capability if it's a sentry.
That said, if there is a clear use-case for this (where handling the function pointer manually is not reasonable), this could be reconsidered.
[1] https://git.morello-project.org/morello/kernel/linux/-/blob/morello/master/D...
Hi Kevin,
Thank you for the detailed reply. It makes sense!
Kind regards, Tudor
Cc: Harry Ramsey harry.ramsey@arm.com Signed-off-by: Tudor Cretu tudor.cretu@arm.com
Many thanks to Harry (CC'ed) for finding an use case where sigreturn didn't behave as expected. Tested with Musl signal tests. Unfortunetaly, these is no LTP test that touches this functionality.
Review branch: https://git.morello-project.org/tudcre01/linux/-/commits/sigreturn_fix_v1
arch/arm64/kernel/signal.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c index 1dd040c72630..e2527df334a9 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -669,6 +669,9 @@ COMPAT_SYSCALL_DEFINE0(rt_sigreturn) if (restore_altstack(&frame->uc.uc_stack)) goto badframe; + if (system_supports_morello()) + morello_setup_signal_return(regs);
This does way more than you intend, for instance it unconditionally sets CLR, and in compat64 PCC as well.
Kevin
#if defined(CONFIG_CHERI_PURECAP_UABI) && !defined(SIGNAL_COMPAT64) return regs->cregs[0]; #else
linux-morello mailing list -- linux-morello@op-lists.linaro.org To unsubscribe send an email to linux-morello-leave@op-lists.linaro.org
linux-morello@op-lists.linaro.org