All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: Unknown <a0282524688@gmail.com>
Cc: linux-hwmon@vger.kernel.org
Subject: Re: [PATCH v2 2/2] mfd: Add Host Interface (HIF) support for Nuvoton NCT6694
Date: Wed, 08 Apr 2026 06:30:14 +0000	[thread overview]
Message-ID: <20260408063014.AEACFC19424@smtp.kernel.org> (raw)
In-Reply-To: <20260408053037.1867092-3-a0282524688@gmail.com>

Sashiko AI review found 8 potential issue(s):
- [High] devm_request_threaded_irq() with IRQF_SHARED and a NULL primary handler unconditionally fails.
- [High] Writing a Linux virtual IRQ number to the SIO hardware register corrupts interrupt routing.
- [High] Use-After-Free during USB disconnect due to incorrect teardown ordering of the IRQ domain.
- [High] Direct DMA to stack variables causes kernel panics.
- [High] Missing endpoint count check allows out-of-bounds array access.
- [Medium] Unbalanced release_region() and unsynchronized hardware access due to ignored superio_enter() return value.
- [Medium] Devres teardown ordering creates a window for an unhandled interrupt storm.
- [Medium] Unmapped hardware interrupts invoke the handler for Linux IRQ 0, causing system instability.
--

commit 60375817e31ea4cd313c9492ef71c36123f2e1d1
Author: Ming Yu <a0282524688@gmail.com>

mfd: Add Host Interface (HIF) support for Nuvoton NCT6694

This commit adds Host Interface (HIF) via eSPI for the Nuvoton NCT6694,
introducing a new transport driver while reorganizing the core and USB
driver. It provides common read/write functions and shared memory
interrupt handling.

> diff --git a/drivers/mfd/nct6694-hif.c b/drivers/mfd/nct6694-hif.c
> new file mode 100644
> index 0000000000000..7560754e74810
> --- /dev/null
> +++ b/drivers/mfd/nct6694-hif.c
[ ... ]
> +static irqreturn_t nct6694_irq_handler(int irq, void *data)
> +{
[ ... ]
> +	while (intr_status) {
> +		int irq = __ffs(intr_status);
> +
> +		generic_handle_irq_safe(irq_find_mapping(nct6694->domain, irq));
> +		intr_status &= ~BIT(irq);
> +	}
> +
> +	return IRQ_HANDLED;
> +}

If the hardware sets an unexpected interrupt bit that hasn't been mapped,
irq_find_mapping() returns 0. Does passing 0 directly into
generic_handle_irq_safe() inadvertently invoke the handler for Linux IRQ 0,
causing system instability? This applies to both this function and the USB
interrupt handler.

[ ... ]
> +static int nct6694_irq_init(struct nct6694 *nct6694, int irq)
> +{
> +	struct nct6694_hif_data *hdata = nct6694->priv;
> +	struct nct6694_sio_data *sio_data = hdata->sio_data;
> +	unsigned char cofs_ctl2;
> +
> +	/* Set SIRQ number */
> +	superio_enter(sio_data);

What happens if the request_muxed_region() inside superio_enter() fails and
returns -EBUSY? If the return value is ignored, the driver might proceed
with unsynchronized hardware access and later call superio_exit(),
releasing an I/O region it never successfully acquired.

> +	superio_select(sio_data, SIO_REG_LD_SHM);
> +	if (!superio_inb(sio_data, SIO_REG_SHM_ENABLE)) {
> +		superio_exit(sio_data);
> +		return -EIO;
> +	}
> +	hdata->shm_base = superio_inw(sio_data, SIO_REG_SHM_BASE_ADDR);
> +
> +	superio_outb(sio_data, SIO_REG_SHM_IRQ_NR, irq);

Could writing the Linux virtual IRQ number here misconfigure the hardware?
The irq parameter comes from platform_get_irq(), which returns a
dynamically allocated virtual IRQ number rather than the physical ISA or
eSPI IRQ line expected by the Super I/O chip.

[ ... ]
> +static int nct6694_probe(struct platform_device *pdev)
> +{
[ ... ]
> +	ret = nct6694_irq_init(data, irq);
> +	if (ret)
> +		return ret;
> +
> +	ret = devm_add_action_or_reset(dev, nct6694_irq_release, data);
> +	if (ret)
> +		return ret;
> +
> +	ret = devm_request_threaded_irq(dev, irq, NULL, nct6694_irq_handler,
> +					IRQF_ONESHOT | IRQF_SHARED,
> +					dev_name(dev), data);

The IRQ subsystem explicitly rejects shared interrupts without a primary
handler, as the default primary handler unconditionally masks the shared
line and starves other devices. Will this devm_request_threaded_irq() call
unconditionally return -EINVAL and fail to initialize?

Also, devres actions execute in reverse order during removal. Since the
hardware interrupt is enabled via nct6694_irq_init() before the IRQ handler
is requested, the handler will be freed before the hardware interrupt is
disabled during teardown. Could this create a window for an unhandled
interrupt storm?

> diff --git a/drivers/mfd/nct6694.c b/drivers/mfd/nct6694.c
> index 8ce2c4985aaba..903a0a7f0694c 100644
> --- a/drivers/mfd/nct6694.c
> +++ b/drivers/mfd/nct6694.c
[ ... ]
> +static int nct6694_usb_read_msg(struct nct6694 *nct6694,
> +				const struct nct6694_cmd_header *cmd_hd,
> +				void *buf)
> +{
[ ... ]
> +	/* Receive data packet from USB device */
> +	ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, NCT6694_BULK_IN_EP), buf,
> +			   le16_to_cpu(cmd_hd->len), &rx_len, NCT6694_URB_TIMEOUT);

Child drivers often pass pointers to local stack variables as the buf
argument. When passed directly to usb_bulk_msg(), does this cause a kernel
panic if CONFIG_VMAP_STACK is enabled, due to performing DMA on a stack
variable? Would it be safer to allocate a bounce buffer for the payload?
This applies to nct6694_usb_write_msg() as well.

[ ... ]
>  static int nct6694_usb_probe(struct usb_interface *iface,
>  			     const struct usb_device_id *id)
>  {
[ ... ]
> +	interface = iface->cur_altsetting;
> +
> +	int_endpoint = &interface->endpoint[0].desc;
> +	if (!usb_endpoint_is_int_in(int_endpoint)) {
> +		ret = -ENODEV;
> +		goto err_irq_domain;
> +	}

If a malformed or malicious USB device presents an interface with zero
endpoints, will this direct access to interface->endpoint[0] result in an
out-of-bounds read?

[ ... ]
>  static void nct6694_usb_disconnect(struct usb_interface *iface)
>  {
>  	struct nct6694 *nct6694 = usb_get_intfdata(iface);
> +	struct nct6694_usb_data *udata = nct6694->priv;
>  
> -	usb_kill_urb(nct6694->int_in_urb);
> +	usb_kill_urb(udata->int_in_urb);
>  	irq_domain_remove(nct6694->domain);
> -	usb_free_urb(nct6694->int_in_urb);
> +	usb_free_urb(udata->int_in_urb);
>  }

The child MFD devices are registered using devm_mfd_add_devices(), which
means they will be unbound by devres after this disconnect function returns.
If irq_domain_remove() is called here, will the child drivers attempt to
access the already-freed IRQ domain during their devres cleanup routines,
leading to a use-after-free?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260408053037.1867092-1-a0282524688@gmail.com?part=2

      reply	other threads:[~2026-04-08  6:30 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-08  5:30 [PATCH v2 0/2] mfd: nct6694: Refactor transport layer and add HIF (eSPI) support a0282524688
2026-04-08  5:30 ` [PATCH v2 1/2] mfd: nct6694: Switch to devm_mfd_add_devices() and drop IDA a0282524688
2026-04-08  5:48   ` sashiko-bot
2026-04-08  7:25   ` Bartosz Golaszewski
2026-04-10  9:59     ` Ming Yu
2026-04-08  5:30 ` [PATCH v2 2/2] mfd: Add Host Interface (HIF) support for Nuvoton NCT6694 a0282524688
2026-04-08  6:30   ` sashiko-bot [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=20260408063014.AEACFC19424@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=a0282524688@gmail.com \
    --cc=linux-hwmon@vger.kernel.org \
    --cc=sashiko@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.