arch/: Fix an interlock that was broken by commit 641a98a434 in all implementations of up_sigdeliver.

This commit is contained in:
Gregory Nutt 2019-02-03 17:14:32 -06:00
parent 641a98a434
commit a77c073797
20 changed files with 125 additions and 268 deletions

8
TODO
View File

@ -1065,7 +1065,7 @@ o Kernel/Protected Build
Linux, applications do not have separate user and supervisor
stacks; everything is done on the user stack.
In the implementation of up_sigdeliver, a copy of the
In the implementation of up_sigdeliver(), a copy of the
register contents that will be restored is present on the
stack and could be modified by the user application. Thus,
if the user mucks with the return stack, problems could
@ -1077,6 +1077,12 @@ o Kernel/Protected Build
return address and switch to supervisor mode. Other register
are still modifiable and there is other possible mayhem that
could be done.
A better solution, in lieu of a kernel stack, would be to
eliminate the stack-based register save area and, instead,
save the registers in another, dedicated state save area in
the TCB. The only hesitation to this option is that it would
significantly increase the size of the TCB structure.
Status: Open
Priority: Medium-ish if are attempting to make a secure environment that
may host malicious code. Very low for the typical FLAT build,

View File

@ -73,7 +73,6 @@ void up_sigdeliver(void)
{
struct tcb_s *rtcb = this_task();
uint32_t regs[XCPTCONTEXT_REGS];
sig_deliver_t sigdeliver;
/* Save the errno. This must be preserved throughout the signal handling
* so that the user code final gets the correct errno value (probably
@ -92,14 +91,6 @@ void up_sigdeliver(void)
up_copyfullstate(regs, rtcb->xcp.regs);
/* Get a local copy of the sigdeliver function pointer. we do this so that
* we can nullify the sigdeliver function pointer in the TCB and accept
* more signal deliveries while processing the current pending signals.
*/
sigdeliver = rtcb->xcp.sigdeliver;
rtcb->xcp.sigdeliver = NULL;
#ifndef CONFIG_SUPPRESS_INTERRUPTS
/* Then make sure that interrupts are enabled. Signal handlers must always
* run with interrupts enabled.
@ -108,9 +99,9 @@ void up_sigdeliver(void)
up_irq_enable();
#endif
/* Deliver the signals */
/* Deliver the signal */
sigdeliver(rtcb);
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
/* Output any debug messages BEFORE restoring errno (because they may
* alter errno), then disable interrupts again and restore the original
@ -119,7 +110,7 @@ void up_sigdeliver(void)
sinfo("Resuming\n");
(void)up_irq_save();
rtcb->pterrno = saved_errno;
rtcb->pterrno = saved_errno;
/* Modify the saved return state with the actual saved values in the
* TCB. This depends on the fact that nested signal handling is
@ -131,8 +122,9 @@ void up_sigdeliver(void)
* could be modified by a hostile program.
*/
regs[REG_PC] = rtcb->xcp.saved_pc;
regs[REG_CPSR] = rtcb->xcp.saved_cpsr;
regs[REG_PC] = rtcb->xcp.saved_pc;
regs[REG_CPSR] = rtcb->xcp.saved_cpsr;
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
/* Then restore the correct state for this thread of execution. */

View File

@ -77,7 +77,6 @@ void up_sigdeliver(void)
struct tcb_s *rtcb = this_task();
uint32_t regs[XCPTCONTEXT_REGS + 4];
sig_deliver_t sigdeliver;
/* Save the errno. This must be preserved throughout the signal handling
* so that the user code final gets the correct errno value (probably
@ -96,14 +95,6 @@ void up_sigdeliver(void)
up_copyfullstate(regs, rtcb->xcp.regs);
/* Get a local copy of the sigdeliver function pointer. We do this so that
* we can nullify the sigdeliver function pointer in the TCB and accept
* more signal deliveries while processing the current pending signals.
*/
sigdeliver = rtcb->xcp.sigdeliver;
rtcb->xcp.sigdeliver = NULL;
#ifndef CONFIG_SUPPRESS_INTERRUPTS
/* Then make sure that interrupts are enabled. Signal handlers must always
* run with interrupts enabled.
@ -114,7 +105,7 @@ void up_sigdeliver(void)
/* Deliver the signal */
sigdeliver(rtcb);
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
/* Output any debug messages BEFORE restoring errno (because they may
* alter errno), then disable interrupts again and restore the original
@ -135,12 +126,13 @@ void up_sigdeliver(void)
* could be modified by a hostile program.
*/
regs[REG_PC] = rtcb->xcp.saved_pc;
regs[REG_PRIMASK] = rtcb->xcp.saved_primask;
regs[REG_XPSR] = rtcb->xcp.saved_xpsr;
regs[REG_PC] = rtcb->xcp.saved_pc;
regs[REG_PRIMASK] = rtcb->xcp.saved_primask;
regs[REG_XPSR] = rtcb->xcp.saved_xpsr;
#ifdef CONFIG_BUILD_PROTECTED
regs[REG_LR] = rtcb->xcp.saved_lr;
regs[REG_LR] = rtcb->xcp.saved_lr;
#endif
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
/* Then restore the correct state for this thread of
* execution.

View File

@ -73,7 +73,6 @@ void up_sigdeliver(void)
{
struct tcb_s *rtcb = this_task();
uint32_t regs[XCPTCONTEXT_REGS];
sig_deliver_t sigdeliver;
/* Save the errno. This must be preserved throughout the signal handling
* so that the user code final gets the correct errno value (probably
@ -101,14 +100,6 @@ void up_sigdeliver(void)
up_copyfullstate(regs, rtcb->xcp.regs);
/* Get a local copy of the sigdeliver function pointer. we do this so that
* we can nullify the sigdeliver function pointer in the TCB and accept
* more signal deliveries while processing the current pending signals.
*/
sigdeliver = rtcb->xcp.sigdeliver;
rtcb->xcp.sigdeliver = NULL;
#ifdef CONFIG_SMP
/* In the SMP case, up_schedule_sigaction(0) will have incremented
* 'irqcount' in order to force us into a critical section. Save the
@ -139,7 +130,7 @@ void up_sigdeliver(void)
/* Deliver the signal */
sigdeliver(rtcb);
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
/* Output any debug messages BEFORE restoring errno (because they may
* alter errno), then disable interrupts again and restore the original
@ -160,7 +151,7 @@ void up_sigdeliver(void)
/* Restore the saved errno value */
rtcb->pterrno = saved_errno;
rtcb->pterrno = saved_errno;
/* Modify the saved return state with the actual saved values in the
* TCB. This depends on the fact that nested signal handling is
@ -172,8 +163,9 @@ void up_sigdeliver(void)
* could be modified by a hostile program.
*/
regs[REG_PC] = rtcb->xcp.saved_pc;
regs[REG_CPSR] = rtcb->xcp.saved_cpsr;
regs[REG_PC] = rtcb->xcp.saved_pc;
regs[REG_CPSR] = rtcb->xcp.saved_cpsr;
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
#ifdef CONFIG_SMP
/* Restore the saved 'irqcount' and recover the critical section

View File

@ -73,7 +73,6 @@ void up_sigdeliver(void)
{
struct tcb_s *rtcb = this_task();
uint32_t regs[XCPTCONTEXT_REGS];
sig_deliver_t sigdeliver;
/* Save the errno. This must be preserved throughout the signal handling
* so that the user code final gets the correct errno value (probably
@ -101,14 +100,6 @@ void up_sigdeliver(void)
up_copyfullstate(regs, rtcb->xcp.regs);
/* Get a local copy of the sigdeliver function pointer. We do this so that
* we can nullify the sigdeliver function pointer in the TCB and accept
* more signal deliveries while processing the current pending signals.
*/
sigdeliver = (sig_deliver_t)rtcb->xcp.sigdeliver;
rtcb->xcp.sigdeliver = NULL;
#ifdef CONFIG_SMP
/* In the SMP case, up_schedule_sigaction(0) will have incremented
* 'irqcount' in order to force us into a critical section. Save the
@ -143,7 +134,7 @@ void up_sigdeliver(void)
/* Deliver the signal */
sigdeliver(rtcb);
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
/* Output any debug messages BEFORE restoring errno (because they may
* alter errno), then disable interrupts again and restore the original
@ -164,7 +155,7 @@ void up_sigdeliver(void)
/* Restore the saved errno value */
rtcb->pterrno = saved_errno;
rtcb->pterrno = saved_errno;
/* Modify the saved return state with the actual saved values in the
* TCB. This depends on the fact that nested signal handling is
@ -176,16 +167,17 @@ void up_sigdeliver(void)
* could be modified by a hostile program.
*/
regs[REG_PC] = rtcb->xcp.saved_pc;
regs[REG_PC] = rtcb->xcp.saved_pc;
#ifdef CONFIG_ARMV7M_USEBASEPRI
regs[REG_BASEPRI] = rtcb->xcp.saved_basepri;
regs[REG_BASEPRI] = rtcb->xcp.saved_basepri;
#else
regs[REG_PRIMASK] = rtcb->xcp.saved_primask;
regs[REG_PRIMASK] = rtcb->xcp.saved_primask;
#endif
regs[REG_XPSR] = rtcb->xcp.saved_xpsr;
regs[REG_XPSR] = rtcb->xcp.saved_xpsr;
#ifdef CONFIG_BUILD_PROTECTED
regs[REG_LR] = rtcb->xcp.saved_lr;
regs[REG_LR] = rtcb->xcp.saved_lr;
#endif
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
#ifdef CONFIG_SMP
/* Restore the saved 'irqcount' and recover the critical section

View File

@ -72,7 +72,6 @@ void up_sigdeliver(void)
{
struct tcb_s *rtcb = this_task();
uint32_t regs[XCPTCONTEXT_REGS];
sig_deliver_t sigdeliver;
/* Save the errno. This must be preserved throughout the signal handling
* so that the user code final gets the correct errno value (probably
@ -91,14 +90,6 @@ void up_sigdeliver(void)
up_copyfullstate(regs, rtcb->xcp.regs);
/* Get a local copy of the sigdeliver function pointer. we do this so that
* we can nullify the sigdeliver function pointer in the TCB and accept
* more signal deliveries while processing the current pending signals.
*/
sigdeliver = rtcb->xcp.sigdeliver;
rtcb->xcp.sigdeliver = NULL;
#ifndef CONFIG_SUPPRESS_INTERRUPTS
/* Then make sure that interrupts are enabled. Signal handlers must always
* run with interrupts enabled.
@ -107,9 +98,9 @@ void up_sigdeliver(void)
up_irq_enable();
#endif
/* Deliver the signals */
/* Deliver the signal */
sigdeliver(rtcb);
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
/* Output any debug messages BEFORE restoring errno (because they may
* alter errno), then disable interrupts again and restore the original
@ -132,6 +123,7 @@ void up_sigdeliver(void)
regs[REG_PC] = rtcb->xcp.saved_pc;
regs[REG_CPSR] = rtcb->xcp.saved_cpsr;
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
/* Then restore the correct state for this thread of execution. */

View File

@ -72,7 +72,6 @@ void up_sigdeliver(void)
{
struct tcb_s *rtcb = this_task();
uint8_t regs[XCPTCONTEXT_REGS];
sig_deliver_t sigdeliver;
/* Save the errno. This must be preserved throughout the signal handling
* so that the user code final gets the correct errno value (probably EINTR).
@ -90,14 +89,6 @@ void up_sigdeliver(void)
up_copystate(regs, rtcb->xcp.regs);
/* Get a local copy of the sigdeliver function pointer. We do this so that
* we can nullify the sigdeliver function pointer in the TCB and accept
* more signal deliveries while processing the current pending signals.
*/
sigdeliver = rtcb->xcp.sigdeliver;
rtcb->xcp.sigdeliver = NULL;
#ifndef CONFIG_SUPPRESS_INTERRUPTS
/* Then make sure that interrupts are enabled. Signal handlers must always
* run with interrupts enabled.
@ -106,9 +97,9 @@ void up_sigdeliver(void)
up_irq_enable();
#endif
/* Deliver the signals */
/* Deliver the signal */
sigdeliver(rtcb);
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
/* Output any debug messages BEFORE restoring errno (because they may
* alter errno), then disable interrupts again and restore the original
@ -117,7 +108,7 @@ void up_sigdeliver(void)
sinfo("Resuming\n");
(void)up_irq_save();
rtcb->pterrno = saved_errno;
rtcb->pterrno = saved_errno;
/* Modify the saved return state with the actual saved values in the
* TCB. This depends on the fact that nested signal handling is
@ -129,12 +120,13 @@ void up_sigdeliver(void)
* could be modified by a hostile program.
*/
regs[REG_PC0] = rtcb->xcp.saved_pc0;
regs[REG_PC1] = rtcb->xcp.saved_pc1;
regs[REG_PC0] = rtcb->xcp.saved_pc0;
regs[REG_PC1] = rtcb->xcp.saved_pc1;
#if defined(REG_PC2)
regs[REG_PC2] = rtcb->xcp.saved_pc2;
regs[REG_PC2] = rtcb->xcp.saved_pc2;
#endif
regs[REG_SREG] = rtcb->xcp.saved_sreg;
regs[REG_SREG] = rtcb->xcp.saved_sreg;
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
/* Then restore the correct state for this thread of execution. This is an
* unusual case that must be handled by up_fullcontextresore. This case is

View File

@ -76,7 +76,6 @@ void up_sigdeliver(void)
#else
uint32_t regs[XCPTCONTEXT_REGS];
#endif
sig_deliver_t sigdeliver;
/* Save the errno. This must be preserved throughout the signal handling
* so that the user code final gets the correct errno value (probably EINTR).
@ -94,14 +93,6 @@ void up_sigdeliver(void)
up_copystate(regs, rtcb->xcp.regs);
/* Get a local copy of the sigdeliver function pointer. We do this so that
* we can nullify the sigdeliver function pointer in the TCB and accept
* more signal deliveries while processing the current pending signals.
*/
sigdeliver = rtcb->xcp.sigdeliver;
rtcb->xcp.sigdeliver = NULL;
#ifndef CONFIG_SUPPRESS_INTERRUPTS
/* Then make sure that interrupts are enabled. Signal handlers must always
* run with interrupts enabled.
@ -110,9 +101,9 @@ void up_sigdeliver(void)
up_irq_enable();
#endif
/* Deliver the signals */
/* Deliver the signal */
sigdeliver(rtcb);
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
/* Output any debug messages BEFORE restoring errno (because they may
* alter errno), then disable interrupts again and restore the original
@ -121,7 +112,7 @@ void up_sigdeliver(void)
sinfo("Resuming\n");
(void)up_irq_save();
rtcb->pterrno = saved_errno;
rtcb->pterrno = saved_errno;
/* Modify the saved return state with the actual saved values in the
* TCB. This depends on the fact that nested signal handling is
@ -133,8 +124,9 @@ void up_sigdeliver(void)
* could be modified by a hostile program.
*/
regs[REG_PC] = rtcb->xcp.saved_pc;
regs[REG_SR] = rtcb->xcp.saved_sr;
regs[REG_PC] = rtcb->xcp.saved_pc;
regs[REG_SR] = rtcb->xcp.saved_sr;
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
/* Then restore the correct state for this thread of execution. This is an
* unusual case that must be handled by up_fullcontextresore. This case is

View File

@ -73,7 +73,6 @@ void up_sigdeliver(void)
{
struct tcb_s *rtcb = this_task();
uint32_t regs[XCPTCONTEXT_REGS];
sig_deliver_t sigdeliver;
/* Save the errno. This must be preserved throughout the signal handling
* so that the user code final gets the correct errno value (probably
@ -92,14 +91,6 @@ void up_sigdeliver(void)
up_copystate(regs, rtcb->xcp.regs);
/* Get a local copy of the sigdeliver function pointer. We do this so that
* we can nullify the sigdeliver function pointer in the TCB and accept
* more signal deliveries while processing the current pending signals.
*/
sigdeliver = rtcb->xcp.sigdeliver;
rtcb->xcp.sigdeliver = NULL;
#ifndef CONFIG_SUPPRESS_INTERRUPTS
/* Then make sure that interrupts are enabled. Signal handlers must always
* run with interrupts enabled.
@ -108,9 +99,9 @@ void up_sigdeliver(void)
up_irq_enable();
#endif
/* Deliver the signals */
/* Deliver the signal */
sigdeliver(rtcb);
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
/* Output any debug messages BEFORE restoring errno (because they may
* alter errno), then disable interrupts again and restore the original
@ -120,7 +111,7 @@ void up_sigdeliver(void)
sinfo("Resuming EPC: %08x STATUS: %08x\n", regs[REG_EPC], regs[REG_STATUS]);
(void)up_irq_save();
rtcb->pterrno = saved_errno;
rtcb->pterrno = saved_errno;
/* Modify the saved return state with the actual saved values in the
* TCB. This depends on the fact that nested signal handling is
@ -132,8 +123,9 @@ void up_sigdeliver(void)
* could be modified by a hostile program.
*/
regs[REG_EPC] = rtcb->xcp.saved_epc;
regs[REG_STATUS] = rtcb->xcp.saved_status;
regs[REG_EPC] = rtcb->xcp.saved_epc;
regs[REG_STATUS] = rtcb->xcp.saved_status;
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
/* Then restore the correct state for this thread of
* execution.

View File

@ -72,7 +72,6 @@ void lm32_sigdeliver(void)
{
struct tcb_s *rtcb = this_task();
uint32_t regs[XCPTCONTEXT_REGS];
sig_deliver_t sigdeliver;
/* Save the errno. This must be preserved throughout the signal handling
* so that the user code final gets the correct errno value (probably
@ -91,14 +90,6 @@ void lm32_sigdeliver(void)
up_copystate(regs, rtcb->xcp.regs);
/* Get a local copy of the sigdeliver function pointer. We do this so that
* we can nullify the sigdeliver function pointer in the TCB and accept
* more signal deliveries while processing the current pending signals.
*/
sigdeliver = rtcb->xcp.sigdeliver;
rtcb->xcp.sigdeliver = NULL;
#ifndef CONFIG_SUPPRESS_INTERRUPTS
/* Then make sure that interrupts are enabled. Signal handlers must always
* run with interrupts enabled.
@ -107,9 +98,9 @@ void lm32_sigdeliver(void)
up_irq_enable();
#endif
/* Deliver the signals */
/* Deliver the signal */
sigdeliver(rtcb);
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
/* Output any debug messages BEFORE restoring errno (because they may
* alter errno), then disable interrupts again and restore the original
@ -119,7 +110,7 @@ void lm32_sigdeliver(void)
sinfo("Resuming EPC: %08x INT_CTX: %08x\n", regs[REG_EPC], regs[REG_INT_CTX]);
(void)up_irq_save();
rtcb->pterrno = saved_errno;
rtcb->pterrno = saved_errno;
/* Modify the saved return state with the actual saved values in the
* TCB. This depends on the fact that nested signal handling is
@ -131,8 +122,9 @@ void lm32_sigdeliver(void)
* could be modified by a hostile program.
*/
regs[REG_EPC] = rtcb->xcp.saved_epc;
regs[REG_INT_CTX] = rtcb->xcp.saved_int_ctx;
regs[REG_EPC] = rtcb->xcp.saved_epc;
regs[REG_INT_CTX] = rtcb->xcp.saved_int_ctx;
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
/* Then restore the correct state for this thread of
* execution.

View File

@ -73,7 +73,6 @@ void up_sigdeliver(void)
#ifndef CONFIG_DISABLE_SIGNALS
struct tcb_s *rtcb = this_task();
uint8_t regs[XCPTCONTEXT_SIZE];
sig_deliver_t sigdeliver;
/* Save the errno. This must be preserved throughout the signal handling
* so that the user code final gets the correct errno value (probably
@ -92,15 +91,6 @@ void up_sigdeliver(void)
up_copystate(regs, rtcb->xcp.regs);
/* Get a local copy of the sigdeliver function pointer. We do this so
* that we can nullify the sigdeliver function pointer in the TCB and
* accept more signal deliveries while processing the current pending
* signals.
*/
sigdeliver = rtcb->xcp.sigdeliver;
rtcb->xcp.sigdeliver = NULL;
#ifndef CONFIG_SUPPRESS_INTERRUPTS
/* Then make sure that interrupts are enabled. Signal handlers must always
* run with interrupts enabled.
@ -109,9 +99,9 @@ void up_sigdeliver(void)
up_irq_enable();
#endif
/* Deliver the signals */
/* Deliver the signal */
sigdeliver(rtcb);
((sig_deliver_t)sig_rtcb->xcp.sigdeliver)(rtcb);
/* Output any debug messages BEFORE restoring errno (because they may
* alter errno), then disable interrupts again and restore the original
@ -120,7 +110,7 @@ void up_sigdeliver(void)
sinfo("Resuming\n");
(void)up_irq_save();
rtcb->pterrno = saved_errno;
rtcb->pterrno = saved_errno;
/* Modify the saved return state with the actual saved values in the
* TCB. This depends on the fact that nested signal handling is
@ -132,9 +122,10 @@ void up_sigdeliver(void)
* could be modified by a hostile program.
*/
regs[REG_PC] = rtcb->xcp.saved_pc[0];
regs[REG_PC+1] = rtcb->xcp.saved_pc[1];
regs[REG_FLG] = rtcb->xcp.saved_flg;
regs[REG_PC] = rtcb->xcp.saved_pc[0];
regs[REG_PC + 1] = rtcb->xcp.saved_pc[1];
regs[REG_FLG] = rtcb->xcp.saved_flg;
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
/* Then restore the correct state for this thread of
* execution.

View File

@ -73,7 +73,6 @@ void up_sigdeliver(void)
#ifndef CONFIG_DISABLE_SIGNALS
struct tcb_s *rtcb = this_task();
uint32_t regs[XCPTCONTEXT_REGS];
sig_deliver_t sigdeliver;
/* Save the errno. This must be preserved throughout the signal handling
* so that the user code final gets the correct errno value (probably
@ -92,15 +91,6 @@ void up_sigdeliver(void)
up_copystate(regs, rtcb->xcp.regs);
/* Get a local copy of the sigdeliver function pointer. We do this so
* that we can nullify the sigdeliver function pointer in the TCB and
* accept more signal deliveries while processing the current pending
* signals.
*/
sigdeliver = rtcb->xcp.sigdeliver;
rtcb->xcp.sigdeliver = NULL;
#ifndef CONFIG_SUPPRESS_INTERRUPTS
/* Then make sure that interrupts are enabled. Signal handlers must always
* run with interrupts enabled.
@ -109,9 +99,9 @@ void up_sigdeliver(void)
up_irq_enable();
#endif
/* Deliver the signals */
/* Deliver the signal */
sigdeliver(rtcb);
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
/* Output any debug messages BEFORE restoring errno (because they may
* alter errno), then disable interrupts again and restore the original
@ -120,7 +110,7 @@ void up_sigdeliver(void)
sinfo("Resuming\n");
(void)up_irq_save();
rtcb->pterrno = saved_errno;
rtcb->pterrno = saved_errno;
/* Modify the saved return state with the actual saved values in the
* TCB. This depends on the fact that nested signal handling is
@ -132,8 +122,9 @@ void up_sigdeliver(void)
* could be modified by a hostile program.
*/
regs[REG_PC] = rtcb->xcp.saved_pc;
regs[REG_SR] = rtcb->xcp.saved_sr;
regs[REG_PC] = rtcb->xcp.saved_pc;
regs[REG_SR] = rtcb->xcp.saved_sr;
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
/* Then restore the correct state for this thread of execution. */

View File

@ -78,7 +78,6 @@ void up_sigdeliver(void)
{
struct tcb_s *rtcb = this_task();
uint32_t regs[XCPTCONTEXT_REGS];
sig_deliver_t sigdeliver;
/* Save the errno. This must be preserved throughout the signal handling
* so that the user code final gets the correct errno value (probably
@ -97,14 +96,6 @@ void up_sigdeliver(void)
up_copystate(regs, rtcb->xcp.regs);
/* Get a local copy of the sigdeliver function pointer. We do this so that
* we can nullify the sigdeliver function pointer in the TCB and accept
* more signal deliveries while processing the current pending signals.
*/
sigdeliver = rtcb->xcp.sigdeliver;
rtcb->xcp.sigdeliver = NULL;
#ifndef CONFIG_SUPPRESS_INTERRUPTS
/* Then make sure that interrupts are enabled. Signal handlers must always
* run with interrupts enabled.
@ -115,7 +106,7 @@ void up_sigdeliver(void)
/* Deliver the signals */
sigdeliver(rtcb);
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
/* Output any debug messages BEFORE restoring errno (because they may
* alter errno), then disable interrupts again and restore the original
@ -125,7 +116,7 @@ void up_sigdeliver(void)
sinfo("Resuming EPC: %08x INT_CTX: %08x\n", regs[REG_EPC], regs[REG_INT_CTX]);
(void)up_irq_save();
rtcb->pterrno = saved_errno;
rtcb->pterrno = saved_errno;
/* Modify the saved return state with the actual saved values in the
* TCB. This depends on the fact that nested signal handling is
@ -137,8 +128,9 @@ void up_sigdeliver(void)
* could be modified by a hostile program.
*/
regs[REG_EPC] = rtcb->xcp.saved_epc;
regs[REG_INT_CTX] = rtcb->xcp.saved_int_ctx;
regs[REG_EPC] = rtcb->xcp.saved_epc;
regs[REG_INT_CTX] = rtcb->xcp.saved_int_ctx;
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
/* Then restore the correct state for this thread of
* execution.

View File

@ -72,7 +72,6 @@ void up_sigdeliver(void)
{
struct tcb_s *rtcb = this_task();
uint32_t regs[XCPTCONTEXT_REGS];
sig_deliver_t sigdeliver;
/* Save the errno. This must be preserved throughout the signal handling
* so that the user code final gets the correct errno value (probably
@ -91,14 +90,6 @@ void up_sigdeliver(void)
up_copystate(regs, rtcb->xcp.regs);
/* Get a local copy of the sigdeliver function pointer. we do this so that
* we can nullify the sigdeliver function pointer in the TCB and accept
* more signal deliveries while processing the current pending signals.
*/
sigdeliver = rtcb->xcp.sigdeliver;
rtcb->xcp.sigdeliver = NULL;
#ifndef CONFIG_SUPPRESS_INTERRUPTS
/* Then make sure that interrupts are enabled. Signal handlers must always
* run with interrupts enabled.
@ -109,7 +100,7 @@ void up_sigdeliver(void)
/* Deliver the signals */
sigdeliver(rtcb);
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
/* Output any debug messages BEFORE restoring errno (because they may
* alter errno), then disable interrupts again and restore the original
@ -118,7 +109,7 @@ void up_sigdeliver(void)
sinfo("Resuming\n");
(void)up_irq_save();
rtcb->pterrno = saved_errno;
rtcb->pterrno = saved_errno;
/* Modify the saved return state with the actual saved values in the
* TCB. This depends on the fact that nested signal handling is
@ -130,8 +121,9 @@ void up_sigdeliver(void)
* could be modified by a hostile program.
*/
regs[REG_EIP] = rtcb->xcp.saved_eip;
regs[REG_EFLAGS] = rtcb->xcp.saved_eflags;
regs[REG_EIP] = rtcb->xcp.saved_eip;
regs[REG_EFLAGS] = rtcb->xcp.saved_eflags;
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
/* Then restore the correct state for this thread of execution. */

View File

@ -69,9 +69,8 @@
void xtensa_sig_deliver(void)
{
struct tcb_s *rtcb = this_task();
struct tcb_s *rtcb = this_task();
uint32_t regs[XCPTCONTEXT_REGS];
sig_deliver_t sigdeliver;
/* Save the errno. This must be preserved throughout the signal handling
* so that the user code final gets the correct errno value (probably
@ -99,14 +98,6 @@ void xtensa_sig_deliver(void)
xtensa_copystate(regs, rtcb->xcp.regs);
/* Get a local copy of the sigdeliver function pointer. we do this so that
* we can nullify the sigdeliver function pointer in the TCB and accept
* more signal deliveries while processing the current pending signals.
*/
sigdeliver = rtcb->xcp.sigdeliver;
rtcb->xcp.sigdeliver = NULL;
#ifdef CONFIG_SMP
/* In the SMP case, up_schedule_sigaction(0) will have incremented
* 'irqcount' in order to force us into a critical section. Save the
@ -137,7 +128,7 @@ void xtensa_sig_deliver(void)
/* Deliver the signals */
sigdeliver(rtcb);
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
/* Output any debug messages BEFORE restoring errno (because they may
* alter errno), then disable interrupts again and restore the original
@ -149,7 +140,7 @@ void xtensa_sig_deliver(void)
/* Restore the saved errno value */
rtcb->pterrno = saved_errno;
rtcb->pterrno = saved_errno;
/* Modify the saved return state with the actual saved values in the
* TCB. This depends on the fact that nested signal handling is
@ -161,8 +152,9 @@ void xtensa_sig_deliver(void)
* could be modified by a hostile program.
*/
regs[REG_PC] = rtcb->xcp.saved_pc;
regs[REG_PS] = rtcb->xcp.saved_ps;
regs[REG_PC] = rtcb->xcp.saved_pc;
regs[REG_PS] = rtcb->xcp.saved_ps;
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
#ifdef CONFIG_SMP
/* Restore the saved 'irqcount' and recover the critical section

View File

@ -74,7 +74,6 @@ void up_sigdeliver(void)
FAR struct tcb_s *rtcb = this_task();
chipreg_t regs[XCPTCONTEXT_REGS];
FAR uint32_t *regs32 = (FAR uint32_t*)regs;
sig_deliver_t sigdeliver;
/* Save the errno. This must be preserved throughout the signal handling
* so that the user code final gets the correct errno value (probably
@ -93,15 +92,6 @@ void up_sigdeliver(void)
up_copystate(regs, rtcb->xcp.regs);
/* Get a local copy of the sigdeliver function pointer. We do this so
* that we can nullify the sigdeliver function point in the TCB and
* accept more signal deliveries while processing the current pending
* signals.
*/
sigdeliver = (sig_deliver_t)rtcb->xcp.sigdeliver;
rtcb->xcp.sigdeliver = NULL;
#ifndef CONFIG_SUPPRESS_INTERRUPTS
/* Then make sure that interrupts are enabled. Signal handlers must always
* run with interrupts enabled.
@ -112,7 +102,7 @@ void up_sigdeliver(void)
/* Deliver the signals */
sigdeliver(rtcb);
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
/* Output any debug messages BEFORE restoring errno (because they may
* alter errno), then disable interrupts again and restore the original
@ -121,7 +111,7 @@ void up_sigdeliver(void)
sinfo("Resuming\n");
(void)up_irq_save();
rtcb->pterrno = saved_errno;
rtcb->pterrno = saved_errno;
/* Modify the saved return state with the actual saved values in the
* TCB. This depends on the fact that nested signal handling is
@ -133,8 +123,9 @@ void up_sigdeliver(void)
* could be modified by a hostile program.
*/
regs32[REG_PC / 2] = rtcb->xcp.saved_pc;
regs[REG_FLAGS] = rtcb->xcp.saved_i;
regs32[REG_PC / 2] = rtcb->xcp.saved_pc;
regs[REG_FLAGS] = rtcb->xcp.saved_i;
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
/* Then restore the correct state for this thread of execution. */

View File

@ -73,7 +73,6 @@ void up_sigdeliver(void)
#ifndef CONFIG_DISABLE_SIGNALS
FAR struct tcb_s *rtcb = this_task();
chipreg_t regs[XCPTCONTEXT_REGS];
sig_deliver_t sigdeliver;
/* Save the errno. This must be preserved throughout the signal handling
* so that the user code final gets the correct errno value (probably
@ -92,15 +91,6 @@ void up_sigdeliver(void)
ez80_copystate(regs, rtcb->xcp.regs);
/* Get a local copy of the sigdeliver function pointer. We do this so
* that we can nullify the sigdeliver function pointer in the TCB and
* accept more signal deliveries while processing the current pending
* signals.
*/
sigdeliver = rtcb->xcp.sigdeliver;
rtcb->xcp.sigdeliver = NULL;
#ifndef CONFIG_SUPPRESS_INTERRUPTS
/* Then make sure that interrupts are enabled. Signal handlers must always
* run with interrupts enabled.
@ -111,7 +101,7 @@ void up_sigdeliver(void)
/* Deliver the signals */
sigdeliver(rtcb);
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
/* Output any debug messages BEFORE restoring errno (because they may
* alter errno), then disable interrupts again and restore the original
@ -120,10 +110,21 @@ void up_sigdeliver(void)
sinfo("Resuming\n");
(void)up_irq_save();
rtcb->pterrno = saved_errno;
rtcb->pterrno = saved_errno;
regs[XCPT_PC] = rtcb->xcp.saved_pc;
regs[XCPT_I] = rtcb->xcp.saved_i;
/* Modify the saved return state with the actual saved values in the
* TCB. This depends on the fact that nested signal handling is
* not supported. Therefore, these values will persist throughout the
* signal handling action.
*
* Keeping this data in the TCB resolves a security problem in protected
* and kernel mode: The regs[] array is visible on the user stack and
* could be modified by a hostile program.
*/
regs[XCPT_PC] = rtcb->xcp.saved_pc;
regs[XCPT_I] = rtcb->xcp.saved_i;
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
/* Modify the saved return state with the actual saved values in the
* TCB. This depends on the fact that nested signal handling is

View File

@ -71,7 +71,6 @@ void up_sigdeliver(void)
#ifndef CONFIG_DISABLE_SIGNALS
FAR struct tcb_s *rtcb = this_task();
chipreg_t regs[XCPTCONTEXT_REGS];
sig_deliver_t sigdeliver;
/* Save the errno. This must be preserved throughout the signal handling
* so that the user code final gets the correct errno value (probably
@ -90,15 +89,6 @@ void up_sigdeliver(void)
z180_copystate(regs, rtcb->xcp.regs);
/* Get a local copy of the sigdeliver function pointer. We do this so
* that we can nullify the sigdeliver function pointer in the TCB and
* accept more signal deliveries while processing the current pending
* signals.
*/
sigdeliver = rtcb->xcp.sigdeliver;
rtcb->xcp.sigdeliver = NULL;
#ifndef CONFIG_SUPPRESS_INTERRUPTS
/* Then make sure that interrupts are enabled. Signal handlers must always
* run with interrupts enabled.
@ -109,7 +99,7 @@ void up_sigdeliver(void)
/* Deliver the signals */
sigdeliver(rtcb);
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
/* Output any debug messages BEFORE restoring errno (because they may
* alter errno), then disable interrupts again and restore the original
@ -118,7 +108,7 @@ void up_sigdeliver(void)
sinfo("Resuming\n");
(void)up_irq_save();
rtcb->pterrno = saved_errno;
rtcb->pterrno = saved_errno;
/* Modify the saved return state with the actual saved values in the
* TCB. This depends on the fact that nested signal handling is
@ -130,8 +120,9 @@ void up_sigdeliver(void)
* could be modified by a hostile program.
*/
regs[XCPT_PC] = rtcb->xcp.saved_pc;
regs[XCPT_I] = rtcb->xcp.saved_i;
regs[XCPT_PC] = rtcb->xcp.saved_pc;
regs[XCPT_I] = rtcb->xcp.saved_i;
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
/* Then restore the correct state for this thread of execution. */

View File

@ -91,7 +91,6 @@ void up_sigdeliver(void)
#ifndef CONFIG_DISABLE_SIGNALS
FAR struct tcb_s *rtcb = this_task();
chipreg_t regs[XCPTCONTEXT_REGS];
sig_deliver_t sigdeliver;
/* Save the errno. This must be preserved throughout the signal handling
* so that the user code final gets the correct errno value (probably
@ -110,15 +109,6 @@ void up_sigdeliver(void)
z8_copystate(regs, rtcb->xcp.regs);
/* Get a local copy of the sigdeliver function pointer. We do this so
* that we can nullify the sigdeliver function pointer in the TCB and
* accept more signal deliveries while processing the current pending
* signals.
*/
sigdeliver = rtcb->xcp.sigdeliver;
rtcb->xcp.sigdeliver = NULL;
#ifndef CONFIG_SUPPRESS_INTERRUPTS
/* Then make sure that interrupts are enabled. Signal handlers must always
* run with interrupts enabled.
@ -129,7 +119,7 @@ void up_sigdeliver(void)
/* Deliver the signals */
sigdeliver(rtcb);
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
/* Output any debug messages BEFORE restoring errno (because they may
* alter errno), then disable interrupts again and restore the original
@ -138,7 +128,7 @@ void up_sigdeliver(void)
sinfo("Resuming\n");
(void)up_irq_save();
rtcb->pterrno = saved_errno;
rtcb->pterrno = saved_errno;
/* Modify the saved return state with the actual saved values in the
* TCB. This depends on the fact that nested signal handling is
@ -150,8 +140,9 @@ void up_sigdeliver(void)
* could be modified by a hostile program.
*/
regs[XCPT_PC] = rtcb->xcp.saved_pc;
regs[XCPT_IRQCTL] = rtcb->xcp.saved_irqctl;
regs[XCPT_PC] = rtcb->xcp.saved_pc;
regs[XCPT_IRQCTL] = rtcb->xcp.saved_irqctl;
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
/* Then restore the correct state for this thread of execution. */

View File

@ -72,7 +72,6 @@ void up_sigdeliver(void)
#ifndef CONFIG_DISABLE_SIGNALS
FAR struct tcb_s *rtcb = this_task();
chipreg_t regs[XCPTCONTEXT_REGS];
sig_deliver_t sigdeliver;
/* Save the errno. This must be preserved throughout the signal handling
* so that the user code final gets the correct errno value (probably
@ -91,15 +90,6 @@ void up_sigdeliver(void)
z80_copystate(regs, rtcb->xcp.regs);
/* Get a local copy of the sigdeliver function pointer. We do this so
* that we can nullify the sigdeliver function pointer in the TCB and
* accept more signal deliveries while processing the current pending
* signals.
*/
sigdeliver = rtcb->xcp.sigdeliver;
rtcb->xcp.sigdeliver = NULL;
#ifndef CONFIG_SUPPRESS_INTERRUPTS
/* Then make sure that interrupts are enabled. Signal handlers must always
* run with interrupts enabled.
@ -110,7 +100,7 @@ void up_sigdeliver(void)
/* Deliver the signals */
sigdeliver(rtcb);
((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
/* Output any debug messages BEFORE restoring errno (because they may
* alter errno), then disable interrupts again and restore the original
@ -119,7 +109,7 @@ void up_sigdeliver(void)
sinfo("Resuming\n");
(void)up_irq_save();
rtcb->pterrno = saved_errno;
rtcb->pterrno = saved_errno;
/* Modify the saved return state with the actual saved values in the
* TCB. This depends on the fact that nested signal handling is
@ -131,8 +121,9 @@ void up_sigdeliver(void)
* could be modified by a hostile program.
*/
regs[XCPT_PC] = rtcb->xcp.saved_pc;
regs[XCPT_I] = rtcb->xcp.saved_i;
regs[XCPT_PC] = rtcb->xcp.saved_pc;
regs[XCPT_I] = rtcb->xcp.saved_i;
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
/* Then restore the correct state for this thread of execution. */