RE: [PATCH v33 3/7] firmware: imx: add driver for NXP EdgeLock Enclave

"Pankaj Gupta (OSS)" <[email protected]> Wed, 5 Aug 2026 13:08:21 +0000
Newsgroups dev.linux.lists.sashiko-reviews,dev.linux.lists.imx,org.kernel.vger.linux-devicetree
Message-ID <GV2PR04MB1227182E66DDB501DA79CEFD195D32@GV2PR04MB12271.eurprd04.prod.outlook.com>
> > diff --git a/drivers/firmware/imx/ele_base_msg.c
> > b/drivers/firmware/imx/ele_base_msg.c
> > new file mode 100644
> > index 0000000000000..724f6e913ce79
> > --- /dev/null
> > +++ b/drivers/firmware/imx/ele_base_msg.c
> > @@ -0,0 +1,282 @@
> 
> [ ... ]
> 
> > +static void ele_get_info_cleanup(struct se_if_priv *priv, u32 *buf,
> dma_addr_t d_addr,
> > +				 size_t size)
> > +{
> > +	if (priv->mem_pool)
> > +		gen_pool_free(priv->mem_pool, (unsigned long)buf, size);
> > +	else
> > +		dma_free_coherent(priv->dev, size, buf, d_addr); }
> > +
> > +int ele_get_info(struct se_if_priv *priv, struct ele_dev_info
> > +*s_info) {
> 
> [ ... ]
> 
> > +	ret = ele_msg_send_rcv(priv, tx_msg, ELE_GET_INFO_REQ_MSG_SZ,
> rx_msg,
> > +			       ELE_GET_INFO_RSP_MSG_SZ);
> > +	if (ret < 0) {
> > +		ele_get_info_cleanup(priv, get_info_data, get_info_addr,
> > +get_info_len);
> 
> [Severity: High]
> If ele_msg_send_rcv() times out and returns -ETIMEDOUT, is it safe to
> immediately free the DMA buffer by calling ele_get_info_cleanup()?
> 
> Since the external EdgeLock Enclave firmware is not halted on a timeout,
> couldn't it eventually complete the transaction and write the response
> payload into this freed memory, causing a DMA-after-free memory
> corruption?
> 
> > +		return ret;
> > +	}
> > +
> > +	ret = se_val_rsp_hdr_n_status(priv, rx_msg, ELE_GET_INFO_REQ,
> > +				      ELE_GET_INFO_RSP_MSG_SZ, true);
> > +	if (ret < 0) {
> > +		ele_get_info_cleanup(priv, get_info_data, get_info_addr,
> get_info_len);
> > +		return ret;
> > +	}
> 
[Already taken care in 5/7]
At 3/7 the cleanup frees unconditionally (gen_pool_free/dma_free_coherent) and the timeout leg only does a bare atomic_set(\&priv->fw_busy, 1), which cannot fence an in-flight enclave DMA. The symbols that fix it (se_is_fw_busy_ctx/se_mark_fw_busy, priv_dev_ctx) do not exist at 3/7. It is resolved by PATCH v33 5/7 (fb107010a07b, "firmware: imx: adds miscdev"), which adds per-context fw_busy ownership and rewrites ele_get_info_cleanup() to quarantine (return without freeing) the buffer while the owning context is still busy.


> [ ... ]
> 
> > diff --git a/drivers/firmware/imx/ele_common.c
> > b/drivers/firmware/imx/ele_common.c
> > new file mode 100644
> > index 0000000000000..bc08ea2dcd87d
> > --- /dev/null
> > +++ b/drivers/firmware/imx/ele_common.c
> > @@ -0,0 +1,492 @@
> 
> [ ... ]
> 
> > +int ele_msg_rcv(struct se_if_priv *priv, struct se_clbk_handle
> > +*se_clbk_hdl) {
> > +	bool is_rsp_wait_with_timeout = false;
> > +	bool wait_uninterruptible = false;
> > +	unsigned long remaining_jiffies;
> > +	unsigned long deadline_jiffies;
> > +	unsigned long flags;
> > +	int ret;
> > +
> > +	remaining_jiffies =
> msecs_to_jiffies(SE_RCV_MSG_DEFAULT_TIMEOUT_MS);
> > +	if (se_clbk_hdl == &priv->waiting_rsp_clbk_hdl) {
> > +		is_rsp_wait_with_timeout = true;
> > +		deadline_jiffies = jiffies + remaining_jiffies;
> > +	}
> > +
> > +	do {
> > +		if (is_rsp_wait_with_timeout) {
> > +			unsigned long now = jiffies;
> > +
> > +			if (time_after_eq(now, deadline_jiffies)) {
> > +				/* Deadline hit: fence hung FW, like the
> ret==0 path. */
> > +				spin_lock_irqsave(&se_clbk_hdl-
> >clbk_rx_lock, flags);
> > +				se_clbk_hdl->rx_msg = NULL;
> > +				if (!completion_done(&se_clbk_hdl->done))
> > +					atomic_set(&priv->fw_busy, 1);
> > +				spin_unlock_irqrestore(&se_clbk_hdl-
> >clbk_rx_lock, flags);
> > +				ret = -ETIMEDOUT;
> > +				break;
> > +			}
> > +			remaining_jiffies = deadline_jiffies - now;
> > +		}
> > +
> > +		if (wait_uninterruptible)
> > +			ret = wait_for_completion_timeout(&se_clbk_hdl-
> >done,
> > +							  remaining_jiffies);
> > +		else
> > +			ret =
> wait_for_completion_interruptible_timeout(&se_clbk_hdl->done,
> > +
> 	remaining_jiffies);
> 
> [Severity: High]
> Since ele_msg_rcv() uses an interruptible wait by default for all transactions,
> what happens to internal kernel transactions if a signal is pending?
> 
> If a fake signal is sent by the PM freezer during suspend, or a user sends
> SIGINT during modprobe, won't this abort the wait with -ERESTARTSYS?
> 
> > +		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;
> > +		}
> 
> [ ... ]
> 
> > +int ele_msg_send_rcv(struct se_if_priv *priv, void *tx_msg, int tx_msg_sz,
> > +		     void *rx_msg, int exp_rx_msg_sz) {
> 
> [ ... ]
> 
> > +	err = ele_msg_rcv(priv, &priv->waiting_rsp_clbk_hdl);
> > +
> > +	if (priv->waiting_rsp_clbk_hdl.signal_rcvd) {
> > +		/*
> > +		 * Signal was deferred until the FW/kernel protocol
> resynchronized.
> > +		 * On success report -ERESTARTSYS for the interrupted wait;
> the
> > +		 * command is not re-sent. Keep real errors like -ETIMEDOUT.
> > +		 */
> > +		if (err > 0)
> > +			err = -ERESTARTSYS;
> > +		priv->waiting_rsp_clbk_hdl.signal_rcvd = false;
> > +		dev_dbg(priv->dev, "Err[0x%x]:Interrupted by signal.", err);
> > +	}
> 
> Since ele_msg_send_rcv() explicitly converts the successful return back to -
> ERESTARTSYS when a signal was received, could this cause spurious device
> initialization or power management failures for callers that are not tied to a
> restartable syscall?

[Already taken care in 5/7]
The `wait_uninterruptible = true` for `priv->priv_dev_ctx` is introduced in 5/7 as well (it depends on `priv_dev_ctx`, added in 4/7 ).
At 3/7 only the `signal_rcvd` deferred-signal mechanism exists, not the internal-transaction fix.

> 
> --
> Sashiko AI review ยท https://sashiko.dev/#/patchset/20260805-imx-se-if-v33-0-
> [email protected]?part=3