[DTrace-devel] [PATCH v4] fixup! proc: rip out waitfd() and hit waitpidding thread with a signal instead
Kris Van Hees
kris.van.hees at oracle.com
Wed Oct 25 06:16:44 UTC 2023
On Mon, Oct 23, 2023 at 04:25:06PM +0100, Nick Alcock via DTrace-devel wrote:
> Introduce and use a compiler barrier to prevent use of return_early's
> dereferent from being moved around.
>
> We want this to be right next to the call to waitpid(): if the compiler
> moves it up, it widens a race window, and if it moves it down, it makes it
> useless.
>
> Introduce a compiler barrier to make sure it does neither of these things.
> ---
> include/sys/compiler.h | 4 +++-
> libproc/Pcontrol.c | 2 ++
> 2 files changed, 5 insertions(+), 1 deletion(-)
>
> Spotted over the weekend while compiling DTrace with LTO for the hell of it.
> This fixes an obvious miscompilation in that case (which, admittedly, is a
> case we don't care much about) and seems unlikely to do any harm.
>
> diff --git a/include/sys/compiler.h b/include/sys/compiler.h
> index c3ffccfc0f9e0..82066e5e48d5f 100644
> --- a/include/sys/compiler.h
> +++ b/include/sys/compiler.h
> @@ -1,6 +1,6 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved.
> * Licensed under the Universal Permissive License v 1.0 as shown at
> * http://oss.oracle.com/licenses/upl.
> */
> @@ -38,6 +38,7 @@
> #define _dt_unused_ __attribute__((__unused__))
> #define _dt_noreturn_ __attribute__((__noreturn__))
> #define _dt_unlikely_(x) __builtin_expect((x),0)
> +#define _dt_barrier_(x) __asm__ __volatile__("": :"r"(x):"memory")
>
> #elif defined (__SUNPRO_C)
>
> @@ -45,6 +46,7 @@
> #define _dt_destructor_(x) _Pragma("fini(" #x ")")
> #define _dt_noreturn_
> #define _dt_unlikely_(x) (x)
> +#define _dt_barrier_(x)
>
> /*
> * These are lint comments with no compiler equivalent.
> diff --git a/libproc/Pcontrol.c b/libproc/Pcontrol.c
> index 371b547c5e07b..79bcb5c24d34c 100644
> --- a/libproc/Pcontrol.c
> +++ b/libproc/Pcontrol.c
> @@ -691,11 +691,13 @@ Pwait_internal(struct ps_prochandle *P, boolean_t block, int *return_early)
> * unlock again to minimize the size of the race window in which
> * the signal might hit before waitpid() starts.)
> */
> + _dt_barrier_(*return_early);
> if (return_early && *return_early > 0) {
Um??? So, if return_early is NULL, that barier expression is really going
to pose a problem, right? Like, SEGV? Surely you need to check whether
return_early is NULL before doing the barrier here (and below).
> if (block && waitpid_lock_hook)
> waitpid_lock_hook(P, P->wrap_arg, 0);
> return 0;
> }
> + _dt_barrier_(*return_early);
>
> err = waitpid(P->pid, &status, __WALL | (!block ? WNOHANG : 0));
>
>
> base-commit: cb3a9e81efd9d4fbc413b9427f86af079b5faab6
> prerequisite-patch-id: ce4dfaceb9baa012a354643f839cc413de5fd9d9
> prerequisite-patch-id: b525e5cb144cc160e18531916c8e4bba2666a39a
> --
> 2.42.0.271.g85384428f1
>
>
> _______________________________________________
> DTrace-devel mailing list
> DTrace-devel at oss.oracle.com
> https://oss.oracle.com/mailman/listinfo/dtrace-devel
More information about the DTrace-devel
mailing list