All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kees Cook <keescook@chromium.org>
To: Max Filippov <jcmvbkbc@gmail.com>
Cc: Chris Zankel <chris@zankel.net>,
	"open list:TENSILICA XTENSA PORT (xtensa)" 
	<linux-xtensa@linux-xtensa.org>,
	linux-hardening@vger.kernel.org
Subject: Re: How large is the xtensa pt_regs::areg array supposed to be?
Date: Thu, 3 Feb 2022 13:56:29 -0800	[thread overview]
Message-ID: <202202031328.21E25051@keescook> (raw)
In-Reply-To: <CAMo8BfK46Va0qAtMHQzg+i053LUe_hGuqwg-WyL4_P0t2JnuRw@mail.gmail.com>

On Thu, Feb 03, 2022 at 01:13:26PM -0800, Max Filippov wrote:
> Hi Kees,
> 
> On Wed, Feb 2, 2022 at 3:03 PM Kees Cook <keescook@chromium.org> wrote:
> > When building with -Warray-bounds, I see this:
> >
> > In file included from ./include/linux/uaccess.h:11,
> >                  from ./include/linux/sched/task.h:11,
> >                  from arch/xtensa/kernel/process.c:21:
> > arch/xtensa/kernel/process.c: In function 'copy_thread':
> > arch/xtensa/kernel/process.c:262:52: warning: array subscript 53 is above array bounds of 'long unsigned int[16]' [-Warray-bounds]
> >   262 |                                 put_user(regs->areg[caller_ars+1],
> > ./arch/xtensa/include/asm/uaccess.h:171:18: note: in definition of macro '__put_user_asm'
> >   171 |         :[x] "r"(x_), [efault] "i"(-EFAULT))
> >       |                  ^~
> > ./arch/xtensa/include/asm/uaccess.h:89:17: note: in expansion of macro '__put_user_size'
> >    89 |                 __put_user_size((x), __pu_addr, (size), __pu_err);      \
> >       |                 ^~~~~~~~~~~~~~~
> > ./arch/xtensa/include/asm/uaccess.h:62:33: note: in expansion of macro '__put_user_check'
> >    62 | #define put_user(x, ptr)        __put_user_check((x), (ptr), sizeof(*(ptr)))
> >       |                                 ^~~~~~~~~~~~~~~~
> > arch/xtensa/kernel/process.c:262:33: note: in expansion of macro 'put_user'
> >   262 |                                 put_user(regs->areg[caller_ars+1],
> >       |                                 ^~~~~~~~
> > In file included from ./arch/xtensa/include/asm/processor.h:17,
> >                  from ./arch/xtensa/include/asm/thread_info.h:20,
> >                  from ./arch/xtensa/include/asm/current.h:14,
> >                  from ./include/linux/sched.h:12,
> >                  from arch/xtensa/kernel/process.c:19:
> > ./arch/xtensa/include/asm/ptrace.h:80:23: note: while referencing 'areg'
> >    80 |         unsigned long areg[16];
> >       |                       ^~~~
> >
> >
> > The code is:
> >                                 int callinc = (regs->areg[0] >> 30) & 3;
> >                                 int caller_ars = XCHAL_NUM_AREGS - callinc * 4;
> >                                 put_user(regs->areg[caller_ars+1],
> >                                          (unsigned __user*)(usp - 12));
> >
> > It looks like XCHAL_NUM_AREGS is larger than "16", though?
> >
> > struct pt_regs {
> > ...
> >         unsigned long areg[16];
> >
> > What should be happening here?
> 
> pt_regs::areg is the current register window, but when we enter
> the kernel from the userspace additional valid registers up the call
> stack are saved here:
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/xtensa/kernel/entry.S?h=v5.16#n204
> This is done because when the kernel is built with windowed ABI
> we cannot have a mix of user and kernel registers in the physical
> register file.

This is a bit opaque for me to read, but it looks like it's a loop of
4-at-a-time of the "extra" registers?

> The space for these registers is reserved here:
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/xtensa/kernel/entry.S?h=v5.16#n2102
> by adding PT_REGS_OFFSET, which accounts for the
> XCHAL_NUM_AREGS value, to the task stack address.

Okay, so it seems like there are two "views" of the registers from an
ABI perspective, the userspace view (struct pt_regs), and the kernel
view which is struct pt_regs + more.

> On the other hand, when the kernel is re-entered we don't need
> to save registers up the kernel stack, so the pt_regs structure
> exactly represents the kernel stack frame.
> 
> The xtensa architecture has configurable windowed registers option.
> When it's enabled the machine has more than 16 general purpose
> registers: typically 32 or 64, but only 16 of them are in the current
> window and may be used by instructions.
> The window rotates forward on entry to functions and backwards
> on return. Additional special registers track current window
> position and valid registers.
> 
> For some reason during xtensa port development it was chosen
> to have pt_regs::areg only cover the current register window. I guess
> this was done as a common denominator for the user and kernel
> stack frames and to avoid an exposure of XCHAL_NUM_AREGS
> constant in the user-visible headers. Chris may have additional details.

Right, that makes sense: pt_regs should be the shared user/kernel view.

The compiler is mad about trying to access the extra registers from the
pt_reg struct, so maybe a kernel-only struct could be used here?

-- 
Kees Cook

  reply	other threads:[~2022-02-03 21:56 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-02 23:03 How large is the xtensa pt_regs::areg array supposed to be? Kees Cook
2022-02-03 21:13 ` Max Filippov
2022-02-03 21:56   ` Kees Cook [this message]
2022-02-04  0:05     ` Max Filippov
2022-03-05 20:43 ` Max Filippov
2022-03-06  1:50   ` Max Filippov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=202202031328.21E25051@keescook \
    --to=keescook@chromium.org \
    --cc=chris@zankel.net \
    --cc=jcmvbkbc@gmail.com \
    --cc=linux-hardening@vger.kernel.org \
    --cc=linux-xtensa@linux-xtensa.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.