Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

fs: improve dump_inode() to safely access inode fields

Use get_kernel_nofault() to safely access inode and related structures
(superblock, file_system_type) to avoid crashing when the inode pointer
is invalid. This allows the same pattern as dump_mapping().

Note: The original access method for i_state and i_count is preserved,
as get_kernel_nofault() is unnecessary once the inode structure is
verified accessible.

Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Yuto Ohnuki <ytohnuki@amazon.com>
Link: https://patch.msgid.link/20260112181443.81286-1-ytohnuki@amazon.com
Reviewed-by: Mateusz Guzik <mjguzik@gmail.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>

authored by

Yuto Ohnuki and committed by
Christian Brauner
7c022500 58ecde96

+34 -13
+34 -13
fs/inode.c
··· 2984 2984 EXPORT_SYMBOL(mode_strip_sgid); 2985 2985 2986 2986 #ifdef CONFIG_DEBUG_VFS 2987 - /* 2988 - * Dump an inode. 2987 + /** 2988 + * dump_inode - dump an inode. 2989 + * @inode: inode to dump 2990 + * @reason: reason for dumping 2989 2991 * 2990 - * TODO: add a proper inode dumping routine, this is a stub to get debug off the 2991 - * ground. 2992 - * 2993 - * TODO: handle getting to fs type with get_kernel_nofault()? 2994 - * See dump_mapping() above. 2992 + * If inode is an invalid pointer, we don't want to crash accessing it, 2993 + * so probe everything depending on it carefully with get_kernel_nofault(). 2995 2994 */ 2996 2995 void dump_inode(struct inode *inode, const char *reason) 2997 2996 { 2998 - struct super_block *sb = inode->i_sb; 2997 + struct super_block *sb; 2998 + struct file_system_type *s_type; 2999 + const char *fs_name_ptr; 3000 + char fs_name[32] = {}; 3001 + umode_t mode; 3002 + unsigned short opflags; 3003 + unsigned int flags; 3004 + unsigned int state; 3005 + int count; 2999 3006 3000 - pr_warn("%s encountered for inode %px\n" 3001 - "fs %s mode %ho opflags 0x%hx flags 0x%x state 0x%x count %d\n", 3002 - reason, inode, sb->s_type->name, inode->i_mode, inode->i_opflags, 3003 - inode->i_flags, inode_state_read_once(inode), atomic_read(&inode->i_count)); 3007 + if (get_kernel_nofault(sb, &inode->i_sb) || 3008 + get_kernel_nofault(mode, &inode->i_mode) || 3009 + get_kernel_nofault(opflags, &inode->i_opflags) || 3010 + get_kernel_nofault(flags, &inode->i_flags)) { 3011 + pr_warn("%s: unreadable inode:%px\n", reason, inode); 3012 + return; 3013 + } 3014 + 3015 + state = inode_state_read_once(inode); 3016 + count = atomic_read(&inode->i_count); 3017 + 3018 + if (!sb || 3019 + get_kernel_nofault(s_type, &sb->s_type) || !s_type || 3020 + get_kernel_nofault(fs_name_ptr, &s_type->name) || !fs_name_ptr || 3021 + strncpy_from_kernel_nofault(fs_name, fs_name_ptr, sizeof(fs_name) - 1) < 0) 3022 + strscpy(fs_name, "<unknown, sb unreadable>"); 3023 + 3024 + pr_warn("%s: inode:%px fs:%s mode:%ho opflags:%#x flags:%#x state:%#x count:%d\n", 3025 + reason, inode, fs_name, mode, opflags, flags, state, count); 3004 3026 } 3005 - 3006 3027 EXPORT_SYMBOL(dump_inode); 3007 3028 #endif