* [PATCH v4 1/3] fs: configfs: add helpers for opening non-configfs paths
2026-09-21 9:05 [PATCH v4 0/3] nvmet: avoid recursive configfs open Runyu Xiao
@ 2026-09-21 9:05 ` Runyu Xiao
2026-09-22 13:29 ` Christoph Hellwig
2026-09-21 9:05 ` [PATCH v4 2/3] nvmet: avoid recursive configfs open for file-backed namespaces Runyu Xiao
2026-09-21 9:05 ` [PATCH v4 3/3] nvmet: avoid recursive configfs open for passthru Runyu Xiao
2 siblings, 1 reply; 8+ messages in thread
From: Runyu Xiao @ 2026-09-21 9:05 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Sagi Grimberg, Chaitanya Kulkarni, Andreas Hindborg,
Breno Leitao, linux-nvme, linux-kernel, stable, Runyu Xiao,
Jianhao Xu
Configfs store callbacks may open user-configured paths while holding an
item frag_sem. Opening a configfs path from such a callback can re-enter
configfs and try to acquire the same semaphore.
Add helpers that reject configfs paths by comparing the actual filesystem
type and open the resolved path with file_open_root(), preserving normal
open-time permission and security checks. Provide a root-relative form for
callers that retain a resolved root and may create a file below it.
Assisted-by: LLM Codex
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
---
fs/configfs/mount.c | 33 +++++++++++++++++++++++++++++++++
include/linux/configfs.h | 6 ++++++
2 files changed, 39 insertions(+)
diff --git a/fs/configfs/mount.c b/fs/configfs/mount.c
index d8cac1cbf3bd5..77e1788ce2372 100644
--- a/fs/configfs/mount.c
+++ b/fs/configfs/mount.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/mount.h>
#include <linux/fs_context.h>
+#include <linux/namei.h>
#include <linux/pagemap.h>
#include <linux/init.h>
#include <linux/slab.h>
@@ -118,6 +119,38 @@ static struct file_system_type configfs_fs_type = {
};
MODULE_ALIAS_FS("configfs");
+bool configfs_path_is_configfs(const struct path *path)
+{
+ return path->dentry->d_sb->s_type == &configfs_fs_type;
+}
+EXPORT_SYMBOL_GPL(configfs_path_is_configfs);
+
+struct file *configfs_open_root(const struct path *root, const char *name,
+ int flags, umode_t mode)
+{
+ if (configfs_path_is_configfs(root))
+ return ERR_PTR(-EINVAL);
+
+ return file_open_root(root, name, flags, mode);
+}
+EXPORT_SYMBOL_GPL(configfs_open_root);
+
+struct file *configfs_file_open(const char *filename, int flags, umode_t mode)
+{
+ struct file *file;
+ struct path path;
+ int ret;
+
+ ret = kern_path(filename, LOOKUP_FOLLOW, &path);
+ if (ret)
+ return ERR_PTR(ret);
+
+ file = configfs_open_root(&path, "", flags, mode);
+ path_put(&path);
+ return file;
+}
+EXPORT_SYMBOL_GPL(configfs_file_open);
+
struct dentry *configfs_pin_fs(void)
{
int err = simple_pin_fs(&configfs_fs_type, &configfs_mount,
diff --git a/include/linux/configfs.h b/include/linux/configfs.h
index ef65c75beeaad..768132b2be1ae 100644
--- a/include/linux/configfs.h
+++ b/include/linux/configfs.h
@@ -34,6 +34,8 @@ struct configfs_group_operations;
struct configfs_attribute;
struct configfs_bin_attribute;
struct configfs_subsystem;
+struct file;
+struct path;
struct config_item {
char *ci_name;
@@ -243,6 +245,10 @@ void configfs_unregister_subsystem(struct configfs_subsystem *subsys);
int configfs_register_group(struct config_group *parent_group,
struct config_group *group);
void configfs_unregister_group(struct config_group *group);
+bool configfs_path_is_configfs(const struct path *path);
+struct file *configfs_open_root(const struct path *root, const char *name,
+ int flags, umode_t mode);
+struct file *configfs_file_open(const char *filename, int flags, umode_t mode);
void configfs_remove_default_groups(struct config_group *group);
--
2.34.1
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH v4 1/3] fs: configfs: add helpers for opening non-configfs paths
2026-09-21 9:05 ` [PATCH v4 1/3] fs: configfs: add helpers for opening non-configfs paths Runyu Xiao
@ 2026-09-22 13:29 ` Christoph Hellwig
2026-09-23 2:39 ` Runyu Xiao
0 siblings, 1 reply; 8+ messages in thread
From: Christoph Hellwig @ 2026-09-22 13:29 UTC (permalink / raw)
To: Runyu Xiao
Cc: Christoph Hellwig, Sagi Grimberg, Chaitanya Kulkarni,
Andreas Hindborg, Breno Leitao, linux-nvme, linux-kernel, stable,
Jianhao Xu
On Mon, Sep 21, 2026 at 05:05:57PM +0800, Runyu Xiao wrote:
> +bool configfs_path_is_configfs(const struct path *path)
> +{
> + return path->dentry->d_sb->s_type == &configfs_fs_type;
> +}
> +EXPORT_SYMBOL_GPL(configfs_path_is_configfs);
> +
> +struct file *configfs_open_root(const struct path *root, const char *name,
> + int flags, umode_t mode)
> +{
> + if (configfs_path_is_configfs(root))
> + return ERR_PTR(-EINVAL);
> +
> + return file_open_root(root, name, flags, mode);
> +}
> +EXPORT_SYMBOL_GPL(configfs_open_root);
These two aren't used outside this file, so they could be static,
or in case of configfs_path_is_configfs even be folded into the
only caller. Or do you plan to have other users?
> +struct file *configfs_file_open(const char *filename, int flags, umode_t mode)
Can you add a kerneldoc comment explaining how/why this should be used?
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH v4 1/3] fs: configfs: add helpers for opening non-configfs paths
2026-09-22 13:29 ` Christoph Hellwig
@ 2026-09-23 2:39 ` Runyu Xiao
0 siblings, 0 replies; 8+ messages in thread
From: Runyu Xiao @ 2026-09-23 2:39 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Sagi Grimberg, Chaitanya Kulkarni, Andreas Hindborg,
Breno Leitao, linux-nvme, linux-kernel, stable, Jianhao Xu
Thanks for the reviews.
> > +bool configfs_path_is_configfs(const struct path *path)
> > +{
> > + return path->dentry->d_sb->s_type == &configfs_fs_type;
> > +}
> > +EXPORT_SYMBOL_GPL(configfs_path_is_configfs);
> > +
> > +struct file *configfs_open_root(const struct path *root, const char *name,
> > + int flags, umode_t mode)
> > +{
> > + if (configfs_path_is_configfs(root))
> > + return ERR_PTR(-EINVAL);
> > +
> > + return file_open_root(root, name, flags, mode);
> > +}
> > +EXPORT_SYMBOL_GPL(configfs_open_root);
>
> These two aren't used outside this file, so they could be static,
> or in case of configfs_path_is_configfs even be folded into the
> only caller. Or do you plan to have other users?
I folded the filesystem-type check into configfs_open_root() and dropped
the predicate entirely. configfs_file_open() is for callers that have a
pathname, while configfs_open_root() is for callers that keep a resolved
root and open files below it.
> > +struct file *configfs_file_open(const char *filename, int flags, umode_t mode)
>
> Can you add a kerneldoc comment explaining how/why this should be used?
I will add kerneldoc comments for both helpers in v5.
> Didn't you also have patches for drivers/target/ that should use
> the new helper?
Yes. The target-core patch titled "scsi: target: pin db_root for metadata
writes" is another consumer of configfs_open_root(). I will rebase that
patch on this series and drop its duplicate configfs changes.
The separate patch titled "scsi: target: file: avoid recursive configfs open
in fd_init_prot()" will use configfs_file_open(), not configfs_open_root().
I will send v5 as a new thread. Patches 2/3 and 3/3 are unchanged and
retain your Reviewed-by.
Thanks,
Runyu
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v4 2/3] nvmet: avoid recursive configfs open for file-backed namespaces
2026-09-21 9:05 [PATCH v4 0/3] nvmet: avoid recursive configfs open Runyu Xiao
2026-09-21 9:05 ` [PATCH v4 1/3] fs: configfs: add helpers for opening non-configfs paths Runyu Xiao
@ 2026-09-21 9:05 ` Runyu Xiao
2026-09-22 13:29 ` Christoph Hellwig
2026-09-21 9:05 ` [PATCH v4 3/3] nvmet: avoid recursive configfs open for passthru Runyu Xiao
2 siblings, 1 reply; 8+ messages in thread
From: Runyu Xiao @ 2026-09-21 9:05 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Sagi Grimberg, Chaitanya Kulkarni, Andreas Hindborg,
Breno Leitao, linux-nvme, linux-kernel, stable, Runyu Xiao,
Jianhao Xu
nvmet_ns_enable_store() runs as a configfs store callback while configfs
holds the item frag_sem. File-backed namespace enable used filp_open() on
the configured device_path, so a path into configfs could re-enter
__configfs_open_file() and try to acquire the same semaphore again.
Use configfs_file_open() so the path is resolved before opening,
configfs-backed paths are rejected, and the resolved path is opened with
file_open_root() while retaining the normal open-time permission and
security checks.
Fixes: d5eff33ee6f8 ("nvmet: add simple file backed ns support")
Cc: stable@vger.kernel.org
Assisted-by: LLM Codex
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
---
drivers/nvme/target/io-cmd-file.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/nvme/target/io-cmd-file.c b/drivers/nvme/target/io-cmd-file.c
index 0b22d183f9279..2a4f25de94ba1 100644
--- a/drivers/nvme/target/io-cmd-file.c
+++ b/drivers/nvme/target/io-cmd-file.c
@@ -8,6 +8,7 @@
#include <linux/uio.h>
#include <linux/falloc.h>
#include <linux/file.h>
+#include <linux/configfs.h>
#include <linux/fs.h>
#include "nvmet.h"
@@ -38,7 +39,7 @@ int nvmet_file_ns_enable(struct nvmet_ns *ns)
if (!ns->buffered_io)
flags |= O_DIRECT;
- ns->file = filp_open(ns->device_path, flags, 0);
+ ns->file = configfs_file_open(ns->device_path, flags, 0);
if (IS_ERR(ns->file)) {
ret = PTR_ERR(ns->file);
pr_err("failed to open file %s: (%d)\n",
--
2.34.1
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH v4 3/3] nvmet: avoid recursive configfs open for passthru
2026-09-21 9:05 [PATCH v4 0/3] nvmet: avoid recursive configfs open Runyu Xiao
2026-09-21 9:05 ` [PATCH v4 1/3] fs: configfs: add helpers for opening non-configfs paths Runyu Xiao
2026-09-21 9:05 ` [PATCH v4 2/3] nvmet: avoid recursive configfs open for file-backed namespaces Runyu Xiao
@ 2026-09-21 9:05 ` Runyu Xiao
2026-09-22 13:29 ` Christoph Hellwig
2 siblings, 1 reply; 8+ messages in thread
From: Runyu Xiao @ 2026-09-21 9:05 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Sagi Grimberg, Chaitanya Kulkarni, Andreas Hindborg,
Breno Leitao, linux-nvme, linux-kernel, stable, Runyu Xiao,
Jianhao Xu
nvmet_passthru_enable_store() runs as a configfs store callback while
configfs holds the item frag_sem. Passthru enable used filp_open() on the
configured controller path, so a path into configfs could re-enter
__configfs_open_file() and try to acquire the same semaphore again.
Use configfs_file_open() so the path is resolved before opening,
configfs-backed paths are rejected, and the resolved path is opened with
file_open_root() while retaining the normal open-time permission and
security checks.
Fixes: cae5b01a2afc ("nvmet: introduce the passthru configfs interface")
Cc: stable@vger.kernel.org
Assisted-by: LLM Codex
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
---
drivers/nvme/target/passthru.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/nvme/target/passthru.c b/drivers/nvme/target/passthru.c
index fa6527c537e26..d60256004e6cf 100644
--- a/drivers/nvme/target/passthru.c
+++ b/drivers/nvme/target/passthru.c
@@ -9,6 +9,7 @@
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
+#include <linux/configfs.h>
#include "../host/nvme.h"
#include "nvmet.h"
@@ -602,7 +603,7 @@ int nvmet_passthru_ctrl_enable(struct nvmet_subsys *subsys)
goto out_unlock;
}
- file = filp_open(subsys->passthru_ctrl_path, O_RDWR, 0);
+ file = configfs_file_open(subsys->passthru_ctrl_path, O_RDWR, 0);
if (IS_ERR(file)) {
ret = PTR_ERR(file);
goto out_unlock;
--
2.34.1
^ permalink raw reply [flat|nested] 8+ messages in thread