[PATCH 2/2] nvmet: avoid recursive configfs open for passthru
From: Runyu Xiao
Date: Mon Aug 17 2026 - 10:50:33 EST
nvmet_passthru_enable_store() runs as a configfs store callback while
configfs holds the item's frag_sem. nvmet_passthru_ctrl_enable() then
uses filp_open() on the configured passthru_ctrl_path.
If passthru_ctrl_path points back into configfs, the open path
re-enters __configfs_open_file() and tries to take the same frag_sem
again.
Resolve the path with kern_path(), reject configfs paths, and open the
resolved path with dentry_open() instead of filp_open(). Configfs paths
are not valid passthru controller backends, so rejecting them avoids
the recursion without changing valid users.
Fixes: cae5b01a2afc ("nvmet: introduce the passthru configfs interface")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Runyu Xiao <runyu.xiao@xxxxxxxxxx>
---
drivers/nvme/target/passthru.c | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/drivers/nvme/target/passthru.c b/drivers/nvme/target/passthru.c
index 0c361b1e3566..be302f70d0e2 100644
--- a/drivers/nvme/target/passthru.c
+++ b/drivers/nvme/target/passthru.c
@@ -8,6 +8,7 @@
*
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <linux/namei.h>
#include <linux/module.h>
#include "../host/nvme.h"
@@ -578,6 +579,7 @@ int nvmet_passthru_ctrl_enable(struct nvmet_subsys *subsys)
{
struct nvme_ctrl *ctrl;
struct file *file;
+ struct path path;
int ret = -EINVAL;
void *old;
@@ -592,7 +594,20 @@ int nvmet_passthru_ctrl_enable(struct nvmet_subsys *subsys)
goto out_unlock;
}
- file = filp_open(subsys->passthru_ctrl_path, O_RDWR, 0);
+ ret = kern_path(subsys->passthru_ctrl_path, LOOKUP_FOLLOW, &path);
+ if (ret)
+ goto out_unlock;
+
+ if (!strcmp(path.dentry->d_sb->s_type->name, "configfs")) {
+ pr_err("configfs paths cannot back passthru controller %s\n",
+ subsys->passthru_ctrl_path);
+ path_put(&path);
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
+ file = dentry_open(&path, O_RDWR, current_cred());
+ path_put(&path);
if (IS_ERR(file)) {
ret = PTR_ERR(file);
goto out_unlock;
--
2.34.1