Re: [RFC PATCH 12/24] fork: let kernel callers create embryonic tasks
From: Andy Lutomirski
Date: Thu Jul 16 2026 - 12:22:22 EST
On Thu, Jul 16, 2026 at 8:52 AM Li Chen <me@linux.beauty> wrote:
>
> A kernel-created task can become visible before it has installed a new
> executable image or a valid userspace register frame. Exposing such a task
> through ptrace can disclose kernel setup state.
>
> Add a task-local embryonic flag and an internal clone argument for callers
> that need this lifecycle. Reject ptrace access until the creator clears the
> flag. Clear it with release ordering and observe it with acquire ordering.
> This orders visibility of the completed exec state with the transition.
>
> Existing fork, vfork, clone, and kernel-thread callers leave the argument
> unset and retain their current behavior.
>
> --- a/kernel/ptrace.c
> +++ b/kernel/ptrace.c
> @@ -56,6 +56,8 @@ bool ptracer_access_allowed(struct task_struct *tsk)
> guard(rcu)();
> if (ptrace_parent(tsk) != current)
> return false;
> + if (task_is_embryonic_exec(tsk))
> + return false;
> es = task_exec_state_rcu(tsk);
> return READ_ONCE(es->dumpable) == TASK_DUMPABLE_OWNER ||
> ptracer_capable(tsk, es->user_ns);
> @@ -312,6 +314,8 @@ static int __ptrace_may_access(struct task_struct *task, unsigned int mode)
> WARN(1, "denying ptrace access check without PTRACE_MODE_*CREDS\n");
> return -EPERM;
> }
> + if (task_is_embryonic_exec(task))
> + return -EPERM;
Would it be better to use a different error code? -ECONNREFUSED?
After all, this isn't a permission failure per se.
There's a not-locally-obvious gotcha here: reading other process
attributes prior to calling task_is_embryonic_exec may result in
(security-relevant!) data races. This should at least be documented
-- it's critical to check task_is_embryonic_exec *before* trying to
read credentials. Also, I think /proc and many pidfd APIs have the
same issue.
--Andy