[caif_serial] Question: ldisc_close() drops tty ref but keeps ser->tty published
From: Bai, Shuangpeng <hidden>
Date: 2026-01-11 23:00:46
Hi netdev/TTY maintainers,
I am looking at drivers/net/caif/caif_serial.c: ldisc_close():
static void ldisc_close(struct tty_struct *tty)
{
struct ser_device *ser = tty->disc_data;
tty_kref_put(ser->tty);
spin_lock(&ser_lock);
list_move(&ser->node, &ser_release_list);
spin_unlock(&ser_lock);
schedule_work(&ser_release_work);
}
In ldisc_open(), ser->tty is set by taking a reference:
ser->tty = tty_kref_get(tty);
In ldisc_close(), tty_kref_put(ser->tty) drops the tty reference while
ser->tty remains published. This can create a window where other CPUs may
still observe a non-NULL ser->tty pointer after the reference has been
dropped, which could be unsafe under concurrency if any reader
dereferences ser->tty without first taking its own reference.
In addition, the ser object itself is released asynchronously via
ser_release_work, so the struct (and thus ser->tty) can remain accessible
for a relatively long time after ldisc_close(). This extends the lifetime
of the published stale pointer and widens the potential race window.
Would it make sense to clear/unpublish ser->tty in ldisc_close(), so that
other CPUs will not observe a non-NULL ser->tty after the reference has
been dropped?
Thanks,
Shuangpeng Bai