From 1986592842cc259b88342f84a779852823179800 Mon Sep 17 00:00:00 2001 From: Max Krummenacher Date: Mon, 8 Sep 2025 15:22:12 +0200 Subject: [PATCH 1/2] drivers: firmware: imx: fix dependency for IMX_SEC_ENCLAVE IMX_SEC_ENCLAVE access the 'nvmem', thus on i.MX 8DXL/QXP/QM the following is required: NVMEM_IMX_OCOTP_SCU. Add it to the depends. With a missing NVMEM_IMX_OCOTP_SCU or with IMX_SEC_ENCLAVE=y and NVMEM_IMX_OCOTP_SCU=m, the probe can keep getting deferred. Fixes: 4faa6aeb8bc3 ("LF-13910-8: drivers: firmware: imx: add support for i.MX8DXL/QXP/QM") Signed-off-by: Max Krummenacher --- drivers/firmware/imx/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/firmware/imx/Kconfig b/drivers/firmware/imx/Kconfig index 65cb88db80fd9..984802128f755 100644 --- a/drivers/firmware/imx/Kconfig +++ b/drivers/firmware/imx/Kconfig @@ -58,7 +58,7 @@ config IMX_SCMI_MISC_DRV config IMX_SEC_ENCLAVE tristate "i.MX Embedded Secure Enclave - EdgeLock Enclave Firmware driver." - depends on IMX_MBOX && ARCH_MXC && ARM64 + depends on NVMEM_IMX_OCOTP_SCU && IMX_MBOX && ARCH_MXC && ARM64 select FW_LOADER default m if ARCH_MXC From eb38225dc62d77048a2c60676d2e2f33c9ecd890 Mon Sep 17 00:00:00 2001 From: Ernest Van Hoecke Date: Wed, 17 Sep 2025 14:47:28 +0200 Subject: [PATCH 2/2] drivers: firmware: imx: fix reference counting of se_kobj At the end of the probe function `se_if_probe`, `se_sysfs_log` is called which creates and adds the kernel object `se_kobj` and the sysfs files. This kobject is then at reference count 1. Since multiple instances of this driver can be present, with the same kobject, the desired behavior is to clean up this kobject when the last instance is removed. Therefore, when the probe is successful and `se_kobj` already existed, the reference count should be increased to track all instances using it. This is not the case now, this patch adds the missing reference count. Secondly, the function `se_if_probe_cleanup` decreases the reference count of `se_kobj`. However, this function is called not only by `se_if_remove` but also in case of probe failure. When the probe fails, the reference count was never increased (because the sysfs entries are not in use) and should thus not be decreased. This leads to a use-after-free situation and a warning in the log: [ 4.282934] fsl-se secure-envlave-1: Fail to read FIPS fuse [ 4.288628] fsl-se secure-envlave-1: Failed to fetch SoC Info. [ 4.294643] fsl-se secure-envlave-1: failed[-EPROBE_DEFER] to fetch SoC Info [ 4.302043] ------------[ cut here ]------------ [ 4.302049] refcount_t: underflow; use-after-free. [ 4.302091] WARNING: CPU: 2 PID: 50 at /lib/refcount.c:28 refcount_warn_saturate+0xf4/0x144 [ 4.302117] Modules linked in: snd_soc_imx_hdmi snd_soc_simple_card_utils sec_enclave rng_core led_class gpio_fan libata phy_fsl_imx8q_pcie fsl_imx8_ddr_perf ci_hdrc_imx cdns3_imx ci_hdrc ulpi ehci_hcd phy_cadence_salvo roles phy_mxs_usb usbmisc_imx usb3503 imx8qxp_adc flexcan can_dev snd_soc_sgtl5000 snd_soc_fsl_audmix snd_soc_fsl_spdif snd_soc_fsl_sai snd_soc_fsl_asrc pwm_imx27 snd_soc_fsl_utils imx_pcm_dma imx8_media_dev(C) spi_fsl_lpspi cdns_mhdp_imx cdns_mhdp_drmcore imx8qxp_pixel_combiner caam error irq_imx_irqsteer amphion_vpu fuse ipv6 autofs4 [ 4.302284] CPU: 2 PID: 50 Comm: kworker/u11:2 Tainted: G C 6.6.101-7.4.0-devel #1 [ 4.302294] Hardware name: Toradex Apalis iMX8QP V1.1 on Apalis Ixora V1.2 Carrier Board (DT) [ 4.302303] Workqueue: events_unbound deferred_probe_work_func [ 4.302319] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 4.302329] pc : refcount_warn_saturate+0xf4/0x144 [ 4.302341] lr : refcount_warn_saturate+0xf4/0x144 [ 4.302352] sp : ffffffc080393ab0 [ 4.302356] x29: ffffffc080393ab0 x28: 0000000000000000 x27: 0000000000000000 [ 4.302372] x26: ffffff8000411428 x25: ffffff8000666580 x24: ffffff8000628605 [ 4.302388] x23: 0000000000000008 x22: ffffffc080393b38 x21: ffffff80004e0810 [ 4.302404] x20: ffffff80004e0810 x19: ffffff800340b140 x18: fffffffffffe7488 [ 4.302419] x17: 0000000000000000 x16: ffffffd4c0967194 x15: 0000000000000030 [ 4.302435] x14: fffffffffffe74b8 x13: ffffffd4c100ad10 x12: 00000000000004f8 [ 4.302450] x11: 00000000000001a8 x10: ffffffd4c1062d10 x9 : ffffffd4c100ad10 [ 4.302466] x8 : 00000000ffffefff x7 : ffffffd4c1062d10 x6 : 80000000fffff000 [ 4.302481] x5 : ffffff807fb5ebc8 x4 : 0000000000000000 x3 : 0000000000000027 [ 4.302497] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffffff80006e6200 [ 4.302512] Call trace: [ 4.302519] refcount_warn_saturate+0xf4/0x144 [ 4.302531] kobject_put+0x164/0x218 [ 4.302544] se_if_probe_cleanup+0xf8/0x134 [sec_enclave] [ 4.302581] devm_action_release+0x14/0x20 [ 4.302594] devres_release_all+0xa8/0x110 [ 4.302604] device_unbind_cleanup+0x18/0x68 [ 4.302614] really_probe+0x120/0x3c4 [ 4.302623] __driver_probe_device+0x7c/0x16c [ 4.302632] driver_probe_device+0x3c/0x110 [ 4.302642] __device_attach_driver+0xbc/0x158 [ 4.302651] bus_for_each_drv+0x88/0xe8 [ 4.302661] __device_attach+0xa0/0x1b4 [ 4.302670] device_initial_probe+0x14/0x20 [ 4.302680] bus_probe_device+0xa8/0xac [ 4.302689] deferred_probe_work_func+0x94/0xe4 [ 4.302698] process_one_work+0x144/0x29c [ 4.302712] worker_thread+0x31c/0x434 [ 4.302723] kthread+0x110/0x114 [ 4.302735] ret_from_fork+0x10/0x20 [ 4.302746] ---[ end trace 0000000000000000 ]--- Fix both of these issues by incrementing the reference count when the kobject is relevant in subsequent probes and moving the kobject_put from the cleanup function to the remove function. This way, all successful probes increment the reference count, and only full removals decrement it, preventing use-after-free issues. Failed probes never alter the reference count so the cleanup shouldn't either. Fixes: 4faa6aeb8bc3 ("LF-13910-8: drivers: firmware: imx: add support for i.MX8DXL/QXP/QM") Signed-off-by: Ernest Van Hoecke --- drivers/firmware/imx/se_ctrl.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/firmware/imx/se_ctrl.c b/drivers/firmware/imx/se_ctrl.c index 19c87aa9f92d8..cac406828ecbc 100644 --- a/drivers/firmware/imx/se_ctrl.c +++ b/drivers/firmware/imx/se_ctrl.c @@ -2076,11 +2076,6 @@ static void se_if_probe_cleanup(void *plat_dev) * un-set bit. */ of_reserved_mem_device_release(dev); - - /* Free Kobj created for logging */ - if (se_kobj) - kobject_put(se_kobj); - } static int get_se_fw_img_nm_idx(const struct se_fw_img_name *se_fw_img_nm) @@ -2280,6 +2275,8 @@ static int se_if_probe(struct platform_device *pdev) ret = se_sysfs_log(); if (ret) pr_warn("Warn: Creating sysfs entry for se_log and se_rcv_msg_timeout: %d\n", ret); + } else { + kobject_get(se_kobj); } dev_info(dev, "i.MX secure-enclave: %s%d interface to firmware, configured.\n", @@ -2296,6 +2293,10 @@ static int se_if_probe(struct platform_device *pdev) static void se_if_remove(struct platform_device *pdev) { se_if_probe_cleanup(pdev); + + /* Free Kobj created for logging */ + if (se_kobj) + kobject_put(se_kobj); } static int se_suspend(struct device *dev)