All of lore.kernel.org
 help / color / mirror / Atom feed
From: Adrian Hunter <adrian.hunter@intel.com>
To: <sashiko-reviews@lists.linux.dev>
Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>,
	<Frank.Li@kernel.org>, <linux-pci@vger.kernel.org>,
	<linux-i3c@lists.infradead.org>
Subject: Re: [PATCH RFC RESEND 2/7] i3c: master: Report wakeup events for IBIs
Date: Thu, 2 Jul 2026 13:38:44 +0300	[thread overview]
Message-ID: <a8aba6ab-75e6-4c0a-b6e3-afd9fbb2042f@intel.com> (raw)
In-Reply-To: <20260701203336.D13321F000E9@smtp.kernel.org>

On 01/07/2026 23:33, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
> 
> New issues:
> - [High] Unconditional NULL pointer dereference of `dev->dev` in `i3c_master_queue_ibi` during device teardown
> 
> Pre-existing issues:
> - [High] Lockless TOCTOU race leading to Use-After-Free of `dev->ibi` during concurrent IBI teardown
> --
> 
> commit ffdd9b066a2bdadecaab205d187dab1a5ecff5ae
> Author: Adrian Hunter <adrian.hunter@intel.com>
> 
> i3c: master: Report wakeup events for IBIs
> 
> An I3C device configured as a wakeup source can wake the system by
> generating an In-Band Interrupt (IBI).
> 
> When an IBI is queued for processing, record a wakeup event for the
> device if wakeup is enabled.  Use a 100 ms processing interval to give
> the I3C device driver time to process the IBI.
> 
>> diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
>> index a47e2924bb701..a36f9b617cbf7 100644
>> --- a/drivers/i3c/master.c
>> +++ b/drivers/i3c/master.c
> 
> [ ... ]
> 
>> @@ -3007,6 +3010,9 @@ void i3c_master_queue_ibi(struct i3c_dev_desc *dev, struct i3c_ibi_slot *slot)
>>  	if (!dev->ibi || !slot)
>>  		return;
>>  
>> +	if (device_may_wakeup(&dev->dev->dev))
>> +		pm_wakeup_event(&dev->dev->dev, I3C_WAKEUP_PROCESSING_TIME_MS);
>> +
> 
> [Severity: High]
> Does this code introduce a NULL pointer dereference if an interrupt arrives
> during device teardown?
> 
> During I3C master controller unregistration, i3c_master_unregister_i3c_devs()
> clears the device description and sets i3cdev->dev to NULL:
> 
> 	i3cdev->dev->desc = NULL;
> 	if (device_is_registered(&i3cdev->dev->dev))
> 		device_unregister(&i3cdev->dev->dev);

I3C drivers are required to disable and free IBIs when they
are removed, and they do do that.  There is a corner case, if
the IBI disable fails, but that is out of scope for this patch
set.

> 	else
> 		put_device(&i3cdev->dev->dev);

dev->ibi will be NULL for devices that are not registered,
so i3c_master_queue_ibi() would never get to i3c_master_queue_ibi()
even if somehow the controller driver tried to queue an IBI.

> 	i3cdev->dev = NULL;
> 
> Since clearing dev->desc prevents the driver's remove callback from disabling
> the hardware IBI, the IBI may still fire. If i3c_master_queue_ibi() executes
> at this point, the newly added device_may_wakeup(&dev->dev->dev) will
> dereference the NULL dev->dev pointer.
> 
>>  	atomic_inc(&dev->ibi->pending_ibis);
> 
> [Severity: High]
> This is a pre-existing issue, but does this lockless check open a 
> use-after-free race window?
> 
> If a hardware IBI interrupt is processed concurrently on another CPU, it can
> evaluate if (!dev->ibi) as false, get preempted, and then access
> dev->ibi->pending_ibis and dev->ibi->wq after they have been freed by
> i3c_dev_free_ibi_locked():
> 
> 	kfree(dev->ibi);
> 	dev->ibi = NULL;
> 
> This is possible for hardware controllers like dw-i3c-master that do not
> implicitly synchronize with executing hardware IRQ handlers during their
> disable op.

