Re: [PATCH] powerpc/kernel: Fix potential spectre v1 in syscall
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
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
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
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
+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
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