From: Selvarasu Ganesan <selvarasu.g@samsung.com>
To: 胡连勤 <hulianqin@vivo.com>,
"Mathias Nyman" <mathias.nyman@linux.intel.com>,
"Mathias Nyman" <mathias.nyman@intel.com>,
"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
"quic_wcheng@quicinc.com" <quic_wcheng@quicinc.com>,
"broonie@kernel.org" <broonie@kernel.org>
Cc: "linux-usb@vger.kernel.org" <linux-usb@vger.kernel.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"cpgs@samsung.com" <cpgs@samsung.com>,
"alim.akhtar@samsung.com" <alim.akhtar@samsung.com>,
"thiagu.r@samsung.com" <thiagu.r@samsung.com>
Subject: Re: 答复: 答复: [PATCH] xhci: sideband: check vdev liveness before removing endpoints on unregister
Date: Fri, 11 Sep 2026 14:11:52 +0530 [thread overview]
Message-ID: <937773018.41789116303608.JavaMail.epsvc@epcpadp1new> (raw)
In-Reply-To: <TYUPR06MB6217F0788C14DD89D237C807D2BE2@TYUPR06MB6217.apcprd06.prod.outlook.com>
On 9/11/2026 12:59 PM, 胡连勤 wrote:
> Hi Selva,
>
>>> drivers/usb/host/xhci-mem.c | 8 ++++++++
>>> drivers/usb/host/xhci-sideband.c | 25 ++++++++++++++++++-------
>>> 2 files changed, 26 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
>>> index af8d4b74c4ba..afdcfb38b35f 100644
>>> --- a/drivers/usb/host/xhci-mem.c
>>> +++ b/drivers/usb/host/xhci-mem.c
>>> @@ -922,6 +922,14 @@ void xhci_free_virt_device(struct xhci_hcd *xhci, struct xhci_virt_device *dev,
>>> dev->rhub_port->slot_id = 0;
>>> if (xhci->devs[slot_id] == dev)
>>> xhci->devs[slot_id] = NULL;
>>> +
>>> + if (dev->sideband) {
>>> + xhci_dbg(xhci, "vdev for slot %d has sideband still set at free, clearing dangling pointer\n",
>>> + slot_id);
>>> + dev->sideband->vdev = NULL;
>> Thanks for your updated patch.
>>
>> Dont forget to add #include <linux/usb/xhci-sideband.h> in this
>> xhci-mem.c file otherwise getting below error,
>>
>> drivers/usb/host/xhci-mem.c:928:30: error: invalid use of undefined type
>> ‘struct xhci_sideband’
>> 928 | dev->sideband->vdev = NULL;
>>
> Include the corresponding header file
> #include <linux/dmapool.h>
> #include <linux/dma-mapping.h>
> #include <linux/bitfield.h>
> +#include <linux/usb/xhci-sideband.h>
>
>
>>> + dev->sideband = NULL;
>>> + }
>>> +
>>> kfree(dev);
>>> }
>>>
>>> diff --git a/drivers/usb/host/xhci-sideband.c b/drivers/usb/host/xhci-sideband.c
>>> index a5deeee4d5dc..6312c9e3af65 100644
>>> --- a/drivers/usb/host/xhci-sideband.c
>>> +++ b/drivers/usb/host/xhci-sideband.c
>>> @@ -472,12 +472,22 @@ xhci_sideband_unregister(struct xhci_sideband *sb)
>>>
>>> scoped_guard(mutex, &sb->mutex) {
>>> vdev = sb->vdev;
>>> - if (!vdev)
>>> - return;
>>> -
>>> - for (i = 0; i < EP_CTX_PER_DEV; i++)
>>> - if (sb->eps[i])
>>> - __xhci_sideband_remove_endpoint(sb, sb->eps[i]);
>>> + /*
>>> + * If vdev is NULL, xhci_free_virt_device() has already
>>> + * cleared sb->vdev and freed vdev (e.g. on
>>> + * COMP_USB_TRANSACTION_ERROR during address device
>>> + * recovery). Skip endpoint cleanup as the xHC has already
>>> + * disabled the slot.
>>> + *
>>> + * The interrupter and sideband instance are host-level
>>> + * resources independent of vdev, so still remove and free
>>> + * them to avoid leaks.
>>> + */
>>> + if (vdev) {
>>> + for (i = 0; i < EP_CTX_PER_DEV; i++)
>>> + if (sb->eps[i])
>>> + __xhci_sideband_remove_endpoint(sb, sb->eps[i]);
>> I have one query on skip endpoint cleanup due to vdev is NULL, in this
>> case the pointers in sb->eps are not cleared. Since these pointers point
>> into the virtual device eps, any subsequent call to sideband API
>> functions like xhci_sideband_get_endpoint_buffer() that dereference
>> sb->eps could result in a use after free if the virtual device has been
>> freed. Is it possible?
> Yes, you're absolutely right. If sb->eps[] is not cleared when vdev
> is NULL, subsequent calls to xhci_sideband_get_endpoint_buffer() or
> similar API functions would dereference dangling pointers into the
> freed vdev, resulting in use-after-free.
>
> I added the else branch to clear sb->eps[]:
>
> } else {
> for (i = 0; i < EP_CTX_PER_DEV; i++)
> sb->eps[i] = NULL;
> }
>
>
> The complete code modification is as follows:
> diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
> index af8d4b74c4ba..448d28aaff3e 100644
> --- a/drivers/usb/host/xhci-mem.c
> +++ b/drivers/usb/host/xhci-mem.c
> @@ -15,6 +15,7 @@
> #include <linux/dmapool.h>
> #include <linux/dma-mapping.h>
> #include <linux/bitfield.h>
> +#include <linux/usb/xhci-sideband.h>
>
> #include "xhci.h"
> #include "xhci-trace.h"
> @@ -922,6 +923,14 @@ void xhci_free_virt_device(struct xhci_hcd *xhci, struct xhci_virt_device *dev,
> dev->rhub_port->slot_id = 0;
> if (xhci->devs[slot_id] == dev)
> xhci->devs[slot_id] = NULL;
> +
> + if (dev->sideband) {
> + xhci_dbg(xhci, "vdev for slot %d has sideband still set at free, clearing dangling pointer\n",
> + slot_id);
> + dev->sideband->vdev = NULL;
> + dev->sideband = NULL;
> + }
> +
> kfree(dev);
> }
>
> diff --git a/drivers/usb/host/xhci-sideband.c b/drivers/usb/host/xhci-sideband.c
> index a5deeee4d5dc..f979ce517163 100644
> --- a/drivers/usb/host/xhci-sideband.c
> +++ b/drivers/usb/host/xhci-sideband.c
> @@ -472,12 +472,25 @@ xhci_sideband_unregister(struct xhci_sideband *sb)
>
> scoped_guard(mutex, &sb->mutex) {
> vdev = sb->vdev;
> - if (!vdev)
> - return;
> -
> - for (i = 0; i < EP_CTX_PER_DEV; i++)
> - if (sb->eps[i])
> - __xhci_sideband_remove_endpoint(sb, sb->eps[i]);
> + /*
> + * If vdev is NULL, xhci_free_virt_device() has already
> + * cleared sb->vdev and freed vdev (e.g. on
> + * COMP_USB_TRANSACTION_ERROR during address device
> + * recovery). Skip endpoint cleanup as the xHC has already
> + * disabled the slot.
> + *
> + * The interrupter and sideband instance are host-level
> + * resources independent of vdev, so still remove and free
> + * them to avoid leaks.
> + */
> + if (vdev) {
> + for (i = 0; i < EP_CTX_PER_DEV; i++)
> + if (sb->eps[i])
> + __xhci_sideband_remove_endpoint(sb, sb->eps[i]);
> + } else {
> + for (i = 0; i < EP_CTX_PER_DEV; i++)
> + sb->eps[i] = NULL;
> + }
>
> __xhci_sideband_remove_interrupter(sb);
>
> @@ -486,7 +499,8 @@ xhci_sideband_unregister(struct xhci_sideband *sb)
>
> spin_lock_irq(&xhci->lock);
> sb->xhci = NULL;
> - vdev->sideband = NULL;
> + if (vdev)
> + vdev->sideband = NULL;
> spin_unlock_irq(&xhci->lock);
>
> kfree(sb);
Looks good to me.
Thanks,
Selva
>
> Thanks
> Lianqin
next prev parent reply other threads:[~2026-09-11 8:45 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-07 12:24 [PATCH] xhci: sideband: check vdev liveness before removing endpoints on unregister 胡连勤
2026-09-10 9:34 ` Mathias Nyman
2026-09-10 11:10 ` Selvarasu Ganesan
2026-09-10 12:11 ` 答复: " 胡连勤
2026-09-10 13:50 ` Mathias Nyman
2026-09-11 5:10 ` Selvarasu Ganesan
2026-09-11 7:29 ` 答复: " 胡连勤
2026-09-11 8:41 ` Selvarasu Ganesan [this message]
2026-09-11 13:10 ` Mathias Nyman
2026-09-11 14:49 ` 答复: " 胡连勤
2026-09-12 12:18 ` Michal Pecio
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=937773018.41789116303608.JavaMail.epsvc@epcpadp1new \
--to=selvarasu.g@samsung.com \
--cc=alim.akhtar@samsung.com \
--cc=broonie@kernel.org \
--cc=cpgs@samsung.com \
--cc=gregkh@linuxfoundation.org \
--cc=hulianqin@vivo.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=mathias.nyman@intel.com \
--cc=mathias.nyman@linux.intel.com \
--cc=quic_wcheng@quicinc.com \
--cc=thiagu.r@samsung.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.