#4955 closed defect (fixed)

sparc: Potential stack corruption in uniprocessor configurations during start multitasking

Reported by: Sebastian Huber Owned by: Sebastian Huber
Priority: normal Milestone: 6.1
Component: arch/sparc Version: 6
Severity: critical Keywords: qualification
Cc: Blocked By:
Blocking:

Description

The system initialization uses the interrupt stack. A first level interrupt shall never interrupt a context which uses the interrupt stack. Such a use would lead to stack corruption and undefined system behaviour. Unfortunately, in uniprocessor configurations this is the case right now. Multiprocessing is started using _CPU_Context_restore(). The caller of this function (_Thread_Start_multitasking()) uses the interrupt stack. Later we have in cpukit/score/cpu/sparc/cpu_asm.S:

        mov     %g1, %psr                     ! restore status register and
                                              ! **** ENABLE TRAPS ****

        ld      [%o1 + G5_OFFSET], %g5        ! restore the global registers
        ld      [%o1 + G7_OFFSET], %g7

        ! Load thread specific ISR dispatch prevention flag
        ld      [%o1 + ISR_DISPATCH_DISABLE_STACK_OFFSET], %o2
        ! Store it to memory later to use the cycles

        ldd     [%o1 + L0_OFFSET], %l0        ! restore the local registers
        ldd     [%o1 + L2_OFFSET], %l2
        ldd     [%o1 + L4_OFFSET], %l4
        ldd     [%o1 + L6_OFFSET], %l6

        ! Now restore thread specific ISR dispatch prevention flag
        st      %o2, [%g6 + PER_CPU_ISR_DISPATCH_DISABLE]

        ldd     [%o1 + I0_OFFSET], %i0        ! restore the input registers
        ldd     [%o1 + I2_OFFSET], %i2
        ldd     [%o1 + I4_OFFSET], %i4
        ldd     [%o1 + I6_FP_OFFSET], %i6

        ldd     [%o1 + O6_SP_OFFSET], %o6     ! restore the output registers

Between the ENABLE TRAPS and the restore of the output registers, we still use the stack of the caller and interrupts may be enabled. If an interrupt happens in this code block, the interrupt stack is concurrently used which may lead to a crash.

Change History (3)

comment:1 Changed on 09/26/23 at 05:50:21 by Sebastian Huber <sebastian.huber@…>

In a9862623/rtems:

validation: Check stack of interrupted context

Check the stack of the interrupted context during the multitasking
start.

Update #4955.

comment:2 Changed on 10/12/23 at 11:53:39 by Sebastian Huber <sebastian.huber@…>

Resolution: fixed
Status: assignedclosed

In 1c36971d/rtems:

sparc: Fix stack corruption

Fix a potential stack corruption in uniprocessor configurations during
start multitasking.

The system initialization uses the interrupt stack. A first level
interrupt shall never interrupt a context which uses the interrupt
stack. Such a use would lead to stack corruption and undefined system
behaviour. Unfortunately, in uniprocessor configurations this was the
case. Multiprocessing is started using _CPU_Context_restore(). The
caller of this function (_Thread_Start_multitasking()) uses the
interrupt stack. Later we have in cpukit/score/cpu/sparc/cpu_asm.S:

mov %g1, %psr ! restore status register and

! ENABLE TRAPS

ld [%o1 + G5_OFFSET], %g5 ! restore the global registers
ld [%o1 + G7_OFFSET], %g7

! Load thread specific ISR dispatch prevention flag
ld [%o1 + ISR_DISPATCH_DISABLE_STACK_OFFSET], %o2
! Store it to memory later to use the cycles

ldd [%o1 + L0_OFFSET], %l0 ! restore the local registers
ldd [%o1 + L2_OFFSET], %l2
ldd [%o1 + L4_OFFSET], %l4
ldd [%o1 + L6_OFFSET], %l6

! Now restore thread specific ISR dispatch prevention flag
st %o2, [%g6 + PER_CPU_ISR_DISPATCH_DISABLE]

ldd [%o1 + I0_OFFSET], %i0 ! restore the input registers
ldd [%o1 + I2_OFFSET], %i2
ldd [%o1 + I4_OFFSET], %i4
ldd [%o1 + I6_FP_OFFSET], %i6

ldd [%o1 + O6_SP_OFFSET], %o6 ! restore the output registers

Between the ENABLE TRAPS and the restore of the output registers, we
still use the stack of the caller and interrupts may be enabled. If an
interrupt happens in this code block, the interrupt stack is
concurrently used which may lead to a crash.

Fix this by adding a new function _SPARC_Start_multiprocessing() for
uniprocessor configurations. This function first sets the stack pointer
to use the stack of the heir thread.

Close #4955.

comment:3 Changed on 10/12/23 at 14:07:59 by Sebastian Huber <sebastian.huber@…>

In 43b74b14/rtems:

validation: Support powerpc in test case

Update #4955.

Note: See TracTickets for help on using tickets.