LinuxPPC-Dev Archive mirror
 help / color / mirror / Atom feed
From: Michael Ellerman <mpe@ellerman.id.au>
To: Nathan Lynch <nathanl@linux.ibm.com>,
	Breno Leitao <leitao@debian.org>,
	Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: "linuxppc-dev@lists.ozlabs.org" <linuxppc-dev@lists.ozlabs.org>
Subject: Re: [PATCH] powerpc/kernel: Fix potential spectre v1 in syscall
Date: Tue, 21 May 2024 11:23:38 +1000	[thread overview]
Message-ID: <87wmno2c11.fsf@mail.lhotse> (raw)
In-Reply-To: <875xxj36ke.fsf@li-e15d104c-2135-11b2-a85c-d7ef17e56be6.ibm.com>

Nathan Lynch <nathanl@linux.ibm.com> writes:
> Michael Ellerman <mpe@ellerman.id.au> writes:
>> Breno Leitao <leitao@debian.org> writes:
>>> On Tue, Mar 12, 2024 at 08:17:42AM +0000, Christophe Leroy wrote:
>>>> +Nathan as this is RTAS related.
>
> Thanks!
>
>>>> Le 21/08/2018 à 20:42, Breno Leitao a écrit :
>>>> > The rtas syscall reads a value from a user-provided structure and uses it
>>>> > to index an array, being a possible area for a potential spectre v1 attack.
>>>> > This is the code that exposes this problem.
>>>> > 
>>>> > 	args.rets = &args.args[nargs];
>>>> > 
>>>> > The nargs is an user provided value, and the below code is an example where
>>>> > the 'nargs' value would be set to XX.
>>>> > 
>>>> > 	struct rtas_args ra;
>>>> > 	ra.nargs = htobe32(XX);
>>>> > 	syscall(__NR_rtas, &ra);
>>>> 
>>>> 
>>>> This patch has been hanging around in patchwork since 2018 and doesn't 
>>>> apply anymore. Is it still relevant ? If so, can you rebase et resubmit ?
>>>
>>> This seems to be important, since nargs is a user-provided value. I can
>>> submit it if the maintainers are willing to accept. I do not want to
>>> spend my time if no one is willing to review it.
>>
>> My memory is that I didn't think it was actually a problem, because all
>> we do is memset args.rets to zero.
>
> This is also my initial reaction to this. I suppose if the memset()
> implementation performs some validation of the destination buffer
> contents (comparing to a known poison value or something) that could
> load the CPU cache then there is a more plausible issue?

Yeah I guess that's possible.

In the past my approach to these was to analyse the exploitability of
each case and only patch those where there was a feasible case to be
made.

But I think that was wrong, doing that analysis is too time consuming at
scale, is easy to get wrong, and is also fragile in the face of the code
changing.

Especially in cases like this where the performance cost of the checks
is going to be dwarfed by other factors like syscall/firmware overhead.

>> Anyway we should probably just fix it to be safe and keep the static
>> checkers happy.
>
> Here is the relevant passage in its current state:
>
>         if (copy_from_user(&args, uargs, 3 * sizeof(u32)) != 0)
>                 return -EFAULT;
>
>         nargs = be32_to_cpu(args.nargs);
>         nret  = be32_to_cpu(args.nret);
>         token = be32_to_cpu(args.token);
>
>         if (nargs >= ARRAY_SIZE(args.args)
>             || nret > ARRAY_SIZE(args.args)
>             || nargs + nret > ARRAY_SIZE(args.args))
>                 return -EINVAL;
>
>         /* Copy in args. */
>         if (copy_from_user(args.args, uargs->args,
>                            nargs * sizeof(rtas_arg_t)) != 0)
>                 return -EFAULT;
>
>         /*
>          * If this token doesn't correspond to a function the kernel
>          * understands, you're not allowed to call it.
>          */
>         func = rtas_token_to_function_untrusted(token);
>         if (!func)
>                 return -EINVAL;
>
>         args.rets = &args.args[nargs];
>         memset(args.rets, 0, nret * sizeof(rtas_arg_t));
>
> Some questions:
>
> 1. The patch sanitizes 'nargs' immediately before the call to memset(),
>    but shouldn't that happen before 'nargs' is used as an input to
>    copy_from_user()?

I think the reasoning is that there's no way to exploit an out of bounds
value using copy_from_user(). But it's much easier to reason about if we
just do the sanitisation up front.

> 2. If 'nargs' needs this treatment, then why wouldn't the user-supplied
>    'nret' and 'token' need them as well? 'nret' is used to index the
>    same array as 'nargs'. And at least conceptually, 'token' is used to
>    index a data structure (xarray) with array-like semantics (to be
>    fair, this is a relatively recent development and was not the case
>    when this change was submitted).
    
I don't know exactly what smatch looks for when trying to detect these,
but I suspect it's a plain array access. Not sure why it doesn't
complain about nret, but I think it would be good to sanitise it as well.

token is different, at least in the above code, because it's not bounds
checked, so there's no bounds check to bypass. Though maybe there is one
inside the rtas lookup code that should be masked.

cheers

  reply	other threads:[~2024-05-21  1:31 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-08-21 18:42 [PATCH] powerpc/kernel: Fix potential spectre v1 in syscall Breno Leitao
2024-03-12  8:17 ` Christophe Leroy
2024-03-12  9:05   ` Breno Leitao
2024-03-12 11:07     ` Michael Ellerman
2024-03-12 13:10       ` Breno Leitao
2024-03-18 15:25       ` Nathan Lynch
2024-05-21  1:23         ` Michael Ellerman [this message]
2024-05-31  0:35           ` Nathan Lynch

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=87wmno2c11.fsf@mail.lhotse \
    --to=mpe@ellerman.id.au \
    --cc=christophe.leroy@csgroup.eu \
    --cc=leitao@debian.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=nathanl@linux.ibm.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).