[PATCH] configfs: Delay the fop setting to prevent noise generated by open
From: Edward Adam Davis
Date: Wed Oct 21 2026 - 02:32:32 EST
mkdir() triggers:
configfs_mkdir() ->
configfs_attach_group() ->
populate_groups() ->
create_default_group("ana_groups") ->
configfs_attach_group() ->
populate_groups() ->
create_default_group("1")
The creation of an inode for the subdentry 1 under ana_groups failed
due to fault injection. [1]
Because helper threads are racing open() on ana_groups, ana_groups has
dentry refcount > 1. d_delete() skips dentry_unlink_inode(), leaving
d_inode non-NULL. create_default_group() hits BUG_ON(d_inode(child)) at
fs/configfs/dir.c:734! [2]
[1]
FAULT_INJECTION: forcing a failure.
name failslab, interval 1, probability 0, space 0, times -1
Call Trace:
should_failslab+0xa8/0x100
kmem_cache_alloc_noprof+0xa1/0x600
security_inode_alloc+0x39/0x310
inode_init_always_gfp+0x97e/0xd30
alloc_inode+0x82/0x1b0
new_inode+0x1f/0x170
configfs_new_inode+0x27/0x410
configfs_create+0xb5/0x270
configfs_attach_item+0x25f/0xd60
configfs_attach_group+0x2a/0x370
create_default_group+0x87/0x180
configfs_attach_group+0x169/0x370
configfs_mkdir+0x6f0/0x9e0
vfs_mkdir+0x40c/0x620
[2]
kernel BUG at fs/configfs/dir.c:734!
Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI
RIP: 0010:create_default_group+0x17c/0x180
Call Trace:
configfs_attach_group+0x169/0x370
configfs_mkdir+0x6f0/0x9e0
vfs_mkdir+0x40c/0x620
The root cause is a race condition between open and mkdir; delaying the
assignment of the fop ensures that directories are not opened before they
are ready.
Fixes: 7063fbf22611 ("[PATCH] configfs: User-driven configuration filesystem")
Reported-by: syzbot+4fae162886e497f72228@xxxxxxxxxxxxxxxxxxxxxxxxx
Closes: https://syzkaller.appspot.com/bug?extid=4fae162886e497f72228
Signed-off-by: Edward Adam Davis <eadavis@xxxxxxxx>
---
fs/configfs/dir.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c
index eda80c2a2d38..45a955b8ab36 100644
--- a/fs/configfs/dir.c
+++ b/fs/configfs/dir.c
@@ -313,7 +313,6 @@ static int configfs_create_dir(struct config_item *item, struct dentry *dentry,
goto out_remove;
inode->i_op = &configfs_dir_inode_operations;
- inode->i_fop = &configfs_dir_operations;
/* directory inodes start off with i_nlink == 2 (for "." entry) */
inc_nlink(inode);
d_make_persistent(dentry, inode);
@@ -930,6 +929,10 @@ static int configfs_attach_group(struct config_item *item,
inode_unlock(d_inode(dentry));
if (ret)
d_delete(dentry);
+ else {
+ struct inode *inode = d_inode(dentry);
+ inode->i_fop = &configfs_dir_operations;
+ }
}
return ret;
@@ -1430,8 +1433,13 @@ static struct dentry *configfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
if (group)
ret = configfs_attach_group(item, dentry, frag);
- else
+ else {
ret = configfs_attach_item(item, dentry, frag);
+ if (!ret) {
+ struct inode *inode = d_inode(dentry);
+ inode->i_fop = &configfs_dir_operations;
+ }
+ }
spin_lock(&configfs_dirent_lock);
sd->s_type &= ~CONFIGFS_USET_IN_MKDIR;
--
2.43.0