Yes, some drivers have gaps.

For dw, an IBI would have to arrive immediately before the DISEC CCC
and end up being processed during the same invocation of
dw_i3c_master_irq_handler().  The DISEC would complete() first which
would potentially allow i3c_dev_disable_ibi_locked() to
atomic_read(&dev->ibi->pending_ibis) before the dw driver gets to
atomic_inc(&dev->ibi->pending_ibis) via i3c_master_queue_ibi().

Out of scope for this patch set.

> 
>>  	queue_work(dev->ibi->wq, &slot->work);
>>  }
> 


WARNING: multiple messages have this Message-ID (diff)
From: Adrian Hunter <adrian.hunter@intel.com>
To: <sashiko-reviews@lists.linux.dev>
Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>,
	<Frank.Li@kernel.org>, <linux-pci@vger.kernel.org>,
	<linux-i3c@lists.infradead.org>
Subject: Re: [PATCH RFC RESEND 2/7] i3c: master: Report wakeup events for IBIs
Date: Thu, 2 Jul 2026 13:38:44 +0300	[thread overview]
Message-ID: <a8aba6ab-75e6-4c0a-b6e3-afd9fbb2042f@intel.com> (raw)
In-Reply-To: <20260701203336.D13321F000E9@smtp.kernel.org>

On 01/07/2026 23:33, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
> 
> New issues:
> - [High] Unconditional NULL pointer dereference of `dev->dev` in `i3c_master_queue_ibi` during device teardown
> 
> Pre-existing issues:
> - [High] Lockless TOCTOU race leading to Use-After-Free of `dev->ibi` during concurrent IBI teardown
> --
> 
> commit ffdd9b066a2bdadecaab205d187dab1a5ecff5ae
> Author: Adrian Hunter <adrian.hunter@intel.com>
> 
> i3c: master: Report wakeup events for IBIs
> 
> An I3C device configured as a wakeup source can wake the system by
> generating an In-Band Interrupt (IBI).
> 
> When an IBI is queued for processing, record a wakeup event for the
> device if wakeup is enabled.  Use a 100 ms processing interval to give
> the I3C device driver time to process the IBI.
> 
>> diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
>> index a47e2924bb701..a36f9b617cbf7 100644
>> --- a/drivers/i3c/master.c
>> +++ b/drivers/i3c/master.c
> 
> [ ... ]
> 
>> @@ -3007,6 +3010,9 @@ void i3c_master_queue_ibi(struct i3c_dev_desc *dev, struct i3c_ibi_slot *slot)
>>  	if (!dev->ibi || !slot)
>>  		return;
>>  
>> +	if (device_may_wakeup(&dev->dev->dev))
>> +		pm_wakeup_event(&dev->dev->dev, I3C_WAKEUP_PROCESSING_TIME_MS);
>> +
> 
> [Severity: High]
> Does this code introduce a NULL pointer dereference if an interrupt arrives
> during device teardown?
> 
> During I3C master controller unregistration, i3c_master_unregister_i3c_devs()
> clears the device description and sets i3cdev->dev to NULL:
> 
> 	i3cdev->dev->desc = NULL;
> 	if (device_is_registered(&i3cdev->dev->dev))
> 		device_unregister(&i3cdev->dev->dev);

I3C drivers are required to disable and free IBIs when they
are removed, and they do do that.  There is a corner case, if
the IBI disable fails, but that is out of scope for this patch
set.

> 	else
> 		put_device(&i3cdev->dev->dev);

dev->ibi will be NULL for devices that are not registered,
so i3c_master_queue_ibi() would never get to i3c_master_queue_ibi()
even if somehow the controller driver tried to queue an IBI.

