Re: [PATCH] tty: ldisc: fix deadlock between ldisc_sem and rtnl_mutex

Greg KH <[email protected]> Fri, 17 Jul 2026 12:53:14 +0200
Newsgroups org.kernel.vger.linux-can,org.kernel.vger.linux-kernel,org.kernel.vger.linux-serial,org.kernel.vger.netdev
Message-ID <2026071718-yearbook-bloated-48ce@gregkh>
On Thu, Jul 16, 2026 at 02:47:19PM +0800, Yun Zhou wrote:
> syzbot reported a circular lock dependency involving tty ldisc_sem and
> the networking rtnl_mutex. The full chain is:
> 
>   rtnl_mutex --> nft_commit_mutex --> ... --> ep->mtx --> ldisc_sem --> rtnl_mutex
> 
> The last edge (ldisc_sem -> rtnl_mutex) is created because tty line
> discipline .open() callbacks (slcan, slip) call register_netdev() which
> acquires rtnl_mutex, and .open() runs under ldisc_sem write lock in
> tty_set_ldisc().
> 
> Fix by moving the .open() call outside the ldisc_sem write lock. The
> ldisc .open() is initialization of the NEW discipline after the old one
> has been closed - there is no need for ldisc_sem protection at this
> point since:
> 
>  - tty_lock is held throughout, preventing concurrent tty_set_ldisc,
>    hangup, or close
>  - tty->ldisc is set to NULL during the window, so concurrent readers
>    (tty_ldisc_ref, tty_ldisc_ref_wait) see NULL and return immediately,
>    which callers already handle as a hangup condition
>  - tty buffer data stays queued until the ldisc is installed

Ah, but look at the review at:
	https://sashiko.dev/#/patchset/[email protected]
which says:
	Does unlocking the semaphore while the ldisc pointer is NULL introduce a UAPI
	break for concurrent operations?

	If a concurrent process calls read(), write(), or poll() during this unlocked
	window, it can enter tty_ldisc_ref_wait() in drivers/tty/tty_io.c. Because the
	semaphore was unlocked here, tty_ldisc_ref_wait() will successfully acquire
	the read lock but observe tty->ldisc as NULL.

	This causes the reader to immediately return EOF or -EIO, potentially
	aborting userspace applications unexpectedly during a line discipline
	transition.

Is that not true?

thanks,

greg k-h