From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: Xin Chen <quic_cxin@quicinc.com>
Cc: Rob Herring <robh@kernel.org>, Jiri Slaby <jirislaby@kernel.org>,
linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org,
liulzhao@qti.qualcomm.com, quic_chejiang@quicinc.com,
zaiyongc@qti.qualcomm.com, quic_zijuhu@quicinc.com,
quic_mohamull@quicinc.com,
Panicker Harish <quic_pharish@quicinc.com>
Subject: Re: [PATCH v1] tty: serdev: serdev-ttyport: Fix use-after-free in ttyport_close() due to uninitialized serport->tty
Date: Sat, 31 May 2025 09:16:04 +0200 [thread overview]
Message-ID: <2025053116-improvise-silk-968a@gregkh> (raw)
In-Reply-To: <7d656b7e-3e7b-4357-80c3-24ab597bdcee@quicinc.com>
On Fri, May 30, 2025 at 04:11:20PM +0800, Xin Chen wrote:
>
>
> On 5/29/2025 5:07 PM, Greg Kroah-Hartman wrote:
> > On Fri, May 23, 2025 at 10:52:27AM +0800, Xin Chen wrote:
> >>
> >>
> >> On 5/14/2025 5:14 PM, Xin Chen wrote:
> >>>
> >>>
> >>> On 5/8/2025 5:41 PM, Greg Kroah-Hartman wrote:
> >>>> On Thu, May 08, 2025 at 05:29:18PM +0800, Xin Chen wrote:
> >>>>>
> >>>>> On 4/30/2025 7:40 PM, Greg Kroah-Hartman wrote:
> >>>>>> On Wed, Apr 30, 2025 at 07:16:17PM +0800, Xin Chen wrote:
> >>>>>>> When ttyport_open() fails to initialize a tty device, serport->tty is not
> >>>>>>> --- a/drivers/tty/serdev/serdev-ttyport.c
> >>>>>>> +++ b/drivers/tty/serdev/serdev-ttyport.c
> >>>>>>> @@ -88,6 +88,10 @@ static void ttyport_write_flush(struct serdev_controller *ctrl)
> >>>>>>> {
> >>>>>>> struct serport *serport = serdev_controller_get_drvdata(ctrl);
> >>>>>>> struct tty_struct *tty = serport->tty;
> >>>>>>> + if (!tty) {
> >>>>>>> + dev_err(&ctrl->dev, "tty is null\n");
> >>>>>>> + return;
> >>>>>>> + }
> >>>>>>
> >>>>>> What prevents tty from going NULL right after you just checked this?
> >>>>>
> >>>>> First sorry for reply so late for I have a long statutory holidays.
> >>>>> Maybe I don't get your point. From my side, there is nothing to prevent it.
> >>>>> Check here is to avoid code go on if tty is NULL.
> >>>>
> >>>> Yes, but the problem is, serport->tty could change to be NULL right
> >>>> after you check it, so you have not removed the real race that can
> >>>> happen here. There is no lock, so by adding this check you are only
> >>>> reducing the risk of the problem happening, not actually fixing the
> >>>> issue so that it will never happen.
> >>>>
> >>>> Please fix it so that this can never happen.
> >>>>
> >>>
> >>> Actually I have never thought the race condition issue since the crash I met is
> >>> not caused by race condition. It's caused due to Bluetooth driver call
> >>> ttyport_close() after ttyport_open() failed. This two action happen one after
> >>> another in one thread and it seems impossible to have race condition. And with
> >>> my fix the crash doesn't happen again in several test of same case.
> >>>
> >>> Let me introduce the complete process for you:
> >>> 1) hci_dev_open_sync()->
> >>> hci_dev_init_sync()->hci_dev_setup_sync()->hdev->setup()(hci_uart_setup)->qca_setup(),
> >>> here in qca_setup(), qca_read_soc_version() fails and goto out, then calls
> >>> serdev_device_close() to close tty normally. And then call serdev_device_open()
> >>> to retry.
> >>> 2) serdev_device_open() fails due to tty_init_dev() fails, then tty gets
> >>> released, which means this time the tty has been freed succesfully.
> >>> 3) Return back to upper func hci_dev_open_sync(),
> >>> hdev->close()(hci_uart_close) is called. And hci_uart_close calls
> >>> hci_uart_flush() and serdev_device_close(). serdev_device_close() tries to close
> >>> tty again, it's calltrace is serdev_device_close()->ttyport_close()->tty_lock(),
> >>> tty_unlock(), tty_release_struct(). The four funcs hci_uart_flush(), tty_lock(),
> >>> tty_unlock(), tty_release_struct() read tty pointer's value, which is invalid
> >>> and causes crash.
> >>>
> >>
> >> Hi Greg, could you please take some time to review my reply?
> >
> > I am not disputing the fact that there is a bug here, I'm just saying
> > that you can't test for a value and then act on it without a lock
> > protecting that action because the value can be changed right after you
> > test for it.
> >
> > You might not see this in your testing, as you have narrowed the window
> > that the value can change, but you have not solved the issue properly,
> > right?
> >
> > thanks,
> >
> > greg k-h
>
> >From my analysis, I think there is only one thread operating the tty of
> Bluetooth. So the case of tty changed after check will not happen.
This might be the case for your specific system, but how can you
guarantee this is the case for all serdev users?
Hint, the way you _CAN_ guarantee it is to use a lock...
{sigh}
greg k-h
prev parent reply other threads:[~2025-05-31 7:16 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-04-30 11:16 [PATCH v1] tty: serdev: serdev-ttyport: Fix use-after-free in ttyport_close() due to uninitialized serport->tty Xin Chen
2025-04-30 11:40 ` Greg Kroah-Hartman
2025-05-08 9:29 ` Xin Chen
2025-05-08 9:41 ` Greg Kroah-Hartman
2025-05-14 9:14 ` Xin Chen
2025-05-23 2:52 ` Xin Chen
2025-05-29 9:07 ` Greg Kroah-Hartman
2025-05-29 9:41 ` Greg Kroah-Hartman
2025-05-30 8:34 ` Xin Chen
2025-05-31 7:20 ` Greg Kroah-Hartman
2025-06-05 8:13 ` Xin Chen
2025-05-30 8:11 ` Xin Chen
2025-05-31 7:16 ` Greg Kroah-Hartman [this message]
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=2025053116-improvise-silk-968a@gregkh \
--to=gregkh@linuxfoundation.org \
--cc=jirislaby@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-serial@vger.kernel.org \
--cc=liulzhao@qti.qualcomm.com \
--cc=quic_chejiang@quicinc.com \
--cc=quic_cxin@quicinc.com \
--cc=quic_mohamull@quicinc.com \
--cc=quic_pharish@quicinc.com \
--cc=quic_zijuhu@quicinc.com \
--cc=robh@kernel.org \
--cc=zaiyongc@qti.qualcomm.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