> 	i3cdev->dev = NULL;
> 
> Since clearing dev->desc prevents the driver's remove callback from disabling
> the hardware IBI, the IBI may still fire. If i3c_master_queue_ibi() executes
> at this point, the newly added device_may_wakeup(&dev->dev->dev) will
> dereference the NULL dev->dev pointer.
> 
>>  	atomic_inc(&dev->ibi->pending_ibis);
> 
> [Severity: High]
> This is a pre-existing issue, but does this lockless check open a 
> use-after-free race window?
> 
> If a hardware IBI interrupt is processed concurrently on another CPU, it can
> evaluate if (!dev->ibi) as false, get preempted, and then access
> dev->ibi->pending_ibis and dev->ibi->wq after they have been freed by
> i3c_dev_free_ibi_locked():
> 
> 	kfree(dev->ibi);
> 	dev->ibi = NULL;
> 
> This is possible for hardware controllers like dw-i3c-master that do not
> implicitly synchronize with executing hardware IRQ handlers during their
> disable op.

Yes, some drivers have gaps.

For dw, an IBI would have to arrive immediately before the DISEC CCC
and end up being processed during the same invocation of
dw_i3c_master_irq_handler().  The DISEC would complete() first which
would potentially allow i3c_dev_disable_ibi_locked() to
atomic_read(&dev->ibi->pending_ibis) before the dw driver gets to
atomic_inc(&dev->ibi->pending_ibis) via i3c_master_queue_ibi().

Out of scope for this patch set.

> 
>>  	queue_work(dev->ibi->wq, &slot->work);
>>  }
> 


-- 
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c

  reply	other threads:[~2026-07-02 10:38 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-01 20:15 [PATCH RFC RESEND 0/7] i3c: Support IBI-based system wakeup Adrian Hunter
2026-07-01 20:15 ` Adrian Hunter
2026-07-01 20:15 ` [PATCH RFC RESEND 1/7] i3c: master: Support IBI-based wakeup capability Adrian Hunter
2026-07-01 20:15   ` Adrian Hunter
2026-07-01 20:30   ` sashiko-bot
2026-07-01 20:30     ` sashiko-bot
2026-07-02 14:10   ` Frank Li
2026-07-02 14:10     ` Frank Li
2026-07-01 20:15 ` [PATCH RFC RESEND 2/7] i3c: master: Report wakeup events for IBIs Adrian Hunter
2026-07-01 20:15   ` Adrian Hunter
2026-07-01 20:33   ` sashiko-bot
2026-07-01 20:33     ` sashiko-bot
2026-07-02 10:38     ` Adrian Hunter [this message]
2026-07-02 10:38       ` Adrian Hunter
2026-07-01 20:15 ` [PATCH RFC RESEND 3/7] i3c: master: Add helper to query bus wakeup requirements Adrian Hunter
2026-07-01 20:15   ` Adrian Hunter
2026-07-01 20:33   ` sashiko-bot
2026-07-01 20:33     ` sashiko-bot
2026-07-01 20:15 ` [PATCH RFC RESEND 4/7] i3c: master: Reject IBI requests from non-IBI-capable devices Adrian Hunter
2026-07-01 20:15   ` Adrian Hunter
2026-07-01 20:29   ` sashiko-bot
2026-07-01 20:29     ` sashiko-bot
2026-07-01 20:15 ` [PATCH RFC RESEND 5/7] i3c: mipi-i3c-hci-pci: Propagate I3C wakeup requirements to PCI Adrian Hunter
2026-07-01 20:15   ` Adrian Hunter
2026-07-01 20:33   ` sashiko-bot
2026-07-01 20:33     ` sashiko-bot
2026-07-01 20:15 ` [PATCH RFC RESEND 6/7] i3c: mipi-i3c-hci: Factor out i3c_hci_sysdev() Adrian Hunter
2026-07-01 20:15   ` Adrian Hunter
2026-07-01 20:23   ` sashiko-bot
2026-07-01 20:23     ` sashiko-bot
2026-07-01 20:15 ` [PATCH RFC RESEND 7/7] i3c: mipi-i3c-hci: Advertise IBI wakeup capability Adrian Hunter
2026-07-01 20:15   ` Adrian Hunter
2026-07-01 20:22   ` sashiko-bot
2026-07-01 20:22     ` sashiko-bot

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=a8aba6ab-75e6-4c0a-b6e3-afd9fbb2042f@intel.com \
    --to=adrian.hunter@intel.com \
    --cc=Frank.Li@kernel.org \
    --cc=alexandre.belloni@bootlin.com \
    --cc=linux-i3c@lists.infradead.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /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.