Skip to content

Commit 8ff006e

Browse files
committed
exfat: fix use of uninitialized spinlock on error path
syzbot reported warning message: Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x1d6/0x29e lib/dump_stack.c:118 register_lock_class+0xf06/0x1520 kernel/locking/lockdep.c:893 __lock_acquire+0xfd/0x2ae0 kernel/locking/lockdep.c:4320 lock_acquire+0x148/0x720 kernel/locking/lockdep.c:5029 __raw_spin_lock include/linux/spinlock_api_smp.h:142 [inline] _raw_spin_lock+0x2a/0x40 kernel/locking/spinlock.c:151 spin_lock include/linux/spinlock.h:354 [inline] exfat_cache_inval_inode+0x30/0x280 fs/exfat/cache.c:226 exfat_evict_inode+0x124/0x270 fs/exfat/inode.c:660 evict+0x2bb/0x6d0 fs/inode.c:576 exfat_fill_super+0x1e07/0x27d0 fs/exfat/super.c:681 get_tree_bdev+0x3e9/0x5f0 fs/super.c:1342 vfs_get_tree+0x88/0x270 fs/super.c:1547 do_new_mount fs/namespace.c:2875 [inline] path_mount+0x179d/0x29e0 fs/namespace.c:3192 do_mount fs/namespace.c:3205 [inline] __do_sys_mount fs/namespace.c:3413 [inline] __se_sys_mount+0x126/0x180 fs/namespace.c:3390 do_syscall_64+0x31/0x70 arch/x86/entry/common.c:46 entry_SYSCALL_64_after_hwframe+0x44/0xa9 If exfat_read_root() returns an error, spinlock is used in exfat_evict_inode() without initialization. This patch combines exfat_cache_init_inode() with exfat_inode_init_once() to initialize spinlock by slab constructor. Fixes: c35b681 ("exfat: add exfat cache") Cc: stable@vger.kernel.org # v5.7+ Reported-by: syzbot <syzbot+b91107320911a26c9a95@syzkaller.appspotmail.com> Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>
1 parent d6c9efd commit 8ff006e

4 files changed

Lines changed: 6 additions & 15 deletions

File tree

fs/exfat/cache.c

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#include "exfat_raw.h"
1818
#include "exfat_fs.h"
1919

20-
#define EXFAT_CACHE_VALID 0
2120
#define EXFAT_MAX_CACHE 16
2221

2322
struct exfat_cache {
@@ -61,16 +60,6 @@ void exfat_cache_shutdown(void)
6160
kmem_cache_destroy(exfat_cachep);
6261
}
6362

64-
void exfat_cache_init_inode(struct inode *inode)
65-
{
66-
struct exfat_inode_info *ei = EXFAT_I(inode);
67-
68-
spin_lock_init(&ei->cache_lru_lock);
69-
ei->nr_caches = 0;
70-
ei->cache_valid_id = EXFAT_CACHE_VALID + 1;
71-
INIT_LIST_HEAD(&ei->cache_lru);
72-
}
73-
7463
static inline struct exfat_cache *exfat_cache_alloc(void)
7564
{
7665
return kmem_cache_alloc(exfat_cachep, GFP_NOFS);

fs/exfat/exfat_fs.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,8 @@ struct exfat_sb_info {
248248
struct rcu_head rcu;
249249
};
250250

251+
#define EXFAT_CACHE_VALID 0
252+
251253
/*
252254
* EXFAT file system inode in-memory data
253255
*/
@@ -428,7 +430,6 @@ extern const struct dentry_operations exfat_utf8_dentry_ops;
428430
/* cache.c */
429431
int exfat_cache_init(void);
430432
void exfat_cache_shutdown(void);
431-
void exfat_cache_init_inode(struct inode *inode);
432433
void exfat_cache_inval_inode(struct inode *inode);
433434
int exfat_get_cluster(struct inode *inode, unsigned int cluster,
434435
unsigned int *fclus, unsigned int *dclus,

fs/exfat/inode.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -611,8 +611,6 @@ static int exfat_fill_inode(struct inode *inode, struct exfat_dir_entry *info)
611611
ei->i_crtime = info->crtime;
612612
inode->i_atime = info->atime;
613613

614-
exfat_cache_init_inode(inode);
615-
616614
return 0;
617615
}
618616

fs/exfat/super.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,6 @@ static int exfat_read_root(struct inode *inode)
376376
inode->i_mtime = inode->i_atime = inode->i_ctime = ei->i_crtime =
377377
current_time(inode);
378378
exfat_truncate_atime(&inode->i_atime);
379-
exfat_cache_init_inode(inode);
380379
return 0;
381380
}
382381

@@ -763,6 +762,10 @@ static void exfat_inode_init_once(void *foo)
763762
{
764763
struct exfat_inode_info *ei = (struct exfat_inode_info *)foo;
765764

765+
spin_lock_init(&ei->cache_lru_lock);
766+
ei->nr_caches = 0;
767+
ei->cache_valid_id = EXFAT_CACHE_VALID + 1;
768+
INIT_LIST_HEAD(&ei->cache_lru);
766769
INIT_HLIST_NODE(&ei->i_hash_fat);
767770
inode_init_once(&ei->vfs_inode);
768771
}

0 commit comments

Comments
 (0)