Skip to content

Commit

Permalink
xtensa: use XCHAL_NUM_AREGS as pt_regs::areg size
Browse files Browse the repository at this point in the history
struct pt_regs is used to access both kernel and user exception frames.
User exception frames may contain up to XCHAL_NUM_AREG registers that
task creation and signal delivery code may access, but pt_regs::areg
array has only 16 entries that cover only the kernel exception frame.
This results in the following build error:

arch/xtensa/kernel/process.c: In function 'copy_thread':
arch/xtensa/kernel/process.c:262:52: error: array subscript 53 is above
           array bounds of 'long unsigned int[16]' [-Werror=array-bounds]
  262 |                                 put_user(regs->areg[caller_ars+1],

Change struct pt_regs::areg size to XCHAL_NUM_AREGS so that it covers
the whole user exception frame. Adjust task_pt_regs and drop additional
register copying code from copy_thread now that the whole user exception
stack frame is copied.

Reported-by: Kees Cook <[email protected]>
Signed-off-by: Max Filippov <[email protected]>
Reviewed-by: Kees Cook <[email protected]>
  • Loading branch information
jcmvbkbc committed Mar 7, 2022
1 parent 6fad9dd commit 5b835d4
Show file tree
Hide file tree
Showing 2 changed files with 3 additions and 14 deletions.
7 changes: 3 additions & 4 deletions arch/xtensa/include/asm/ptrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#ifndef __ASSEMBLY__

#include <asm/coprocessor.h>
#include <asm/core.h>

/*
* This struct defines the way the registers are stored on the
Expand Down Expand Up @@ -77,14 +78,12 @@ struct pt_regs {
/* current register frame.
* Note: The ESF for kernel exceptions ends after 16 registers!
*/
unsigned long areg[16];
unsigned long areg[XCHAL_NUM_AREGS];
};

#include <asm/core.h>

# define arch_has_single_step() (1)
# define task_pt_regs(tsk) ((struct pt_regs*) \
(task_stack_page(tsk) + KERNEL_STACK_SIZE - (XCHAL_NUM_AREGS-16)*4) - 1)
(task_stack_page(tsk) + KERNEL_STACK_SIZE) - 1)
# define user_mode(regs) (((regs)->ps & 0x00000020)!=0)
# define instruction_pointer(regs) ((regs)->pc)
# define return_pointer(regs) (MAKE_PC_FROM_RA((regs)->areg[0], \
Expand Down
10 changes: 0 additions & 10 deletions arch/xtensa/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,10 +232,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp_thread_fn,
p->thread.ra = MAKE_RA_FOR_CALL(
(unsigned long)ret_from_fork, 0x1);

/* This does not copy all the regs.
* In a bout of brilliance or madness,
* ARs beyond a0-a15 exist past the end of the struct.
*/
*childregs = *regs;
childregs->areg[1] = usp;
childregs->areg[2] = 0;
Expand Down Expand Up @@ -265,14 +261,8 @@ int copy_thread(unsigned long clone_flags, unsigned long usp_thread_fn,
childregs->wmask = 1;
childregs->windowstart = 1;
childregs->windowbase = 0;
} else {
int len = childregs->wmask & ~0xf;
memcpy(&childregs->areg[XCHAL_NUM_AREGS - len/4],
&regs->areg[XCHAL_NUM_AREGS - len/4], len);
}

childregs->syscall = regs->syscall;

if (clone_flags & CLONE_SETTLS)
childregs->threadptr = tls;
} else {
Expand Down

0 comments on commit 5b835d4

Please sign in to comment.