* Re: [PATCHv8 9/9] man2: Add uretprobe syscall page
From: Alejandro Colomar @ 2024-08-16 21:56 UTC (permalink / raw)
To: Jiri Olsa
Cc: Steven Rostedt, Masami Hiramatsu, Oleg Nesterov,
Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
linux-kernel, linux-trace-kernel, linux-api, linux-man, x86, bpf,
Song Liu, Yonghong Song, John Fastabend, Peter Zijlstra,
Thomas Gleixner, Borislav Petkov (AMD), Ingo Molnar,
Andy Lutomirski, Edgecombe, Rick P, Deepak Gupta
In-Reply-To: <c7v4einpsvpswvj3rqn5esap2e5lpeiwacylqlzwdcp7slsgvg@jfmchkiqru4u>
[-- Attachment #1: Type: text/plain, Size: 1086 bytes --]
Hi Jiri, Steven,
On Fri, Aug 16, 2024 at 08:55:47PM GMT, Alejandro Colomar wrote:
> > hi,
> > there are no args for x86.. it's there just to note that it might
> > be different on other archs, so not sure what man page should say
> > in such case.. keeping (void) is fine with me
>
> Hmmm, then I'll remove that paragraph. If that function is implemented
> in another arch and the args are different, we can change the manual
> page then.
>
> >
> > >
> > > Please add the changes proposed below to your patch, tweak anything if
> > > you consider it appropriate) and send it as v10.
> >
> > it looks good to me, thanks a lot
> >
> > Acked-by: From: Jiri Olsa <jolsa@kernel.org>
I have applied your patch with the tweaks I mentioned, and added several
tags to the commit message.
It's currently here:
<https://www.alejandro-colomar.es/src/alx/linux/man-pages/man-pages.git/commit/?h=contrib&id=977e3eecbb81b7398defc4e4f41810ca31d63c1b>
and will $soon be pushed to master.
Have a lovely night!
Alex
--
<https://www.alejandro-colomar.es/>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [PATCHv8 9/9] man2: Add uretprobe syscall page
From: Alejandro Colomar @ 2024-08-16 18:55 UTC (permalink / raw)
To: Jiri Olsa
Cc: Steven Rostedt, Masami Hiramatsu, Oleg Nesterov,
Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
linux-kernel, linux-trace-kernel, linux-api, linux-man, x86, bpf,
Song Liu, Yonghong Song, John Fastabend, Peter Zijlstra,
Thomas Gleixner, Borislav Petkov (AMD), Ingo Molnar,
Andy Lutomirski, Edgecombe, Rick P, Deepak Gupta
In-Reply-To: <Zr-Gf3EEganRSzGM@krava>
[-- Attachment #1: Type: text/plain, Size: 3701 bytes --]
On Fri, Aug 16, 2024 at 07:03:59PM GMT, Jiri Olsa wrote:
> On Fri, Aug 16, 2024 at 01:42:26PM +0200, Alejandro Colomar wrote:
> > Hi Steven, Jiri,
> >
> > On Wed, Aug 07, 2024 at 04:27:34PM GMT, Steven Rostedt wrote:
> > > Just in case nobody pinged you, the rest of the series is now in Linus's
> > > tree.
> >
> > Thanks for the ping!
> >
> > I have prepared some tweaks to the patch (see below).
> > Also, I have some doubts. The prototype shows that it has no arguments
> > (void), but the text said that arguments, if any, are arch-specific.
> > Does any arch have arguments? Should we use a variadic prototype (...)?
>
> hi,
> there are no args for x86.. it's there just to note that it might
> be different on other archs, so not sure what man page should say
> in such case.. keeping (void) is fine with me
Hmmm, then I'll remove that paragraph. If that function is implemented
in another arch and the args are different, we can change the manual
page then.
>
> >
> > Please add the changes proposed below to your patch, tweak anything if
> > you consider it appropriate) and send it as v10.
>
> it looks good to me, thanks a lot
>
> Acked-by: From: Jiri Olsa <jolsa@kernel.org>
Thanks!
Have a lovely day!
Alex
>
> jirka
>
> >
> > Have a lovely day!
> > Alex
> >
> >
> > diff --git i/man/man2/uretprobe.2 w/man/man2/uretprobe.2
> > index cf1c2b0d8..51b566998 100644
> > --- i/man/man2/uretprobe.2
> > +++ w/man/man2/uretprobe.2
> > @@ -7,50 +7,43 @@ .SH NAME
> > uretprobe \- execute pending return uprobes
> > .SH SYNOPSIS
> > .nf
> > -.B int uretprobe(void)
> > +.B int uretprobe(void);
> > .fi
> > .SH DESCRIPTION
> > -The
> > .BR uretprobe ()
> > -system call is an alternative to breakpoint instructions for triggering return
> > -uprobe consumers.
> > +is an alternative to breakpoint instructions
> > +for triggering return uprobe consumers.
> > .P
> > Calls to
> > .BR uretprobe ()
> > -system call are only made from the user-space trampoline provided by the kernel.
> > +are only made from the user-space trampoline provided by the kernel.
> > Calls from any other place result in a
> > .BR SIGILL .
> > -.SH RETURN VALUE
> > -The
> > +.P
> > +Details of the arguments (if any) passed to
> > .BR uretprobe ()
> > -system call return value is architecture-specific.
> > +are architecture-specific.
> > +.SH RETURN VALUE
> > +The return value is architecture-specific.
> > .SH ERRORS
> > .TP
> > .B SIGILL
> > -The
> > .BR uretprobe ()
> > -system call was called by a user-space program.
> > +was called by a user-space program.
> > .SH VERSIONS
> > -Details of the
> > -.BR uretprobe ()
> > -system call behavior vary across systems.
> > +The behavior varies across systems.
> > .SH STANDARDS
> > None.
> > .SH HISTORY
> > -TBD
> > -.SH NOTES
> > -The
> > +Linux 6.11.
> > +.P
> > .BR uretprobe ()
> > -system call was initially introduced for the x86_64 architecture
> > +was initially introduced for the x86_64 architecture
> > where it was shown to be faster than breakpoint traps.
> > It might be extended to other architectures.
> > -.P
> > -The
> > +.SH CAVEATS
> > .BR uretprobe ()
> > -system call exists only to allow the invocation of return uprobe consumers.
> > +exists only to allow the invocation of return uprobe consumers.
> > It should
> > .B never
> > be called directly.
> > -Details of the arguments (if any) passed to
> > -.BR uretprobe ()
> > -and the return value are architecture-specific.
> >
> > --
> > <https://www.alejandro-colomar.es/>
>
--
<https://www.alejandro-colomar.es/>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [PATCH RFT v8 4/9] fork: Add shadow stack support to clone3()
From: Mark Brown @ 2024-08-16 17:17 UTC (permalink / raw)
To: Jann Horn
Cc: Edgecombe, Rick P, dietmar.eggemann@arm.com,
Szabolcs.Nagy@arm.com, brauner@kernel.org,
dave.hansen@linux.intel.com, debug@rivosinc.com, mgorman@suse.de,
vincent.guittot@linaro.org, fweimer@redhat.com, mingo@redhat.com,
rostedt@goodmis.org, hjl.tools@gmail.com, tglx@linutronix.de,
vschneid@redhat.com, shuah@kernel.org, hpa@zytor.com,
peterz@infradead.org, bp@alien8.de, bsegall@google.com,
x86@kernel.org, juri.lelli@redhat.com,
linux-kselftest@vger.kernel.org, kees@kernel.org,
linux-kernel@vger.kernel.org, catalin.marinas@arm.com,
linux-api@vger.kernel.org, will@kernel.org
In-Reply-To: <CAG48ez2z5bRdKNddG+kEGz9A_m=66r38OHjyg6CapFTcjT9aRg@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 924 bytes --]
On Fri, Aug 16, 2024 at 07:08:09PM +0200, Jann Horn wrote:
> Yeah, having a FOLL_FORCE write in clone3 would be a weakness for
> userspace CFI and probably make it possible to violate mseal()
> restrictions that are supposed to enforce that address space regions
> are read-only.
Note that this will only happen for shadow stack pages (with the new
version) and only for a valid token at the specific address. mseal()ing
a shadow stack to be read only is hopefully not going to go terribly
well for userspace.
> Though, did anyone in the thread yet suggest that you could do this
> before the child process has fully materialized but after the child MM
> has been set up? Somewhere in copy_process() between copy_mm() and the
> "/* No more failure paths after this point. */" comment?
Yes, I'e got a version that does that waiting to go pending some
discussion on if we even do the check for the token in the child mm.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCH RFT v8 4/9] fork: Add shadow stack support to clone3()
From: Jann Horn @ 2024-08-16 17:08 UTC (permalink / raw)
To: Edgecombe, Rick P
Cc: dietmar.eggemann@arm.com, broonie@kernel.org,
Szabolcs.Nagy@arm.com, brauner@kernel.org,
dave.hansen@linux.intel.com, debug@rivosinc.com, mgorman@suse.de,
vincent.guittot@linaro.org, fweimer@redhat.com, mingo@redhat.com,
rostedt@goodmis.org, hjl.tools@gmail.com, tglx@linutronix.de,
vschneid@redhat.com, shuah@kernel.org, hpa@zytor.com,
peterz@infradead.org, bp@alien8.de, bsegall@google.com,
x86@kernel.org, juri.lelli@redhat.com,
linux-kselftest@vger.kernel.org, kees@kernel.org,
linux-kernel@vger.kernel.org, catalin.marinas@arm.com,
linux-api@vger.kernel.org, will@kernel.org
In-Reply-To: <f3a2a564094d05beac2dc5ab657cbc009c465667.camel@intel.com>
On Thu, Aug 15, 2024 at 2:18 AM Edgecombe, Rick P
<rick.p.edgecombe@intel.com> wrote:
> On Thu, 2024-08-08 at 09:15 +0100, Mark Brown wrote:
> > + if (access_remote_vm(mm, addr, &val, sizeof(val),
> > + FOLL_FORCE | FOLL_WRITE) != sizeof(val))
> > + goto out;
>
> The GUPs still seem a bit unfortunate for a couple reasons:
> - We could do a CMPXCHG version and are just not (I see ARM has identical code
> in gcs_consume_token()). It's not the only race like this though FWIW.
> - I *think* this is the only unprivileged FOLL_FORCE that can write to the
> current process in the kernel. As is, it could be used on normal RO mappings, at
> least in a limited way. Maybe another point for the VMA check. We'd want to
> check that it is normal shadow stack?
Yeah, having a FOLL_FORCE write in clone3 would be a weakness for
userspace CFI and probably make it possible to violate mseal()
restrictions that are supposed to enforce that address space regions
are read-only.
> - Lingering doubts about the wisdom of doing GUPs during task creation.
>
> I don't think they are show stoppers, but the VMA check would be nice to have in
> the first upstream support.
[...]
> > +static void shstk_post_fork(struct task_struct *p,
> > + struct kernel_clone_args *args)
> > +{
> > + if (!IS_ENABLED(CONFIG_ARCH_HAS_USER_SHADOW_STACK))
> > + return;
> > +
> > + if (!args->shadow_stack)
> > + return;
> > +
> > + if (arch_shstk_post_fork(p, args) != 0)
> > + force_sig_fault_to_task(SIGSEGV, SEGV_CPERR, NULL, p);
> > +}
> > +
>
> Hmm, is this forcing the signal on the new task, which is set up on a user
> provided shadow stack that failed the token check? It would handle the signal
> with an arbitrary SSP then I think. We should probably fail the clone call in
> the parent instead, which can be done by doing the work in copy_process(). Do
> you see a problem with doing it at the end of copy_process()? I don't know if
> there could be ordering constraints.
FWIW I think we have things like force_fatal_sig() and
force_exit_sig() to send signals that userspace can't catch with
signal handlers - if you have to do the copying after the new task has
been set up, something along those lines might be the right way to
kill the child.
Though, did anyone in the thread yet suggest that you could do this
before the child process has fully materialized but after the child MM
has been set up? Somewhere in copy_process() between copy_mm() and the
"/* No more failure paths after this point. */" comment?
^ permalink raw reply
* Re: [PATCH RFT v8 4/9] fork: Add shadow stack support to clone3()
From: Mark Brown @ 2024-08-16 17:06 UTC (permalink / raw)
To: Catalin Marinas
Cc: Edgecombe, Rick P, dietmar.eggemann@arm.com,
juri.lelli@redhat.com, linux-api@vger.kernel.org,
shuah@kernel.org, brauner@kernel.org, dave.hansen@linux.intel.com,
debug@rivosinc.com, mgorman@suse.de, Szabolcs.Nagy@arm.com,
fweimer@redhat.com, linux-kernel@vger.kernel.org,
mingo@redhat.com, hjl.tools@gmail.com, rostedt@goodmis.org,
vincent.guittot@linaro.org, tglx@linutronix.de,
vschneid@redhat.com, kees@kernel.org, will@kernel.org,
hpa@zytor.com, peterz@infradead.org, jannh@google.com,
bp@alien8.de, bsegall@google.com, linux-kselftest@vger.kernel.org,
x86@kernel.org
In-Reply-To: <Zr9yiH6DP0IPac-H@arm.com>
[-- Attachment #1: Type: text/plain, Size: 857 bytes --]
On Fri, Aug 16, 2024 at 04:38:48PM +0100, Catalin Marinas wrote:
> On Fri, Aug 16, 2024 at 02:52:28PM +0000, Edgecombe, Rick P wrote:
> > On the x86 side, we don't have a shadow stack access CMPXCHG. We will have to
> > GUP and do a normal CMPXCHG off of the direct map to handle it fully properly in
> > any case (CLONE_VM or not).
> I guess we could do the same here and for the arm64 gcs_consume_token().
> Basically get_user_page_vma_remote() gives us the page together with the
> vma that you mentioned needs checking. We can then do a cmpxchg directly
> on the page_address(). It's probably faster anyway than doing GUP twice.
There was some complication with get_user_page_vma_remote() while I was
working on an earlier version which meant I didn't use it, though with
adding checking of VMAs perhaps whatever it was isn't such an issue any
more.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCHv8 9/9] man2: Add uretprobe syscall page
From: Jiri Olsa @ 2024-08-16 17:03 UTC (permalink / raw)
To: Alejandro Colomar
Cc: Steven Rostedt, Masami Hiramatsu, Oleg Nesterov,
Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
linux-kernel, linux-trace-kernel, linux-api, linux-man, x86, bpf,
Song Liu, Yonghong Song, John Fastabend, Peter Zijlstra,
Thomas Gleixner, Borislav Petkov (AMD), Ingo Molnar,
Andy Lutomirski, Edgecombe, Rick P, Deepak Gupta
In-Reply-To: <ygpwfyjvhuctug2bsibvc7exbirahojuivglcfjusw4rrqeqhc@44h23muvk3xb>
On Fri, Aug 16, 2024 at 01:42:26PM +0200, Alejandro Colomar wrote:
> Hi Steven, Jiri,
>
> On Wed, Aug 07, 2024 at 04:27:34PM GMT, Steven Rostedt wrote:
> > Just in case nobody pinged you, the rest of the series is now in Linus's
> > tree.
>
> Thanks for the ping!
>
> I have prepared some tweaks to the patch (see below).
> Also, I have some doubts. The prototype shows that it has no arguments
> (void), but the text said that arguments, if any, are arch-specific.
> Does any arch have arguments? Should we use a variadic prototype (...)?
hi,
there are no args for x86.. it's there just to note that it might
be different on other archs, so not sure what man page should say
in such case.. keeping (void) is fine with me
>
> Please add the changes proposed below to your patch, tweak anything if
> you consider it appropriate) and send it as v10.
it looks good to me, thanks a lot
Acked-by: From: Jiri Olsa <jolsa@kernel.org>
jirka
>
> Have a lovely day!
> Alex
>
>
> diff --git i/man/man2/uretprobe.2 w/man/man2/uretprobe.2
> index cf1c2b0d8..51b566998 100644
> --- i/man/man2/uretprobe.2
> +++ w/man/man2/uretprobe.2
> @@ -7,50 +7,43 @@ .SH NAME
> uretprobe \- execute pending return uprobes
> .SH SYNOPSIS
> .nf
> -.B int uretprobe(void)
> +.B int uretprobe(void);
> .fi
> .SH DESCRIPTION
> -The
> .BR uretprobe ()
> -system call is an alternative to breakpoint instructions for triggering return
> -uprobe consumers.
> +is an alternative to breakpoint instructions
> +for triggering return uprobe consumers.
> .P
> Calls to
> .BR uretprobe ()
> -system call are only made from the user-space trampoline provided by the kernel.
> +are only made from the user-space trampoline provided by the kernel.
> Calls from any other place result in a
> .BR SIGILL .
> -.SH RETURN VALUE
> -The
> +.P
> +Details of the arguments (if any) passed to
> .BR uretprobe ()
> -system call return value is architecture-specific.
> +are architecture-specific.
> +.SH RETURN VALUE
> +The return value is architecture-specific.
> .SH ERRORS
> .TP
> .B SIGILL
> -The
> .BR uretprobe ()
> -system call was called by a user-space program.
> +was called by a user-space program.
> .SH VERSIONS
> -Details of the
> -.BR uretprobe ()
> -system call behavior vary across systems.
> +The behavior varies across systems.
> .SH STANDARDS
> None.
> .SH HISTORY
> -TBD
> -.SH NOTES
> -The
> +Linux 6.11.
> +.P
> .BR uretprobe ()
> -system call was initially introduced for the x86_64 architecture
> +was initially introduced for the x86_64 architecture
> where it was shown to be faster than breakpoint traps.
> It might be extended to other architectures.
> -.P
> -The
> +.SH CAVEATS
> .BR uretprobe ()
> -system call exists only to allow the invocation of return uprobe consumers.
> +exists only to allow the invocation of return uprobe consumers.
> It should
> .B never
> be called directly.
> -Details of the arguments (if any) passed to
> -.BR uretprobe ()
> -and the return value are architecture-specific.
>
> --
> <https://www.alejandro-colomar.es/>
^ permalink raw reply
* Re: [PATCH RFT v8 0/9] fork: Support shadow stacks in clone3()
From: Mark Brown @ 2024-08-16 16:19 UTC (permalink / raw)
To: Jann Horn
Cc: brauner, Kees Cook, Rick P. Edgecombe, Deepak Gupta,
Szabolcs Nagy, H.J. Lu, Florian Weimer, Thomas Gleixner,
Ingo Molnar, Borislav Petkov, Dave Hansen, x86, H. Peter Anvin,
Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider,
Shuah Khan, linux-kernel, Catalin Marinas, Will Deacon,
linux-kselftest, linux-api, David Hildenbrand
In-Reply-To: <CAG48ez38VVj10fixN5FYo1qujHSH17bPGynzUQugqeBRYAOBRw@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 941 bytes --]
On Fri, Aug 16, 2024 at 05:52:20PM +0200, Jann Horn wrote:
> As a heads-up so you don't get surprised by this in the future:
> Because clone3() does not pass the flags in a register like clone()
> does, it is not available in places like docker containers that use
> the default Docker seccomp policy
> (https://github.com/moby/moby/blob/master/profiles/seccomp/default.json).
> Docker uses seccomp to filter clone() arguments (to prevent stuff like
> namespace creation), and that's not possible with clone3(), so
> clone3() is blocked.
This is probably fine, the existing shadow stack ABI provides a sensible
default behaviour for things that just use regular clone(). This series
just adds more control for things using clone3(), the main issue would
be anything that *needs* to specify stack size/placement and can't use
clone3(). That would need a separate userspace API if required, and
we'd still want to extend clone3() anyway.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCH RFT v8 0/9] fork: Support shadow stacks in clone3()
From: Jann Horn @ 2024-08-16 15:52 UTC (permalink / raw)
To: Mark Brown, brauner, Kees Cook
Cc: Rick P. Edgecombe, Deepak Gupta, Szabolcs Nagy, H.J. Lu,
Florian Weimer, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, x86, H. Peter Anvin, Peter Zijlstra, Juri Lelli,
Vincent Guittot, Dietmar Eggemann, Steven Rostedt, Ben Segall,
Mel Gorman, Valentin Schneider, Shuah Khan, linux-kernel,
Catalin Marinas, Will Deacon, linux-kselftest, linux-api,
David Hildenbrand
In-Reply-To: <20240808-clone3-shadow-stack-v8-0-0acf37caf14c@kernel.org>
On Thu, Aug 8, 2024 at 10:16 AM Mark Brown <broonie@kernel.org> wrote:
> Since clone3() is readily extensible let's add support for specifying a
> shadow stack when creating a new thread or process in a similar manner
> to how the normal stack is specified, keeping the current implicit
> allocation behaviour if one is not specified either with clone3() or
> through the use of clone(). The user must provide a shadow stack
> address and size, this must point to memory mapped for use as a shadow
> stackby map_shadow_stack() with a shadow stack token at the top of the
> stack.
As a heads-up so you don't get surprised by this in the future:
Because clone3() does not pass the flags in a register like clone()
does, it is not available in places like docker containers that use
the default Docker seccomp policy
(https://github.com/moby/moby/blob/master/profiles/seccomp/default.json).
Docker uses seccomp to filter clone() arguments (to prevent stuff like
namespace creation), and that's not possible with clone3(), so
clone3() is blocked.
The same thing applies to things like sandboxed renderer processes of
web browsers - they want to block anything other than creating normal
threads, so they use seccomp to block stuff like namespace creation
and creating new processes.
I briefly mentioned this here during clone3 development, though I
probably should have been more explicit about how it would be
beneficial for clone3 to pass flags in a register:
<https://lore.kernel.org/all/CAG48ez3q=BeNcuVTKBN79kJui4vC6nw0Bfq6xc-i0neheT17TA@mail.gmail.com/>
So if you want your feature to be available in such contexts, you'll
probably have to either add a new syscall clone4() that passes the
flags in a register; or do the plumbing work required to make it
possible to seccomp-filter things other than register contexts (by
invoking seccomp again from the clone3 handler with some kinda
pseudo-syscall?); or change the signature of the existing syscall (but
that would require something like using the high bit of the size to
signal that there's a flags argument in another register, which is
probably more ugly than just adding a new syscall).
^ permalink raw reply
* Re: [PATCH RFT v8 4/9] fork: Add shadow stack support to clone3()
From: Mark Brown @ 2024-08-16 15:46 UTC (permalink / raw)
To: Catalin Marinas
Cc: Edgecombe, Rick P, dietmar.eggemann@arm.com,
Szabolcs.Nagy@arm.com, brauner@kernel.org,
dave.hansen@linux.intel.com, debug@rivosinc.com, mgorman@suse.de,
vincent.guittot@linaro.org, fweimer@redhat.com, mingo@redhat.com,
rostedt@goodmis.org, hjl.tools@gmail.com, tglx@linutronix.de,
vschneid@redhat.com, shuah@kernel.org, hpa@zytor.com,
peterz@infradead.org, bp@alien8.de, bsegall@google.com,
x86@kernel.org, juri.lelli@redhat.com, jannh@google.com,
linux-kselftest@vger.kernel.org, kees@kernel.org,
linux-kernel@vger.kernel.org, linux-api@vger.kernel.org,
will@kernel.org
In-Reply-To: <Zr9wSa2Yyq-MCWVq@arm.com>
[-- Attachment #1: Type: text/plain, Size: 853 bytes --]
On Fri, Aug 16, 2024 at 04:29:13PM +0100, Catalin Marinas wrote:
> On Fri, Aug 16, 2024 at 11:51:57AM +0100, Mark Brown wrote:
> > I change back to parsing the token in the parent but I don't want to end
> > up in a cycle of bouncing between the two implementations depending on
> > who's reviewed the most recent version.
> You and others spent a lot more time looking at shadow stacks than me.
> I'm not necessarily asking to change stuff but rather understand the
> choices made.
I'm a little ambivalent on this - on the one hand accessing the child's
memory is not a thing of great beauty but on the other hand it does
make the !CLONE_VM case more solid. My general instinct is that the
ugliness is less of an issue than the "oh, there's a gap there" stuff
with the !CLONE_VM case since it's more "why are we doing that?" than
"we missed this".
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCH RFT v8 4/9] fork: Add shadow stack support to clone3()
From: Catalin Marinas @ 2024-08-16 15:38 UTC (permalink / raw)
To: Edgecombe, Rick P
Cc: dietmar.eggemann@arm.com, juri.lelli@redhat.com,
linux-api@vger.kernel.org, shuah@kernel.org, brauner@kernel.org,
dave.hansen@linux.intel.com, debug@rivosinc.com, mgorman@suse.de,
Szabolcs.Nagy@arm.com, fweimer@redhat.com,
linux-kernel@vger.kernel.org, mingo@redhat.com,
hjl.tools@gmail.com, rostedt@goodmis.org,
vincent.guittot@linaro.org, tglx@linutronix.de,
vschneid@redhat.com, kees@kernel.org, will@kernel.org,
hpa@zytor.com, peterz@infradead.org, jannh@google.com,
bp@alien8.de, bsegall@google.com, linux-kselftest@vger.kernel.org,
broonie@kernel.org, x86@kernel.org
In-Reply-To: <23a8838adda28b03b3db77e135934e2da0599d0f.camel@intel.com>
On Fri, Aug 16, 2024 at 02:52:28PM +0000, Edgecombe, Rick P wrote:
> On Fri, 2024-08-16 at 09:44 +0100, Catalin Marinas wrote:
> > > After a token is consumed normally, it doesn't set it to zero. Instead it
> > > sets it to a "previous-ssp token". I don't think we actually want to do that here
> > > though because it involves the old SSP, which doesn't really apply in this
> > > case. I don't see any problem with zero, but was there any special thinking behind
> > > it?
> >
> > BTW, since it's the parent setting up the shadow stack in its own
> > address space before forking, I think at least the read can avoid
> > access_remote_vm() and we could do it earlier, even before the new
> > process is created.
>
> Hmm. Makes sense. It's a bit racy since the parent could consume that token from
> another thread, but it would be a race in any case.
More on the race below. If we handle it properly, we don't need the
separate checks.
> > > > + if (access_remote_vm(mm, addr, &val, sizeof(val),
> > > > + FOLL_FORCE | FOLL_WRITE) != sizeof(val))
> > > > + goto out;
> > >
> > > The GUPs still seem a bit unfortunate for a couple reasons:
> > > - We could do a CMPXCHG version and are just not (I see ARM has identical
> > > code in gcs_consume_token()). It's not the only race like this though FWIW.
> > > - I *think* this is the only unprivileged FOLL_FORCE that can write to the
> > > current process in the kernel. As is, it could be used on normal RO
> > > mappings, at
> > > least in a limited way. Maybe another point for the VMA check. We'd want to
> > > check that it is normal shadow stack?
> > > - Lingering doubts about the wisdom of doing GUPs during task creation.
> >
> > I don't like the access_remote_vm() either. In the common (practically
> > only) case with CLONE_VM, the mm is actually current->mm, so no need for
> > a GUP.
>
> On the x86 side, we don't have a shadow stack access CMPXCHG. We will have to
> GUP and do a normal CMPXCHG off of the direct map to handle it fully properly in
> any case (CLONE_VM or not).
I guess we could do the same here and for the arm64 gcs_consume_token().
Basically get_user_page_vma_remote() gives us the page together with the
vma that you mentioned needs checking. We can then do a cmpxchg directly
on the page_address(). It's probably faster anyway than doing GUP twice.
--
Catalin
^ permalink raw reply
* Re: [PATCH RFT v8 4/9] fork: Add shadow stack support to clone3()
From: Mark Brown @ 2024-08-16 15:30 UTC (permalink / raw)
To: Edgecombe, Rick P
Cc: catalin.marinas@arm.com, dietmar.eggemann@arm.com,
juri.lelli@redhat.com, linux-api@vger.kernel.org,
shuah@kernel.org, brauner@kernel.org, dave.hansen@linux.intel.com,
debug@rivosinc.com, mgorman@suse.de, Szabolcs.Nagy@arm.com,
fweimer@redhat.com, linux-kernel@vger.kernel.org,
mingo@redhat.com, hjl.tools@gmail.com, rostedt@goodmis.org,
vincent.guittot@linaro.org, tglx@linutronix.de,
vschneid@redhat.com, kees@kernel.org, will@kernel.org,
hpa@zytor.com, peterz@infradead.org, jannh@google.com,
bp@alien8.de, bsegall@google.com, linux-kselftest@vger.kernel.org,
x86@kernel.org
In-Reply-To: <23a8838adda28b03b3db77e135934e2da0599d0f.camel@intel.com>
[-- Attachment #1: Type: text/plain, Size: 790 bytes --]
On Fri, Aug 16, 2024 at 02:52:28PM +0000, Edgecombe, Rick P wrote:
> On Fri, 2024-08-16 at 09:44 +0100, Catalin Marinas wrote:
> > BTW, since it's the parent setting up the shadow stack in its own
> > address space before forking, I think at least the read can avoid
> > access_remote_vm() and we could do it earlier, even before the new
> > process is created.
> Hmm. Makes sense. It's a bit racy since the parent could consume that token from
> another thread, but it would be a race in any case.
So it sounds like we might be coming round to this? I've got a new
version that verifies the VM_SHADOW_STACK good to go but if we're going
to switch back to consuming the token in the parent context I may as
well do that. Like I said in the other mail I'd rather not flip flop
on this.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCH RFT v8 4/9] fork: Add shadow stack support to clone3()
From: Catalin Marinas @ 2024-08-16 15:29 UTC (permalink / raw)
To: Mark Brown
Cc: Edgecombe, Rick P, dietmar.eggemann@arm.com,
Szabolcs.Nagy@arm.com, brauner@kernel.org,
dave.hansen@linux.intel.com, debug@rivosinc.com, mgorman@suse.de,
vincent.guittot@linaro.org, fweimer@redhat.com, mingo@redhat.com,
rostedt@goodmis.org, hjl.tools@gmail.com, tglx@linutronix.de,
vschneid@redhat.com, shuah@kernel.org, hpa@zytor.com,
peterz@infradead.org, bp@alien8.de, bsegall@google.com,
x86@kernel.org, juri.lelli@redhat.com, jannh@google.com,
linux-kselftest@vger.kernel.org, kees@kernel.org,
linux-kernel@vger.kernel.org, linux-api@vger.kernel.org,
will@kernel.org
In-Reply-To: <c644d64b-f7d0-47de-b5ba-ae2ac1b46e1b@sirena.org.uk>
On Fri, Aug 16, 2024 at 11:51:57AM +0100, Mark Brown wrote:
> On Fri, Aug 16, 2024 at 09:44:46AM +0100, Catalin Marinas wrote:
> > We could, in theory, consume this token in the parent before the child
> > mm is created. The downside is that if a parent forks multiple
> > processes using the same shadow stack, it will have to set the token
> > each time. I'd be fine with this, that's really only for the mostly
> > theoretical case where one doesn't use CLONE_VM and still want a
> > separate stack and shadow stack.
>
> I originally implemented things that way but people did complain about
> the !CLONE_VM case, which does TBH seem reasonable. Note that the
> parent won't as standard be able to set the token again - since the
> shadow stack is not writable to userspace by default it'd instead need
> to allocate a whole new shadow stack for each child.
Ah, good point.
> I change back to parsing the token in the parent but I don't want to end
> up in a cycle of bouncing between the two implementations depending on
> who's reviewed the most recent version.
You and others spent a lot more time looking at shadow stacks than me.
I'm not necessarily asking to change stuff but rather understand the
choices made.
--
Catalin
^ permalink raw reply
* Re: [PATCH RFT v8 4/9] fork: Add shadow stack support to clone3()
From: Edgecombe, Rick P @ 2024-08-16 14:52 UTC (permalink / raw)
To: catalin.marinas@arm.com
Cc: dietmar.eggemann@arm.com, juri.lelli@redhat.com,
linux-api@vger.kernel.org, shuah@kernel.org, brauner@kernel.org,
dave.hansen@linux.intel.com, debug@rivosinc.com, mgorman@suse.de,
Szabolcs.Nagy@arm.com, fweimer@redhat.com,
linux-kernel@vger.kernel.org, mingo@redhat.com,
hjl.tools@gmail.com, rostedt@goodmis.org,
vincent.guittot@linaro.org, tglx@linutronix.de,
vschneid@redhat.com, kees@kernel.org, will@kernel.org,
hpa@zytor.com, peterz@infradead.org, jannh@google.com,
bp@alien8.de, bsegall@google.com, linux-kselftest@vger.kernel.org,
broonie@kernel.org, x86@kernel.org
In-Reply-To: <Zr8RfoHZYRWem1K9@arm.com>
On Fri, 2024-08-16 at 09:44 +0100, Catalin Marinas wrote:
> > After a token is consumed normally, it doesn't set it to zero. Instead it
> > sets
> > it to a "previous-ssp token". I don't think we actually want to do that here
> > though because it involves the old SSP, which doesn't really apply in this
> > case.
> > I don't see any problem with zero, but was there any special thinking behind
> > it?
>
> BTW, since it's the parent setting up the shadow stack in its own
> address space before forking, I think at least the read can avoid
> access_remote_vm() and we could do it earlier, even before the new
> process is created.
Hmm. Makes sense. It's a bit racy since the parent could consume that token from
another thread, but it would be a race in any case.
>
> > > + if (access_remote_vm(mm, addr, &val, sizeof(val),
> > > + FOLL_FORCE | FOLL_WRITE) != sizeof(val))
> > > + goto out;
> >
> > The GUPs still seem a bit unfortunate for a couple reasons:
> > - We could do a CMPXCHG version and are just not (I see ARM has identical
> > code
> > in gcs_consume_token()). It's not the only race like this though FWIW.
> > - I *think* this is the only unprivileged FOLL_FORCE that can write to the
> > current process in the kernel. As is, it could be used on normal RO
> > mappings, at
> > least in a limited way. Maybe another point for the VMA check. We'd want to
> > check that it is normal shadow stack?
> > - Lingering doubts about the wisdom of doing GUPs during task creation.
>
> I don't like the access_remote_vm() either. In the common (practically
> only) case with CLONE_VM, the mm is actually current->mm, so no need for
> a GUP.
On the x86 side, we don't have a shadow stack access CMPXCHG. We will have to
GUP and do a normal CMPXCHG off of the direct map to handle it fully properly in
any case (CLONE_VM or not).
>
> We could, in theory, consume this token in the parent before the child
> mm is created. The downside is that if a parent forks multiple
> processes using the same shadow stack, it will have to set the token
> each time. I'd be fine with this, that's really only for the mostly
> theoretical case where one doesn't use CLONE_VM and still want a
> separate stack and shadow stack.
>
> > I don't think they are show stoppers, but the VMA check would be nice to
> > have in
> > the first upstream support.
>
> Good point.
^ permalink raw reply
* Re: [PATCHv8 9/9] man2: Add uretprobe syscall page
From: Alejandro Colomar @ 2024-08-16 11:42 UTC (permalink / raw)
To: Steven Rostedt
Cc: Masami Hiramatsu, Jiri Olsa, Oleg Nesterov, Alexei Starovoitov,
Daniel Borkmann, Andrii Nakryiko, linux-kernel,
linux-trace-kernel, linux-api, linux-man, x86, bpf, Song Liu,
Yonghong Song, John Fastabend, Peter Zijlstra, Thomas Gleixner,
Borislav Petkov (AMD), Ingo Molnar, Andy Lutomirski,
Edgecombe, Rick P, Deepak Gupta
In-Reply-To: <20240807162734.100d3b55@gandalf.local.home>
[-- Attachment #1: Type: text/plain, Size: 2637 bytes --]
Hi Steven, Jiri,
On Wed, Aug 07, 2024 at 04:27:34PM GMT, Steven Rostedt wrote:
> Just in case nobody pinged you, the rest of the series is now in Linus's
> tree.
Thanks for the ping!
I have prepared some tweaks to the patch (see below).
Also, I have some doubts. The prototype shows that it has no arguments
(void), but the text said that arguments, if any, are arch-specific.
Does any arch have arguments? Should we use a variadic prototype (...)?
Please add the changes proposed below to your patch, tweak anything if
you consider it appropriate) and send it as v10.
Have a lovely day!
Alex
diff --git i/man/man2/uretprobe.2 w/man/man2/uretprobe.2
index cf1c2b0d8..51b566998 100644
--- i/man/man2/uretprobe.2
+++ w/man/man2/uretprobe.2
@@ -7,50 +7,43 @@ .SH NAME
uretprobe \- execute pending return uprobes
.SH SYNOPSIS
.nf
-.B int uretprobe(void)
+.B int uretprobe(void);
.fi
.SH DESCRIPTION
-The
.BR uretprobe ()
-system call is an alternative to breakpoint instructions for triggering return
-uprobe consumers.
+is an alternative to breakpoint instructions
+for triggering return uprobe consumers.
.P
Calls to
.BR uretprobe ()
-system call are only made from the user-space trampoline provided by the kernel.
+are only made from the user-space trampoline provided by the kernel.
Calls from any other place result in a
.BR SIGILL .
-.SH RETURN VALUE
-The
+.P
+Details of the arguments (if any) passed to
.BR uretprobe ()
-system call return value is architecture-specific.
+are architecture-specific.
+.SH RETURN VALUE
+The return value is architecture-specific.
.SH ERRORS
.TP
.B SIGILL
-The
.BR uretprobe ()
-system call was called by a user-space program.
+was called by a user-space program.
.SH VERSIONS
-Details of the
-.BR uretprobe ()
-system call behavior vary across systems.
+The behavior varies across systems.
.SH STANDARDS
None.
.SH HISTORY
-TBD
-.SH NOTES
-The
+Linux 6.11.
+.P
.BR uretprobe ()
-system call was initially introduced for the x86_64 architecture
+was initially introduced for the x86_64 architecture
where it was shown to be faster than breakpoint traps.
It might be extended to other architectures.
-.P
-The
+.SH CAVEATS
.BR uretprobe ()
-system call exists only to allow the invocation of return uprobe consumers.
+exists only to allow the invocation of return uprobe consumers.
It should
.B never
be called directly.
-Details of the arguments (if any) passed to
-.BR uretprobe ()
-and the return value are architecture-specific.
--
<https://www.alejandro-colomar.es/>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply related
* Re: [PATCH RFT v8 4/9] fork: Add shadow stack support to clone3()
From: Mark Brown @ 2024-08-16 10:51 UTC (permalink / raw)
To: Catalin Marinas
Cc: Edgecombe, Rick P, dietmar.eggemann@arm.com,
Szabolcs.Nagy@arm.com, brauner@kernel.org,
dave.hansen@linux.intel.com, debug@rivosinc.com, mgorman@suse.de,
vincent.guittot@linaro.org, fweimer@redhat.com, mingo@redhat.com,
rostedt@goodmis.org, hjl.tools@gmail.com, tglx@linutronix.de,
vschneid@redhat.com, shuah@kernel.org, hpa@zytor.com,
peterz@infradead.org, bp@alien8.de, bsegall@google.com,
x86@kernel.org, juri.lelli@redhat.com, jannh@google.com,
linux-kselftest@vger.kernel.org, kees@kernel.org,
linux-kernel@vger.kernel.org, linux-api@vger.kernel.org,
will@kernel.org
In-Reply-To: <Zr8RfoHZYRWem1K9@arm.com>
[-- Attachment #1: Type: text/plain, Size: 963 bytes --]
On Fri, Aug 16, 2024 at 09:44:46AM +0100, Catalin Marinas wrote:
> We could, in theory, consume this token in the parent before the child
> mm is created. The downside is that if a parent forks multiple
> processes using the same shadow stack, it will have to set the token
> each time. I'd be fine with this, that's really only for the mostly
> theoretical case where one doesn't use CLONE_VM and still want a
> separate stack and shadow stack.
I originally implemented things that way but people did complain about
the !CLONE_VM case, which does TBH seem reasonable. Note that the
parent won't as standard be able to set the token again - since the
shadow stack is not writable to userspace by default it'd instead need
to allocate a whole new shadow stack for each child.
I change back to parsing the token in the parent but I don't want to end
up in a cycle of bouncing between the two implementations depending on
who's reviewed the most recent version.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCH RFT v8 4/9] fork: Add shadow stack support to clone3()
From: Catalin Marinas @ 2024-08-16 8:44 UTC (permalink / raw)
To: Edgecombe, Rick P
Cc: dietmar.eggemann@arm.com, broonie@kernel.org,
Szabolcs.Nagy@arm.com, brauner@kernel.org,
dave.hansen@linux.intel.com, debug@rivosinc.com, mgorman@suse.de,
vincent.guittot@linaro.org, fweimer@redhat.com, mingo@redhat.com,
rostedt@goodmis.org, hjl.tools@gmail.com, tglx@linutronix.de,
vschneid@redhat.com, shuah@kernel.org, hpa@zytor.com,
peterz@infradead.org, bp@alien8.de, bsegall@google.com,
x86@kernel.org, juri.lelli@redhat.com, jannh@google.com,
linux-kselftest@vger.kernel.org, kees@kernel.org,
linux-kernel@vger.kernel.org, linux-api@vger.kernel.org,
will@kernel.org
In-Reply-To: <f3a2a564094d05beac2dc5ab657cbc009c465667.camel@intel.com>
On Thu, Aug 15, 2024 at 12:18:23AM +0000, Edgecombe, Rick P wrote:
> On Thu, 2024-08-08 at 09:15 +0100, Mark Brown wrote:
> > +int arch_shstk_post_fork(struct task_struct *t, struct kernel_clone_args
> > *args)
[...]
> > + /* This should really be an atomic cmpxchg. It is not. */
> > + if (access_remote_vm(mm, addr, &val, sizeof(val),
> > + FOLL_FORCE) != sizeof(val))
> > + goto out;
> > +
> > + if (val != expected)
> > + goto out;
> > + val = 0;
>
> After a token is consumed normally, it doesn't set it to zero. Instead it sets
> it to a "previous-ssp token". I don't think we actually want to do that here
> though because it involves the old SSP, which doesn't really apply in this case.
> I don't see any problem with zero, but was there any special thinking behind it?
BTW, since it's the parent setting up the shadow stack in its own
address space before forking, I think at least the read can avoid
access_remote_vm() and we could do it earlier, even before the new
process is created.
> > + if (access_remote_vm(mm, addr, &val, sizeof(val),
> > + FOLL_FORCE | FOLL_WRITE) != sizeof(val))
> > + goto out;
>
> The GUPs still seem a bit unfortunate for a couple reasons:
> - We could do a CMPXCHG version and are just not (I see ARM has identical code
> in gcs_consume_token()). It's not the only race like this though FWIW.
> - I *think* this is the only unprivileged FOLL_FORCE that can write to the
> current process in the kernel. As is, it could be used on normal RO mappings, at
> least in a limited way. Maybe another point for the VMA check. We'd want to
> check that it is normal shadow stack?
> - Lingering doubts about the wisdom of doing GUPs during task creation.
I don't like the access_remote_vm() either. In the common (practically
only) case with CLONE_VM, the mm is actually current->mm, so no need for
a GUP.
We could, in theory, consume this token in the parent before the child
mm is created. The downside is that if a parent forks multiple
processes using the same shadow stack, it will have to set the token
each time. I'd be fine with this, that's really only for the mostly
theoretical case where one doesn't use CLONE_VM and still want a
separate stack and shadow stack.
> I don't think they are show stoppers, but the VMA check would be nice to have in
> the first upstream support.
Good point.
--
Catalin
^ permalink raw reply
* Re: [PATCH RFT v8 4/9] fork: Add shadow stack support to clone3()
From: Mark Brown @ 2024-08-15 14:24 UTC (permalink / raw)
To: Edgecombe, Rick P
Cc: dietmar.eggemann@arm.com, Szabolcs.Nagy@arm.com,
brauner@kernel.org, dave.hansen@linux.intel.com,
debug@rivosinc.com, mgorman@suse.de, vincent.guittot@linaro.org,
fweimer@redhat.com, mingo@redhat.com, rostedt@goodmis.org,
hjl.tools@gmail.com, tglx@linutronix.de, vschneid@redhat.com,
shuah@kernel.org, hpa@zytor.com, peterz@infradead.org,
bp@alien8.de, bsegall@google.com, x86@kernel.org,
juri.lelli@redhat.com, jannh@google.com,
linux-kselftest@vger.kernel.org, kees@kernel.org,
linux-kernel@vger.kernel.org, catalin.marinas@arm.com,
linux-api@vger.kernel.org, will@kernel.org
In-Reply-To: <f3a2a564094d05beac2dc5ab657cbc009c465667.camel@intel.com>
[-- Attachment #1: Type: text/plain, Size: 4165 bytes --]
On Thu, Aug 15, 2024 at 12:18:23AM +0000, Edgecombe, Rick P wrote:
> On Thu, 2024-08-08 at 09:15 +0100, Mark Brown wrote:
> > + ssp = args->shadow_stack + args->shadow_stack_size;
> > + addr = ssp - SS_FRAME_SIZE;
> > + expected = ssp | BIT(0);
> > + mm = get_task_mm(t);
> > + if (!mm)
> > + return -EFAULT;
> We could check that the VMA is shadow stack here. I'm not sure what could go
> wrong though. If you point it to RW memory it could start the thread with that
> as a shadow stack and just blow up at the first call. It might be nicer to fail
> earlier though.
Sure, I wasn't doing anything since like you say the new thread will
fail anyway but we can do the check. As you point out below it'll close
down the possibility of writing to memory.
> > + /* This should really be an atomic cmpxchg. It is not. */
> > + if (access_remote_vm(mm, addr, &val, sizeof(val),
> > + FOLL_FORCE) != sizeof(val))
> > + goto out;
> > +
> > + if (val != expected)
> > + goto out;
> > + val = 0;
> After a token is consumed normally, it doesn't set it to zero. Instead it sets
> it to a "previous-ssp token". I don't think we actually want to do that here
> though because it involves the old SSP, which doesn't really apply in this case.
> I don't see any problem with zero, but was there any special thinking behind it?
I wasn't aware of the x86 behaviour for pivots here, 0 was just a
default thing to choose for an invalid value. arm64 will also leave
a value on the outgoing stack as a product of the two step pivots we
have but it's not really something you'd look for.
> > + if (access_remote_vm(mm, addr, &val, sizeof(val),
> > + FOLL_FORCE | FOLL_WRITE) != sizeof(val))
> > + goto out;
> The GUPs still seem a bit unfortunate for a couple reasons:
> - We could do a CMPXCHG version and are just not (I see ARM has identical code
> in gcs_consume_token()). It's not the only race like this though FWIW.
> - I *think* this is the only unprivileged FOLL_FORCE that can write to the
> current process in the kernel. As is, it could be used on normal RO mappings, at
> least in a limited way. Maybe another point for the VMA check. We'd want to
> check that it is normal shadow stack?
> - Lingering doubts about the wisdom of doing GUPs during task creation.
> I don't think they are show stoppers, but the VMA check would be nice to have in
> the first upstream support.
The check you suggest for shadow stack memory should avoid abuse of the
FOLL_FORCE at least. It'd be a bit narrow, you'd only be able to
overwrite a value where we managed to read a valid token, but it's
there.
> > +static void shstk_post_fork(struct task_struct *p,
> > + struct kernel_clone_args *args)
> > +{
> > + if (!IS_ENABLED(CONFIG_ARCH_HAS_USER_SHADOW_STACK))
> > + return;
> > +
> > + if (!args->shadow_stack)
> > + return;
> > +
> > + if (arch_shstk_post_fork(p, args) != 0)
> > + force_sig_fault_to_task(SIGSEGV, SEGV_CPERR, NULL, p);
> > +}
> Hmm, is this forcing the signal on the new task, which is set up on a user
> provided shadow stack that failed the token check? It would handle the signal
> with an arbitrary SSP then I think. We should probably fail the clone call in
> the parent instead, which can be done by doing the work in copy_process(). Do
One thing I was thinking when writing this was that I wanted to make it
possible to implement the check in the vDSO if there's any architectures
that could do so, avoiding any need to GUP, but I can't see that that's
actually been possible.
> you see a problem with doing it at the end of copy_process()? I don't know if
> there could be ordering constraints.
I was concerned when I was writing the code about ordring constraints,
but I did revise what the code was doing several times and as I was
saying in reply to Catalin I'm no longer sure those apply.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCH RFT v8 0/9] fork: Support shadow stacks in clone3()
From: Edgecombe, Rick P @ 2024-08-15 0:19 UTC (permalink / raw)
To: kees@kernel.org, broonie@kernel.org
Cc: dietmar.eggemann@arm.com, catalin.marinas@arm.com,
david@redhat.com, Szabolcs.Nagy@arm.com, brauner@kernel.org,
dave.hansen@linux.intel.com, debug@rivosinc.com, mgorman@suse.de,
vincent.guittot@linaro.org, fweimer@redhat.com,
linux-kernel@vger.kernel.org, mingo@redhat.com,
rostedt@goodmis.org, hjl.tools@gmail.com, tglx@linutronix.de,
linux-api@vger.kernel.org, vschneid@redhat.com, shuah@kernel.org,
will@kernel.org, hpa@zytor.com, peterz@infradead.org,
jannh@google.com, bp@alien8.de, bsegall@google.com,
linux-kselftest@vger.kernel.org, x86@kernel.org,
juri.lelli@redhat.com
In-Reply-To: <202408081053.0EABACA@keescook>
On Thu, 2024-08-08 at 10:54 -0700, Kees Cook wrote:
> Tested-by: Kees Cook <kees@kernel.org>
I regression tested it with the CET enabled glibc selftests. No issues.
^ permalink raw reply
* Re: [PATCH RFT v8 4/9] fork: Add shadow stack support to clone3()
From: Edgecombe, Rick P @ 2024-08-15 0:18 UTC (permalink / raw)
To: dietmar.eggemann@arm.com, broonie@kernel.org,
Szabolcs.Nagy@arm.com, brauner@kernel.org,
dave.hansen@linux.intel.com, debug@rivosinc.com, mgorman@suse.de,
vincent.guittot@linaro.org, fweimer@redhat.com, mingo@redhat.com,
rostedt@goodmis.org, hjl.tools@gmail.com, tglx@linutronix.de,
vschneid@redhat.com, shuah@kernel.org, hpa@zytor.com,
peterz@infradead.org, bp@alien8.de, bsegall@google.com,
x86@kernel.org, juri.lelli@redhat.com
Cc: jannh@google.com, linux-kselftest@vger.kernel.org,
kees@kernel.org, linux-kernel@vger.kernel.org,
catalin.marinas@arm.com, linux-api@vger.kernel.org,
will@kernel.org
In-Reply-To: <20240808-clone3-shadow-stack-v8-4-0acf37caf14c@kernel.org>
On Thu, 2024-08-08 at 09:15 +0100, Mark Brown wrote:
> +int arch_shstk_post_fork(struct task_struct *t, struct kernel_clone_args
> *args)
> +{
> + /*
> + * SSP is aligned, so reserved bits and mode bit are a zero, just mark
> + * the token 64-bit.
> + */
> + struct mm_struct *mm;
> + unsigned long addr, ssp;
> + u64 expected;
> + u64 val;
> + int ret = -EINVAL;
We should probably?
if (!features_enabled(ARCH_SHSTK_SHSTK))
return 0;
> +
> + ssp = args->shadow_stack + args->shadow_stack_size;
> + addr = ssp - SS_FRAME_SIZE;
> + expected = ssp | BIT(0);
> +
> + mm = get_task_mm(t);
> + if (!mm)
> + return -EFAULT;
We could check that the VMA is shadow stack here. I'm not sure what could go
wrong though. If you point it to RW memory it could start the thread with that
as a shadow stack and just blow up at the first call. It might be nicer to fail
earlier though.
> +
> + /* This should really be an atomic cmpxchg. It is not. */
> + if (access_remote_vm(mm, addr, &val, sizeof(val),
> + FOLL_FORCE) != sizeof(val))
> + goto out;
> +
> + if (val != expected)
> + goto out;
> + val = 0;
After a token is consumed normally, it doesn't set it to zero. Instead it sets
it to a "previous-ssp token". I don't think we actually want to do that here
though because it involves the old SSP, which doesn't really apply in this case.
I don't see any problem with zero, but was there any special thinking behind it?
> + if (access_remote_vm(mm, addr, &val, sizeof(val),
> + FOLL_FORCE | FOLL_WRITE) != sizeof(val))
> + goto out;
The GUPs still seem a bit unfortunate for a couple reasons:
- We could do a CMPXCHG version and are just not (I see ARM has identical code
in gcs_consume_token()). It's not the only race like this though FWIW.
- I *think* this is the only unprivileged FOLL_FORCE that can write to the
current process in the kernel. As is, it could be used on normal RO mappings, at
least in a limited way. Maybe another point for the VMA check. We'd want to
check that it is normal shadow stack?
- Lingering doubts about the wisdom of doing GUPs during task creation.
I don't think they are show stoppers, but the VMA check would be nice to have in
the first upstream support.
> +
> + ret = 0;
> +
> +out:
> + mmput(mm);
> + return ret;
> +}
> +
>
[snip]
>
>
> +static void shstk_post_fork(struct task_struct *p,
> + struct kernel_clone_args *args)
> +{
> + if (!IS_ENABLED(CONFIG_ARCH_HAS_USER_SHADOW_STACK))
> + return;
> +
> + if (!args->shadow_stack)
> + return;
> +
> + if (arch_shstk_post_fork(p, args) != 0)
> + force_sig_fault_to_task(SIGSEGV, SEGV_CPERR, NULL, p);
> +}
> +
Hmm, is this forcing the signal on the new task, which is set up on a user
provided shadow stack that failed the token check? It would handle the signal
with an arbitrary SSP then I think. We should probably fail the clone call in
the parent instead, which can be done by doing the work in copy_process(). Do
you see a problem with doing it at the end of copy_process()? I don't know if
there could be ordering constraints.
^ permalink raw reply
* Re: [PATCH RFT v8 4/9] fork: Add shadow stack support to clone3()
From: Mark Brown @ 2024-08-14 13:20 UTC (permalink / raw)
To: Catalin Marinas
Cc: Rick P. Edgecombe, Deepak Gupta, Szabolcs Nagy, H.J. Lu,
Florian Weimer, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, x86, H. Peter Anvin, Peter Zijlstra, Juri Lelli,
Vincent Guittot, Dietmar Eggemann, Steven Rostedt, Ben Segall,
Mel Gorman, Valentin Schneider, Christian Brauner, Shuah Khan,
linux-kernel, Will Deacon, jannh, linux-kselftest, linux-api,
Kees Cook
In-Reply-To: <Zrx7Lj09b99ozgAE@arm.com>
[-- Attachment #1: Type: text/plain, Size: 1229 bytes --]
On Wed, Aug 14, 2024 at 10:38:54AM +0100, Catalin Marinas wrote:
> On Tue, Aug 13, 2024 at 07:58:26PM +0100, Mark Brown wrote:
> > ISTR the concerns were around someone being clever with vfork() but I
> > don't remember anything super concrete. In terms of the inconsistency
> > here that was actually another thing that came up - if userspace
> > specifies a stack for clone3() it'll just get used even with CLONE_VFORK
> > so it seemed to make sense to do the same thing for the shadow stack.
> > This was part of the thinking when we were looking at it, if you can
> > specify a regular stack you should be able to specify a shadow stack.
> Yes, I agree. But by this logic, I was wondering why the current clone()
> behaviour does not allocate a shadow stack when a new stack is
> requested with CLONE_VFORK. That's rather theoretical though and we may
> not want to change the ABI.
The default for vfork() is to reuse both the normal and shadow stacks,
clone3() does make it all much more flexible. All the shadow stack
ABI predates clone3(), even if it ended up getting merged after.
> Anyway, I understood this patch now and the ABI decisions. FWIW:
> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Thanks!
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCH RFT v8 3/9] mm: Introduce ARCH_HAS_USER_SHADOW_STACK
From: Catalin Marinas @ 2024-08-14 10:41 UTC (permalink / raw)
To: Mark Brown
Cc: Rick P. Edgecombe, Deepak Gupta, Szabolcs Nagy, H.J. Lu,
Florian Weimer, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, x86, H. Peter Anvin, Peter Zijlstra, Juri Lelli,
Vincent Guittot, Dietmar Eggemann, Steven Rostedt, Ben Segall,
Mel Gorman, Valentin Schneider, Christian Brauner, Shuah Khan,
linux-kernel, Will Deacon, jannh, linux-kselftest, linux-api,
Kees Cook, David Hildenbrand
In-Reply-To: <20240808-clone3-shadow-stack-v8-3-0acf37caf14c@kernel.org>
On Thu, Aug 08, 2024 at 09:15:24AM +0100, Mark Brown wrote:
> Since multiple architectures have support for shadow stacks and we need to
> select support for this feature in several places in the generic code
> provide a generic config option that the architectures can select.
>
> Suggested-by: David Hildenbrand <david@redhat.com>
> Acked-by: David Hildenbrand <david@redhat.com>
> Reviewed-by: Deepak Gupta <debug@rivosinc.com>
> Reviewed-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
> Signed-off-by: Mark Brown <broonie@kernel.org>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
^ permalink raw reply
* Re: [PATCH RFT v8 1/9] Documentation: userspace-api: Add shadow stack API documentation
From: Catalin Marinas @ 2024-08-14 10:40 UTC (permalink / raw)
To: Mark Brown
Cc: Rick P. Edgecombe, Deepak Gupta, Szabolcs Nagy, H.J. Lu,
Florian Weimer, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, x86, H. Peter Anvin, Peter Zijlstra, Juri Lelli,
Vincent Guittot, Dietmar Eggemann, Steven Rostedt, Ben Segall,
Mel Gorman, Valentin Schneider, Christian Brauner, Shuah Khan,
linux-kernel, Will Deacon, jannh, linux-kselftest, linux-api,
Kees Cook
In-Reply-To: <20240808-clone3-shadow-stack-v8-1-0acf37caf14c@kernel.org>
On Thu, Aug 08, 2024 at 09:15:22AM +0100, Mark Brown wrote:
> There are a number of architectures with shadow stack features which we are
> presenting to userspace with as consistent an API as we can (though there
> are some architecture specifics). Especially given that there are some
> important considerations for userspace code interacting directly with the
> feature let's provide some documentation covering the common aspects.
>
> Signed-off-by: Mark Brown <broonie@kernel.org>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
^ permalink raw reply
* Re: [PATCH RFT v8 4/9] fork: Add shadow stack support to clone3()
From: Catalin Marinas @ 2024-08-14 9:38 UTC (permalink / raw)
To: Mark Brown
Cc: Rick P. Edgecombe, Deepak Gupta, Szabolcs Nagy, H.J. Lu,
Florian Weimer, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, x86, H. Peter Anvin, Peter Zijlstra, Juri Lelli,
Vincent Guittot, Dietmar Eggemann, Steven Rostedt, Ben Segall,
Mel Gorman, Valentin Schneider, Christian Brauner, Shuah Khan,
linux-kernel, Will Deacon, jannh, linux-kselftest, linux-api,
Kees Cook
In-Reply-To: <e24a93cb-e7ba-4046-a7c6-fe2ea12420e3@sirena.org.uk>
On Tue, Aug 13, 2024 at 07:58:26PM +0100, Mark Brown wrote:
> On Tue, Aug 13, 2024 at 05:25:47PM +0100, Catalin Marinas wrote:
> > However, the x86 would be slightly inconsistent here between clone() and
> > clone3(). I guess it depends how you look at it. The classic clone()
> > syscall, if one doesn't pass CLONE_VM but does set new stack, there's no
> > new shadow stack allocated which I'd expect since it's a new stack.
> > Well, I doubt anyone cares about this scenario. Are there real cases of
> > !CLONE_VM but with a new stack?
>
> ISTR the concerns were around someone being clever with vfork() but I
> don't remember anything super concrete. In terms of the inconsistency
> here that was actually another thing that came up - if userspace
> specifies a stack for clone3() it'll just get used even with CLONE_VFORK
> so it seemed to make sense to do the same thing for the shadow stack.
> This was part of the thinking when we were looking at it, if you can
> specify a regular stack you should be able to specify a shadow stack.
Yes, I agree. But by this logic, I was wondering why the current clone()
behaviour does not allocate a shadow stack when a new stack is
requested with CLONE_VFORK. That's rather theoretical though and we may
not want to change the ABI.
> > > > I'm confused that we need to consume the token here. I could not find
> > > > the default shadow stack allocation doing this, only setting it via
> > > > create_rstor_token() (or I did not search enough). In the default case,
>
> > > As discussed for a couple of previous versions if we don't have the
> > > token and userspace can specify any old shadow stack page as the shadow
> > > stack this allows clone3() to be used to overwrite the shadow stack of
> > > another thread, you can point to a shadow stack page which is currently
>
> > IIUC, the kernel-allocated shadow stack will have the token always set
> > while the user-allocated one will be cleared. I was looking to
>
> No, when the kernel allocates we don't bother with tokens at all. We
> only look for and clear a token with the user specified shadow stack.
Ah, you are right, I misread the alloc_shstk() function. It takes a
set_res_tok parameter which is false for the normal allocation.
> > I guess I was rather questioning the current choices than the new
> > clone3() ABI. But even for the new clone3() ABI, does it make sense to
> > set up a shadow stack if the current stack isn't changed? We'll end up
> > with a lot of possible combinations that will never get tested but
> > potentially become obscure ABI. Limiting the options to the sane choices
> > only helps with validation and unsurprising changes later on.
>
> OTOH if we add the restrictions it's more code (and more test code) to
> check, and thinking about if we've missed some important use case. Not
> that it's a *huge* amount of code, like I say I'd not be too unhappy
> with adding a restriction on having a regular stack specified in order
> to specify a shadow stack.
I guess we just follow the normal stack behaviour for clone3(), at least
we'd be consistent with that.
Anyway, I understood this patch now and the ABI decisions. FWIW:
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
^ permalink raw reply
* Re: [PATCH RFT v8 4/9] fork: Add shadow stack support to clone3()
From: Mark Brown @ 2024-08-13 18:58 UTC (permalink / raw)
To: Catalin Marinas
Cc: Rick P. Edgecombe, Deepak Gupta, Szabolcs Nagy, H.J. Lu,
Florian Weimer, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, x86, H. Peter Anvin, Peter Zijlstra, Juri Lelli,
Vincent Guittot, Dietmar Eggemann, Steven Rostedt, Ben Segall,
Mel Gorman, Valentin Schneider, Christian Brauner, Shuah Khan,
linux-kernel, Will Deacon, jannh, linux-kselftest, linux-api,
Kees Cook
In-Reply-To: <ZruJCyXDRNhw6U5A@arm.com>
[-- Attachment #1: Type: text/plain, Size: 6382 bytes --]
On Tue, Aug 13, 2024 at 05:25:47PM +0100, Catalin Marinas wrote:
> However, the x86 would be slightly inconsistent here between clone() and
> clone3(). I guess it depends how you look at it. The classic clone()
> syscall, if one doesn't pass CLONE_VM but does set new stack, there's no
> new shadow stack allocated which I'd expect since it's a new stack.
> Well, I doubt anyone cares about this scenario. Are there real cases of
> !CLONE_VM but with a new stack?
ISTR the concerns were around someone being clever with vfork() but I
don't remember anything super concrete. In terms of the inconsistency
here that was actually another thing that came up - if userspace
specifies a stack for clone3() it'll just get used even with CLONE_VFORK
so it seemed to make sense to do the same thing for the shadow stack.
This was part of the thinking when we were looking at it, if you can
specify a regular stack you should be able to specify a shadow stack.
> > > I'm confused that we need to consume the token here. I could not find
> > > the default shadow stack allocation doing this, only setting it via
> > > create_rstor_token() (or I did not search enough). In the default case,
> > As discussed for a couple of previous versions if we don't have the
> > token and userspace can specify any old shadow stack page as the shadow
> > stack this allows clone3() to be used to overwrite the shadow stack of
> > another thread, you can point to a shadow stack page which is currently
> IIUC, the kernel-allocated shadow stack will have the token always set
> while the user-allocated one will be cleared. I was looking to
No, when the kernel allocates we don't bother with tokens at all. We
only look for and clear a token with the user specified shadow stack.
> understand the inconsistency between these two cases in terms of the
> final layout of the new shadow stack: one with the token, the other
> without. I can see the need for checking but maybe start with requiring
> it to be 0 and setting the token before returning, for consistency with
> clone().
The layout should be the same, the shadow stack will point to where the
token would be - the only difference is if we checked to see if there
was a token there. Since we either clear the token on use or allocate a
fresh page in both cases the value there will be 0.
> In the kernel-allocated shadow stack, is the token used for anything? I
> can see it's used for signal delivery and return but I couldn't figure
> out what it is used for in a thread's shadow stack.
For arm64 we place differently formatted tokens there during signal
handling, and a token is placed at the top of the stack as part of the
architected stack pivoting instructions (and a token at the destination
consumed). I believe x86 has the same pivoting behaviour but ICBW. A
user specified shadow stack is handled in a very similar way to what
would happen if the newly created thread immediately pivoted to the
specified stack.
> Also, can one not use the clone3() to point to the clone()-allocated
> shadow stack? Maybe that's unlikely as an app tends to stick to one
> syscall flavour or the other.
A valid token will only be present on an inactive stack. If a thread
pivots away from a kernel allocated stack then another thread could be
started using the original kernel allocated stack, any program doing
this should think carefully about the lifecycle of the kernel allocated
stack but it's possible. If a thread has not pivoted away from it's
stack then there won't be a token at the top of the stack and it won't
be possible to pivot to it.
> > > > + /*
> > > > + * For CLONE_VFORK the child will share the parents
> > > > + * shadow stack. Make sure to clear the internal
> > > > + * tracking of the thread shadow stack so the freeing
> > > > + * logic run for child knows to leave it alone.
> > > > + */
> > > > + if (clone_flags & CLONE_VFORK) {
> > > > + shstk->base = 0;
> > > > + shstk->size = 0;
> > > > + return 0;
> > > > + }
> > > I think we should leave the CLONE_VFORK check on its own independent of
> > > the clone3() arguments. If one passes both CLONE_VFORK and specific
> > > shadow stack address/size, they should be ignored (or maybe return an
> > > error if you want to make it stricter).
> > This is existing logic from the current x86 code that's been reindented
> > due to the addition of explicitly specified shadow stacks, it's not new
> > behaviour. It is needed to stop the child thinking it has the parent's
> > shadow stack in the CLONE_VFORK case.
> I figured that. But similar to the current !CLONE_VM behaviour where no
> new shadow stack is allocated even if a new stack is passed to clone(),
> I was thinking of something similar here for consistency: don't set up a
> shadow stack in the CLONE_VFORK case or at least allow it only if a new
> stack is being set up (if we extend this to clone(), it would be a small
> ABI change).
We could restrict specifying a shadow stack to only be supported when a
regular stack is also specified, if we're doing that I'd prefer to do it
in all cases rather than only for vfork() since that reduces the number
of special cases and we don't restrict normal stacks like that.
> > This is again all existing behaviour for the case where the user has not
> > specified a shadow stack reindented, as mentioned above if the user has
> > specified one explicitly then we just do what we were asked. The
> > existing behaviour is to only create a new shadow stack for the child in
> > the CLONE_VM case and leave the child using the same shadow stack as the
> > parent in the copied mm for !CLONE_VM.
> I guess I was rather questioning the current choices than the new
> clone3() ABI. But even for the new clone3() ABI, does it make sense to
> set up a shadow stack if the current stack isn't changed? We'll end up
> with a lot of possible combinations that will never get tested but
> potentially become obscure ABI. Limiting the options to the sane choices
> only helps with validation and unsurprising changes later on.
OTOH if we add the restrictions it's more code (and more test code) to
check, and thinking about if we've missed some important use case. Not
that it's a *huge* amount of code, like I say I'd not be too unhappy
with adding a restriction on having a regular stack specified in order
to specify a shadow stack.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCH RFT v8 4/9] fork: Add shadow stack support to clone3()
From: Catalin Marinas @ 2024-08-13 16:25 UTC (permalink / raw)
To: Mark Brown
Cc: Rick P. Edgecombe, Deepak Gupta, Szabolcs Nagy, H.J. Lu,
Florian Weimer, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, x86, H. Peter Anvin, Peter Zijlstra, Juri Lelli,
Vincent Guittot, Dietmar Eggemann, Steven Rostedt, Ben Segall,
Mel Gorman, Valentin Schneider, Christian Brauner, Shuah Khan,
linux-kernel, Will Deacon, jannh, linux-kselftest, linux-api,
Kees Cook
In-Reply-To: <Zrag5A5K9pv1K9Uz@finisterre.sirena.org.uk>
On Sat, Aug 10, 2024 at 12:06:12AM +0100, Mark Brown wrote:
> On Fri, Aug 09, 2024 at 07:19:26PM +0100, Catalin Marinas wrote:
> > On Thu, Aug 08, 2024 at 09:15:25AM +0100, Mark Brown wrote:
> > > + /* This should really be an atomic cmpxchg. It is not. */
> > > + if (access_remote_vm(mm, addr, &val, sizeof(val),
> > > + FOLL_FORCE) != sizeof(val))
> > > + goto out;
>
> > If we restrict the shadow stack creation only to the CLONE_VM case, we'd
> > not need the remote vm access, it's in the current mm context already.
> > More on this below.
>
> The discussion in previous iterations was that it seemed better to allow
> even surprising use cases since it simplifies the analysis of what we
> have covered. If the user has specified a shadow stack we just do what
> they asked for and let them worry about if it's useful.
Thanks for the summary of the past discussions, the patch makes more
sense now. I guess it's easier to follow a clone*() syscall where one
can set a new stack pointer even in the !CLONE_VM case. Just let it set
the shadow stack as well with the new ABI.
However, the x86 would be slightly inconsistent here between clone() and
clone3(). I guess it depends how you look at it. The classic clone()
syscall, if one doesn't pass CLONE_VM but does set new stack, there's no
new shadow stack allocated which I'd expect since it's a new stack.
Well, I doubt anyone cares about this scenario. Are there real cases of
!CLONE_VM but with a new stack?
> > > + if (val != expected)
> > > + goto out;
>
> > I'm confused that we need to consume the token here. I could not find
> > the default shadow stack allocation doing this, only setting it via
> > create_rstor_token() (or I did not search enough). In the default case,
> > is the user consuming it? To me the only difference should been the
> > default allocation vs the one passed by the user via clone3(), with the
> > latter maybe requiring the user to set the token initially.
>
> As discussed for a couple of previous versions if we don't have the
> token and userspace can specify any old shadow stack page as the shadow
> stack this allows clone3() to be used to overwrite the shadow stack of
> another thread, you can point to a shadow stack page which is currently
> in use and then run some code that causes shadow stack writes. This
> could potentially then in turn be used as part of a bigger exploit
> chain, probably it's hard to get anything beyond just causing the other
> thread to fault but won't be impossible.
>
> With a kernel allocated shadow stack this is not an issue since we are
> placing the shadow stack in new memory, userspace can't control where we
> place it so it can't overwrite an existing shadow stack.
IIUC, the kernel-allocated shadow stack will have the token always set
while the user-allocated one will be cleared. I was looking to
understand the inconsistency between these two cases in terms of the
final layout of the new shadow stack: one with the token, the other
without. I can see the need for checking but maybe start with requiring
it to be 0 and setting the token before returning, for consistency with
clone().
In the kernel-allocated shadow stack, is the token used for anything? I
can see it's used for signal delivery and return but I couldn't figure
out what it is used for in a thread's shadow stack.
Also, can one not use the clone3() to point to the clone()-allocated
shadow stack? Maybe that's unlikely as an app tends to stick to one
syscall flavour or the other.
> > > + /*
> > > + * For CLONE_VFORK the child will share the parents
> > > + * shadow stack. Make sure to clear the internal
> > > + * tracking of the thread shadow stack so the freeing
> > > + * logic run for child knows to leave it alone.
> > > + */
> > > + if (clone_flags & CLONE_VFORK) {
> > > + shstk->base = 0;
> > > + shstk->size = 0;
> > > + return 0;
> > > + }
>
> > I think we should leave the CLONE_VFORK check on its own independent of
> > the clone3() arguments. If one passes both CLONE_VFORK and specific
> > shadow stack address/size, they should be ignored (or maybe return an
> > error if you want to make it stricter).
>
> This is existing logic from the current x86 code that's been reindented
> due to the addition of explicitly specified shadow stacks, it's not new
> behaviour. It is needed to stop the child thinking it has the parent's
> shadow stack in the CLONE_VFORK case.
I figured that. But similar to the current !CLONE_VM behaviour where no
new shadow stack is allocated even if a new stack is passed to clone(),
I was thinking of something similar here for consistency: don't set up a
shadow stack in the CLONE_VFORK case or at least allow it only if a new
stack is being set up (if we extend this to clone(), it would be a small
ABI change).
> > > - /*
> > > - * For !CLONE_VM the child will use a copy of the parents shadow
> > > - * stack.
> > > - */
> > > - if (!(clone_flags & CLONE_VM))
> > > - return 0;
> > > + /*
> > > + * For !CLONE_VM the child will use a copy of the
> > > + * parents shadow stack.
> > > + */
> > > + if (!(clone_flags & CLONE_VM))
> > > + return 0;
>
> > Is the !CLONE_VM case specific only to the default shadow stack
> > allocation? Sorry if this has been discussed already (or I completely
> > forgot) but I thought we'd only implement this for the thread creation
> > case. The typical fork() for a new process should inherit the parent's
> > layout, so applicable to the clone3() with the shadow stack arguments as
> > well (which should be ignored or maybe return an error with !CLONE_VM).
>
> This is again all existing behaviour for the case where the user has not
> specified a shadow stack reindented, as mentioned above if the user has
> specified one explicitly then we just do what we were asked. The
> existing behaviour is to only create a new shadow stack for the child in
> the CLONE_VM case and leave the child using the same shadow stack as the
> parent in the copied mm for !CLONE_VM.
I guess I was rather questioning the current choices than the new
clone3() ABI. But even for the new clone3() ABI, does it make sense to
set up a shadow stack if the current stack isn't changed? We'll end up
with a lot of possible combinations that will never get tested but
potentially become obscure ABI. Limiting the options to the sane choices
only helps with validation and unsurprising changes later on.
> > > @@ -2790,6 +2808,8 @@ pid_t kernel_clone(struct kernel_clone_args *args)
> > > */
> > > trace_sched_process_fork(current, p);
> > >
> > > + shstk_post_fork(p, args);
>
> > Do we need this post fork call? Can we not handle the setup via the
> > copy_thread() path in shstk_alloc_thread_stack()?
>
> It looks like we do actually have the new mm in the process before we
> call copy_thread() so we could move things into there though we'd loose
> a small bit of factoring out of the error handling (at one point I had
> more code factored out but right now it's quite small, looking again we
> could also factor out the get_task_mm()/mput()). ISTR having the new
> process' mm was the biggest reason for this initially but looking again
> I'm not sure why that was. It does still feel like even the small
> amount that's factored out currently is useful though, a bit less
> duplication in the architecture code which feels welcome here.
I think you can probably keep this. My comment was based on the
assumption that we only support the CLONE_VM case where we wouldn't need
the access_remote_vm(), just some direct write similar to
write_user_shstk_64().
I still think we should have limited this ABI to the CLONE_VM and
!CLONE_VFORK cases but I don't have a strong view if the consensus was
to allow it for classic fork() and vfork() like uses (I just think they
won't be used).
--
Catalin
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox