From: Frank Li <Frank.li@oss.nxp.com>
To: sashiko-reviews@lists.linux.dev
Cc: pankaj.gupta@oss.nxp.com, Frank.Li@kernel.org,
imx@lists.linux.dev, robh@kernel.org, devicetree@vger.kernel.org,
conor+dt@kernel.org
Subject: Re: [PATCH v35 5/7] firmware: imx: adds miscdev
Date: Thu, 6 Aug 2026 11:31:29 -0500 [thread overview]
Message-ID: <anS24Uf5jI7auJxS@SMW015318> (raw)
In-Reply-To: <20260806112724.89B351F000E9@smtp.kernel.org>
On Thu, Aug 06, 2026 at 11:27:24AM +0000, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
> - [Critical] The driver allows userspace to embed arbitrary DMA addresses in permitted firmware commands, enabling arbitrary physical memory overwrite.
> - [High] The `se_if_open_gate` structure can be accessed after it is freed if an `open()` system call races with driver unbind.
> - [High] A concurrent `close()` racing with driver unbind causes a Use-After-Free on the mailbox channel `priv->tx_chan` due to premature unlinking.
> - [High] Firmware session and storage handles can be permanently leaked if response validation or userspace memory copies fail, bypassing the tracking of allocated handles.
> - [High] Signal interruption converts an interruptible wait into an unkillable uninterruptible wait for up to 5000 seconds.
> --
>
> --- Patch [5]: [PATCH v35 5/7] firmware: imx: adds miscdev ---
> commit a678d58783e842f1a853a0ba674864702cf30910
> Author: Pankaj Gupta <pankaj.gupta@nxp.com>
> Subject: firmware: imx: adds miscdev
>
> This commit adds a character driver to communicate with the NXP secure
> enclave hardware. It provides an ioctl interface for userspace applications
> to send commands, manage shared memory, and restricts invalid or disallowed
> firmware commands.
>
> Closes: https://sashiko.dev/#/patchset/20260805-imx-se-if-v34-0-7e4713d14e0a@nxp.com?part=5
>
> > diff --git a/drivers/firmware/imx/ele_base_msg.c b/drivers/firmware/imx/ele_base_msg.c
> > --- a/drivers/firmware/imx/ele_base_msg.c
> > +++ b/drivers/firmware/imx/ele_base_msg.c
> > @@ -15,13 +15,57 @@
> >
> > #define FW_DBG_DUMP_FIXED_STR "ELE"
> >
> > +int ele_uapi_allowed_base_cmd(struct se_if_priv *priv,
> > + struct se_msg_hdr *header)
> > +{
> > + switch (header->command) {
> > + case ELE_PING_REQ: return 0;
> > + case ELE_DEBUG_DUMP_REQ: return 0;
> > + case ELE_OEM_AUTH_CONTAINER_REQ: return 0;
> > + case ELE_OEM_VERIFY_IMAGE_REQ: return 0;
> > + case ELE_OEM_REL_CONTAINER_REQ: return 0;
> > + case ELE_FW_LIFE_CYCLE_REQ: return 0;
> > + case ELE_READ_FUSE_REQ: return 0;
> > + case ELE_GET_FW_VERS_REQ: return 0;
> > + case ELE_RETURN_LIFE_CYCLE_REQ: return 0;
> > + case ELE_GET_EVENT_REQ: return 0;
> > + case ELE_COMMIT_REQ: return 0;
> > + case ELE_GEN_KEY_BLOB_REQ: return 0;
> > + case ELE_GET_FW_STATUS_REQ: return 0;
> > + case ELE_XIP_DECRYPT_REQ: return 0;
> > + case ELE_WRITE_FUSE: return 0;
> > + case ELE_GET_INFO_REQ: return 0;
> > + case ELE_DEV_ATTEST_REQ: return 0;
> > + case ELE_WRITE_SHADOW_FUSE_REQ: return 0;
> > + case ELE_READ_SHADOW_FUSE_REQ: return 0;
> > + default:
> > + return -EACCES;
> > + }
> > +}
>
> [Severity: Critical]
> Does this allowlist permit userspace to embed arbitrary DMA addresses without
> kernel validation?
>
> Commands like ELE_GET_INFO_REQ accept physical DMA addresses directly in
> their payloads. Because se_chk_tx_msg_hdr() only validates the command header
> against this list and performs no payload sanitization, could an unprivileged
> user embed arbitrary physical addresses (e.g., kernel text) leading to the
> hardware enclave overwriting arbitrary memory?
This one may security hole, you need check payload to make sure DMA
address is in ranges.
>
> > diff --git a/drivers/firmware/imx/ele_common.c b/drivers/firmware/imx/ele_common.c
> > --- a/drivers/firmware/imx/ele_common.c
> > +++ b/drivers/firmware/imx/ele_common.c
> [ ... ]
> > @@ -71,7 +122,7 @@ int ele_msg_rcv(struct se_if_device_ctx *dev_ctx, struct se_clbk_handle *se_clbk
> > + if (ret == -ERESTARTSYS) {
> > + /*
> > + * Record that a signal was observed, then continue waiting non-
> > + * interruptibly until the response arrives or the timeout
> > + * expires. The caller can surface the interruption to userspace
> > + * after the protocol transaction is brought back to a
> > + * synchronized state.
> > + */
> > + if (is_rsp_wait_with_timeout &&
> > + READ_ONCE(se_clbk_hdl->rx_msg)) {
> > + WRITE_ONCE(se_clbk_hdl->signal_rcvd, true);
> > + wait_uninterruptible = true;
> > + continue;
> > + }
> > + break;
> > + }
>
> [Severity: High]
> Can this loop trap a process in an unkillable state for a very long time?
>
> If a process is interrupted by a signal while waiting in ele_msg_rcv(), the
> code converts the interruptible wait into an uninterruptible one by setting
> wait_uninterruptible = true. Given that SE_RCV_MSG_LONG_TIMEOUT_MS is 5000
> seconds, this could leave the task unkillable for over an hour, potentially
> triggering the kernel's hung task watchdog.
This one need double check.
Other high problem need your judgement.
Frank
>
> > diff --git a/drivers/firmware/imx/se_ctrl.c b/drivers/firmware/imx/se_ctrl.c
> > --- a/drivers/firmware/imx/se_ctrl.c
> > +++ b/drivers/firmware/imx/se_ctrl.c
> [ ... ]
> > +static void dlink_n_cleanup_dev_ctx(struct se_if_device_ctx *dev_ctx, bool is_fclose)
> > +{
> > + struct se_if_priv *priv = dev_ctx->priv;
> > +
> > + if (is_fclose) {
> > + scoped_guard(mutex, &priv->modify_lock)
> > + dlink_dev_ctx(dev_ctx);
> > + }
> > +
> > + cleanup_dev_ctx(dev_ctx, is_fclose);
> > +}
>
> [Severity: High]
> Does unlinking dev_ctx before executing cleanup_dev_ctx() open a race
> condition during driver unbind?
>
> In se_if_probe_cleanup(), the unbind thread iterates over priv->dev_ctx_list
> to gracefully close contexts. By unlinking the context here before the
> cleanup completes, the unbind thread won't see it, won't block on fops_lock,
> and might call mbox_free_channel(priv->tx_chan) prematurely. This could cause
> the concurrent close thread to send on a freed channel in ele_msg_send().
>
> [ ... ]
> > + rsp_status_err =
> > + se_val_rsp_hdr_n_status(priv, rx_msg, tx_msg->header.command,
> > + cmd_snd_rcv_rsp_info.rx_buf_sz,
> > + tx_msg->header.ver == priv->if_defs->base_api_ver);
> > +
> > + if (!rsp_status_err) {
> > + err = se_dev_ctx_cpy_out_data(dev_ctx);
> > + if (err < 0) {
> > + se_ioctl_cmd_snd_rcv_cleanup(dev_ctx, uarg, &cmd_snd_rcv_rsp_info);
> > + return err;
> > + }
> > + }
> > +
> > + /* Copy data from the buffer */
> > + print_hex_dump_debug("to user ", DUMP_PREFIX_OFFSET, 4, 4, rx_msg,
> > + cmd_snd_rcv_rsp_info.rx_buf_sz, false);
> > +
> > + if (copy_to_user(u64_to_user_ptr(cmd_snd_rcv_rsp_info.rx_buf), rx_msg,
> > + cmd_snd_rcv_rsp_info.rx_buf_sz)) {
> > + dev_err(priv->dev, "%s: Failed to copy to user.", dev_ctx->devname);
> > + err = -EFAULT;
> > + }
> > +
> > + cleanup_err = se_ioctl_cmd_snd_rcv_cleanup(dev_ctx, uarg, &cmd_snd_rcv_rsp_info);
> > +
> > + if (cleanup_err && !err)
> > + err = cleanup_err;
> > +
> > + if (!err && !rsp_status_err)
> > + fw_api_specific_ops(dev_ctx, rx_msg);
>
> [Severity: High]
> Could this error handling sequence leak firmware session or storage handles?
>
> If the firmware successfully executes an ELE_SESSION_OPEN_REQ, it allocates a
> handle. However, if a user submits an intentionally truncated rx_buf_sz
> (causing se_val_rsp_hdr_n_status() to fail) or a bad user pointer (causing
> copy_to_user() to fail), the function skips calling fw_api_specific_ops().
> This leaves the handle untracked by the kernel, preventing cleanup and
> leaking hardware resources.
>
> [ ... ]
> > +/* Open a character device. */
> > +static int se_if_fops_open(struct inode *nd, struct file *fp)
> > +{
> > + struct miscdevice *miscdev = fp->private_data;
> > + struct se_if_open_gate *gate;
> > + struct se_if_device_ctx *misc_dev_ctx;
> > + struct se_if_device_ctx *dev_ctx;
> > + struct se_if_priv *priv;
> > + int err = 0;
> > +
> > + gate = container_of(miscdev, struct se_if_open_gate, miscdev);
> > +
> > + if (!se_if_open_gate_get(gate))
> > + return -ENODEV;
>
> [Severity: High]
> Is there a use-after-free risk if open() races with driver unbind?
>
> When the module unbinds, se_if_probe_cleanup() calls misc_deregister(),
> which does not fully synchronize with active open() calls. If the unbind
> thread drops the final reference to priv in se_if_priv_release(),
> se_if_open_gate_put() frees the gate object. A concurrent se_if_fops_open()
> might then attempt to access the refcount of this already freed gate pointer.
>
> --
> Sashiko AI review · https://sashiko.dev/#/patchset/20260806-imx-se-if-v35-0-11b25bb308ef@nxp.com?part=5
next prev parent reply other threads:[~2026-08-06 16:31 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-06 11:51 [PATCH v35 0/7] firmware: imx: driver for NXP secure-enclave pankaj.gupta
2026-08-06 11:51 ` [PATCH v35 1/7] Documentation/firmware: add imx/se to other_interfaces pankaj.gupta
2026-08-06 11:08 ` sashiko-bot
2026-08-06 11:51 ` [PATCH v35 2/7] dt-bindings: arm: fsl: add imx-se-fw binding doc pankaj.gupta
2026-08-06 11:51 ` [PATCH v35 3/7] firmware: imx: add driver for NXP EdgeLock Enclave pankaj.gupta
2026-08-06 11:17 ` sashiko-bot
2026-08-06 16:08 ` Frank Li
2026-08-06 11:51 ` [PATCH v35 4/7] firmware: imx: device context dedicated to priv pankaj.gupta
2026-08-06 11:15 ` sashiko-bot
2026-08-06 11:51 ` [PATCH v35 5/7] firmware: imx: adds miscdev pankaj.gupta
2026-08-06 11:27 ` sashiko-bot
2026-08-06 16:31 ` Frank Li [this message]
2026-08-06 11:51 ` [PATCH v35 6/7] arm64: dts: imx8ulp: add secure enclave node pankaj.gupta
2026-08-06 11:13 ` sashiko-bot
2026-08-06 11:51 ` [PATCH v35 7/7] arm64: dts: imx8ulp: add reserved memory for EdgeLock Enclave pankaj.gupta
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=anS24Uf5jI7auJxS@SMW015318 \
--to=frank.li@oss.nxp.com \
--cc=Frank.Li@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=imx@lists.linux.dev \
--cc=pankaj.gupta@oss.nxp.com \
--cc=robh@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.