Re: [PATCH] powerpc/kernel: Fix potential spectre v1 in syscall

2024-03-18 Thread Nathan Lynch
Michael Ellerman  writes:

> Breno Leitao  writes:
>> On Tue, Mar 12, 2024 at 08:17:42AM +, 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 = [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, );
>>> 
>>> 
>>> 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?

> 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(, 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 = [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()?

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).


Re: [PATCH] powerpc/kernel: Fix potential spectre v1 in syscall

2024-03-12 Thread Breno Leitao
On Tue, Mar 12, 2024 at 10:07:54PM +1100, Michael Ellerman wrote:
> Breno Leitao  writes:
> > On Tue, Mar 12, 2024 at 08:17:42AM +, Christophe Leroy wrote:
> >> +Nathan as this is RTAS related.
> >> 
> >> 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 = [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, );
> >> 
> >> 
> >> 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. I thought I'd talked to you on Slack
> about it, but maybe I didn't.
> 
> Anyway we should probably just fix it to be safe and keep the static
> checkers happy.
> 
> I'll rebase it and apply it, I'm sure you've got better things to do :)

Awesome. Thanks Michael!


Re: [PATCH] powerpc/kernel: Fix potential spectre v1 in syscall

2024-03-12 Thread Michael Ellerman
Breno Leitao  writes:
> On Tue, Mar 12, 2024 at 08:17:42AM +, Christophe Leroy wrote:
>> +Nathan as this is RTAS related.
>> 
>> 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 = [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, );
>> 
>> 
>> 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. I thought I'd talked to you on Slack
about it, but maybe I didn't.

Anyway we should probably just fix it to be safe and keep the static
checkers happy.

I'll rebase it and apply it, I'm sure you've got better things to do :)

cheers


Re: [PATCH] powerpc/kernel: Fix potential spectre v1 in syscall

2024-03-12 Thread Breno Leitao
On Tue, Mar 12, 2024 at 08:17:42AM +, Christophe Leroy wrote:
> +Nathan as this is RTAS related.
> 
> 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 = [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, );
> 
> 
> 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.

Thanks for revamping this one.


Re: [PATCH] powerpc/kernel: Fix potential spectre v1 in syscall

2024-03-12 Thread Christophe Leroy
+Nathan as this is RTAS related.

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 = [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, );


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 ?

Thanks
Christophe


> 
> Signed-off-by: Breno Leitao 
> ---
>   arch/powerpc/kernel/rtas.c | 6 --
>   1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
> index 8afd146bc9c7..5ef3c863003d 100644
> --- a/arch/powerpc/kernel/rtas.c
> +++ b/arch/powerpc/kernel/rtas.c
> @@ -27,6 +27,7 @@
>   #include 
>   #include 
>   #include 
> +#include 
>   
>   #include 
>   #include 
> @@ -1056,7 +1057,7 @@ SYSCALL_DEFINE1(rtas, struct rtas_args __user *, uargs)
>   struct rtas_args args;
>   unsigned long flags;
>   char *buff_copy, *errbuf = NULL;
> - int nargs, nret, token;
> + int index, nargs, nret, token;
>   
>   if (!capable(CAP_SYS_ADMIN))
>   return -EPERM;
> @@ -1084,7 +1085,8 @@ SYSCALL_DEFINE1(rtas, struct rtas_args __user *, uargs)
>   if (token == RTAS_UNKNOWN_SERVICE)
>   return -EINVAL;
>   
> - args.rets = [nargs];
> + index = array_index_nospec(nargs, ARRAY_SIZE(args.args));
> + args.rets = [index];
>   memset(args.rets, 0, nret * sizeof(rtas_arg_t));
>   
>   /* Need to handle ibm,suspend_me call specially */


[PATCH] powerpc/kernel: Fix potential spectre v1 in syscall

2018-08-21 Thread Breno Leitao
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 = [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, );

Signed-off-by: Breno Leitao 
---
 arch/powerpc/kernel/rtas.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 8afd146bc9c7..5ef3c863003d 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -1056,7 +1057,7 @@ SYSCALL_DEFINE1(rtas, struct rtas_args __user *, uargs)
struct rtas_args args;
unsigned long flags;
char *buff_copy, *errbuf = NULL;
-   int nargs, nret, token;
+   int index, nargs, nret, token;
 
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
@@ -1084,7 +1085,8 @@ SYSCALL_DEFINE1(rtas, struct rtas_args __user *, uargs)
if (token == RTAS_UNKNOWN_SERVICE)
return -EINVAL;
 
-   args.rets = [nargs];
+   index = array_index_nospec(nargs, ARRAY_SIZE(args.args));
+   args.rets = [index];
memset(args.rets, 0, nret * sizeof(rtas_arg_t));
 
/* Need to handle ibm,suspend_me call specially */
-- 
2.16.3