Re: [patch V2 1/8] signal: Prevent exec() race

From: Frederic Weisbecker

Date: Wed Sep 09 2026 - 12:03:04 EST


Le Wed, Sep 09, 2026 at 03:45:36PM +0200, Thomas Gleixner a écrit :
> On Wed, Sep 09 2026 at 14:51, Peter Zijlstra wrote:
> > 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:
> >> > 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?
>
> sighand is r0->sighand->siglock and obviously not known before r0 is
> read. So yes there is a data dependency in reality :)

So unfortunately litmus tests don't support structures. So instead
of transfering the pid, I fake the data dependency by transfering the
sighand directly and then yes it works. I don't know what is the name
of the pattern behind that.

This is not a control dependency as there is no LOAD-cond-store. If
someone can shed some light on this?

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, spinlock_t *tasklist_lock, spinlock_t *sighand, spinlock_t **psighand)
{
int r0;

// de_thread()
spin_lock(tasklist_lock);
r0 = READ_ONCE(*exit_state);
if (r0 == 1) {
// exchange_tids()
WRITE_ONCE(*psighand, sighand);
}
spin_unlock(tasklist_lock);
}

P2(int *next, int *prev, int *pid, spinlock_t *sighand, spinlock_t **psighand)
{
spinlock_t *r0;
int r1;

// get target
r0 = READ_ONCE(*psighand);
spin_lock(r0);
// queue signal
r1 = READ_ONCE(*next);
if (r1 == 1) {
WRITE_ONCE(*prev, 2);
}
spin_unlock(r0);
}

exists (prev=1 /\ 2:r0=sighand) (* Bad outcome. *)
---
herd7 -conf linux-kernel.cfg ~/farfetched.litmus
Test MP+farfetched Allowed
States 3
2:r0=0; [prev]=1;
2:r0=0; [prev]=2;
2:r0=sighand; [prev]=2;
No
Witnesses
Positive: 0 Negative: 7
Condition exists ([prev]=1 /\ 2:r0=sighand)
Observation MP+farfetched Never 0 7