mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Nickolai Zeldovich <nickolai@csail.mit.edu>
To: Oleg Nesterov <oleg@redhat.com>, Christian Brauner <brauner@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>,
	linux-kernel@vger.kernel.org,
	Nickolai Zeldovich <nickolai@csail.mit.edu>
Subject: [PATCH] exit: fix lost-update race on the child_subreaper bitfields
Date: Fri,  9 Oct 2026 18:24:04 -0400	[thread overview]
Message-ID: <20261009222404.760787-1-nickolai@csail.mit.edu> (raw)

is_child_subreaper, has_child_subreaper and autoreap are 1-bit fields
that share one word of struct signal_struct.  A store to any of them is
a read-modify-write of the whole word, and two of the stores run
without a common lock:

  - PR_SET_CHILD_SUBREAPER writes me->signal->is_child_subreaper with
    no lock held.

  - propagate_has_child_subreaper(), run by walk_process_tree() from
    the same prctl in an ancestor, writes p->signal->has_child_subreaper
    of every descendant p under read_lock(&tasklist_lock), which does
    not exclude the unlocked writer.

When a process calls prctl(PR_SET_CHILD_SUBREAPER, 1) while an
ancestor's PR_SET_CHILD_SUBREAPER walk visits it, the two
read-modify-write sequences interleave and one of the bits is silently
lost:

  - If has_child_subreaper is lost, the process's orphaned descendants
    are reparented straight to init when it exits: find_new_reaper()
    tests father->signal->has_child_subreaper first and never looks for
    the ancestor subreaper.  The service manager that registered as the
    subreaper never gets SIGCHLD for them and cannot wait() on them.

  - If is_child_subreaper is lost, the prctl returned 0 but the process
    is not a subreaper: orphans of its descendants skip it and are
    reparented to the next subreaper up or to init.
    PR_GET_CHILD_SUBREAPER reads back 0.

Documentation/memory-barriers.txt requires all fields of one bitfield
to be protected by one lock for exactly this reason.  No lock is taken
or documented for these flags, and the prctl needs no privilege, so any
process can hit the race against its own ancestors or descendants.

Make the three flags separate bool members.  Each store then has its
own memory location and no read-modify-write of a neighbour.  The
readers and their locking are unchanged.  autoreap is only written to
a not yet published signal_struct in copy_process() and is not racy by
itself, but it shares the word and is converted with the other two.

Fixes: 749860ce2427 ("prctl: propagate has_child_subreaper flag to every descendant")
Signed-off-by: Nickolai Zeldovich <nickolai@csail.mit.edu>
---
 include/linux/sched/signal.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h
index d45a5476b..f7266dd2e 100644
--- a/include/linux/sched/signal.h
+++ b/include/linux/sched/signal.h
@@ -130,9 +130,9 @@ struct signal_struct {
 	 * process will inherit a flag if they should look for a
 	 * child_subreaper process at exit.
 	 */
-	unsigned int		is_child_subreaper:1;
-	unsigned int		has_child_subreaper:1;
-	unsigned int		autoreap:1;
+	bool			is_child_subreaper;
+	bool			has_child_subreaper;
+	bool			autoreap;
 
 #ifdef CONFIG_POSIX_TIMERS
 

base-commit: fc1c25014ff8e416d75e8a5ba3b9c0ba5eb8e877
-- 
2.56.0


             reply	other threads:[~2026-10-09 22:24 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-09 22:24 Nickolai Zeldovich [this message]
2026-10-11 12:09 ` Oleg Nesterov
2026-10-11 12:34   ` Nickolai Zeldovich
2026-10-11 12:34   ` [PATCH v2] " Nickolai Zeldovich
2026-10-11 14:24     ` Oleg Nesterov
2026-10-12  8:39     ` Christian Brauner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261009222404.760787-1-nickolai@csail.mit.edu \
    --to=nickolai@csail.mit.edu \
    --cc=akpm@linux-foundation.org \
    --cc=brauner@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=oleg@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®