Re: [patch V2 1/8] signal: Prevent exec() race
From: Peter Zijlstra
Date: Wed Sep 09 2026 - 08:58:13 EST
On Wed, Sep 09, 2026 at 02:45:55PM +0200, Peter Zijlstra wrote:
> On Wed, Sep 09, 2026 at 02:13:11PM +0200, Frederic Weisbecker wrote:
> > Because the following doesn't verify that:
> > ---
> > C MP+farfetched
> >
> > {}
> >
> > P0(int *next, int *prev, int *exit_state, spinlock_t *tasklist_lock)
> > {
> > // list_del_init()
> > WRITE_ONCE(*next, 1);
> > WRITE_ONCE(*prev, 1);
> > // exit_notify()
> > spin_lock(tasklist_lock);
> > WRITE_ONCE(*exit_state, 1);
> > spin_unlock(tasklist_lock);
> > }
> >
> > P1(int *exit_state, int *pid, spinlock_t *tasklist_lock)
> > {
> > int r0;
> >
> > // de_thread()
> > spin_lock(tasklist_lock);
> > r0 = READ_ONCE(*exit_state);
> > if (r0 == 1) {
> > // exchange_tids()
> > WRITE_ONCE(*pid, 1);
> > }
> > spin_unlock(tasklist_lock);
> > }
> >
> > P2(int *next, int *prev, int *pid, spinlock_t *sighand)
> > {
> > int r0;
> > int r1;
> > // get target
> > r0 = READ_ONCE(*pid);
> > spin_lock(sighand);
There is no dependency between r0 and sighand. While I think there is in
posixtimer_send_sigqueue(). Does making it smp_load_acquire() help?
> > // queue signal
> > r1 = READ_ONCE(*next);
> > if (r1 == 0)
> > WRITE_ONCE(*prev, 2);
> > spin_unlock(sighand);
> > }
> >
> > exists (prev=1 /\ 2:r0=1) (* Bad outcome. *)