public inbox for linux-security-module@vger.kernel.org
 help / color / mirror / Atom feed
From: "Günther Noack" <gnoack3000@gmail.com>
To: "Günther Noack" <gnoack@google.com>
Cc: "Yihan Ding" <dingyihan@uniontech.com>,
	"Mickaël Salaün" <mic@digikod.net>,
	"Paul Moore" <paul@paul-moore.com>,
	"Jann Horn" <jannh@google.com>,
	linux-security-module@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	syzbot+7ea2f5e9dfd468201817@syzkaller.appspotmail.com
Subject: Re: [PATCH v2 1/2] landlock: Serialize TSYNC thread restriction
Date: Wed, 25 Feb 2026 23:33:39 +0100	[thread overview]
Message-ID: <20260225.42330125301c@gnoack.org> (raw)
In-Reply-To: <aZ7l6jU7XJ1BYbN-@google.com>

On Wed, Feb 25, 2026 at 01:07:26PM +0100, Günther Noack wrote:
> On Wed, Feb 25, 2026 at 10:47:33AM +0800, Yihan Ding wrote:
> > syzbot found a deadlock in landlock_restrict_sibling_threads().
> > When multiple threads concurrently call landlock_restrict_self() with
> > sibling thread restriction enabled, they can deadlock by mutually
> > queueing task_works on each other and then blocking in kernel space
> > (waiting for the other to finish).
> > 
> > Fix this by serializing the TSYNC operations within the same process
> > using the exec_update_lock. This prevents concurrent invocations
> > from deadlocking. We use down_write_killable() to ensure the thread
> > remains responsive to fatal signals while waiting for the lock.
> > 
> > Fixes: 42fc7e6543f6 ("landlock: Multithreading support for landlock_restrict_self()")
> > Reported-by: syzbot+7ea2f5e9dfd468201817@syzkaller.appspotmail.com
> > Closes: https://syzkaller.appspot.com/bug?extid=7ea2f5e9dfd468201817
> > Suggested-by: Günther Noack <gnoack3000@gmail.com>
> > Signed-off-by: Yihan Ding <dingyihan@uniontech.com>
> > ---
> >  security/landlock/tsync.c | 8 ++++++++
> >  1 file changed, 8 insertions(+)
> > 
> > diff --git a/security/landlock/tsync.c b/security/landlock/tsync.c
> > index de01aa899751..420fcfc2fe9a 100644
> > --- a/security/landlock/tsync.c
> > +++ b/security/landlock/tsync.c
> > @@ -447,6 +447,13 @@ int landlock_restrict_sibling_threads(const struct cred *old_cred,
> >  	shared_ctx.new_cred = new_cred;
> >  	shared_ctx.set_no_new_privs = task_no_new_privs(current);
> >  
> > +	/*
> > +	 * Serialize concurrent TSYNC operations to prevent deadlocks
> > +	 * when multiple threads call landlock_restrict_self() simultaneously.
> > +	 */
> > +	if (down_write_killable(&current->signal->exec_update_lock))
> > +		return -EINTR;
> > +
> >  	/*
> >  	 * We schedule a pseudo-signal task_work for each of the calling task's
> >  	 * sibling threads.  In the task work, each thread:
> > @@ -556,6 +563,7 @@ int landlock_restrict_sibling_threads(const struct cred *old_cred,
> >  		wait_for_completion(&shared_ctx.all_finished);
> >  
> >  	tsync_works_release(&works);
> > +	up_write(&current->signal->exec_update_lock);
> >  
> >  	return atomic_read(&shared_ctx.preparation_error);
> >  }
> > -- 
> > 2.51.0
> > 
> 
> Thank you!
> 
> Reviewed-by: Günther Noack <gnoack@google.com>

Hello Yihan Ding!

Apologies, I have to take this back -- applying the patch in this form
would be a mistake.  When I tried this out with the Syzkaller test
case, I noticed that the tests started taking multiple seconds per
run.  The way I reproduced it was by running the Syzkaller reproducer
under Qemu and looking for the frequency of the "executing program"
lines that it prints for each test run.

When I looked deeper, what was happening was actually that we got
ourselves into a deadlock again, which, in hindsight should have been
obvious: When two threads call landlock_restrict_self() roughly at the
same time, then the one that grabs the lock first will (a) keep the
other (killably) blocked on the lock acquisition, and (b) later ask
the other thread to run a task work.  But in order to run a task work,
the blocked thread must first return from the syscall.  However,
down_write_killable() only returns when either the lock is available
or when the thread was killed.

To resolve this, we need to actually use a lock acquisition that
respects other ways of interruption as well; we can either use a
down_write_trylock() and return -ERESTARTNOINTR, or we can use
down_write_interruptible().

Sorry for the poor advice to use the _killable variant earlier.  Could
I ask you to please send another revision using _trylock() or
_interruptible()?

Thanks,
–Günther

  reply	other threads:[~2026-02-25 22:33 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-25  2:47 [PATCH v2 0/2] landlock: Fix TSYNC deadlock and clean up error path Yihan Ding
2026-02-25  2:47 ` [PATCH v2 1/2] landlock: Serialize TSYNC thread restriction Yihan Ding
2026-02-25 12:07   ` Günther Noack
2026-02-25 22:33     ` Günther Noack [this message]
2026-02-26  1:43       ` Ding Yihan
2026-02-25  2:47 ` [PATCH v2 2/2] landlock: Clean up interrupted thread logic in TSYNC Yihan Ding
2026-02-25 12:09   ` Günther Noack

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=20260225.42330125301c@gnoack.org \
    --to=gnoack3000@gmail.com \
    --cc=dingyihan@uniontech.com \
    --cc=gnoack@google.com \
    --cc=jannh@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=mic@digikod.net \
    --cc=paul@paul-moore.com \
    --cc=syzbot+7ea2f5e9dfd468201817@syzkaller.appspotmail.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