fs/inode.c | 47 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 13 deletions(-)
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>
---
Changes in v3:
- Avoided pr_warn duplication for long-term maintainability.
- Changed "invalid inode" to "unreadable inode", and clearly denote the
situation where sb is unreadable as suggested by Mateusz Guzik.
- Added passed reason to all pr_warn outputs.
- Used %# format specifier for printing hex values, verified to
work as expected.
- Link to v2: https://lore.kernel.org/linux-fsdevel/20260109154019.74717-1-ytohnuki@amazon.com/
Changes in v2:
- Merged NULL inode->i_sb check with invalid sb check as pointed out
by Jan Kara.
- Link to v1: https://lore.kernel.org/linux-fsdevel/20260101165304.34516-1-ytohnuki@amazon.com/
---
fs/inode.c | 47 ++++++++++++++++++++++++++++++++++-------------
1 file changed, 34 insertions(+), 13 deletions(-)
diff --git a/fs/inode.c b/fs/inode.c
index 521383223d8a..440ae05f9df5 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -2984,24 +2984,45 @@ umode_t mode_strip_sgid(struct mnt_idmap *idmap,
EXPORT_SYMBOL(mode_strip_sgid);
#ifdef CONFIG_DEBUG_VFS
-/*
- * Dump an inode.
- *
- * TODO: add a proper inode dumping routine, this is a stub to get debug off the
- * ground.
+/**
+ * dump_inode - dump an inode.
+ * @inode: inode to dump
+ * @reason: reason for dumping
*
- * TODO: handle getting to fs type with get_kernel_nofault()?
- * See dump_mapping() above.
+ * If inode is an invalid pointer, we don't want to crash accessing it,
+ * so probe everything depending on it carefully with get_kernel_nofault().
*/
void dump_inode(struct inode *inode, const char *reason)
{
- struct super_block *sb = inode->i_sb;
+ struct super_block *sb;
+ struct file_system_type *s_type;
+ const char *fs_name_ptr;
+ char fs_name[32] = {};
+ umode_t mode;
+ unsigned short opflags;
+ unsigned int flags;
+ unsigned int state;
+ int count;
+
+ if (get_kernel_nofault(sb, &inode->i_sb) ||
+ get_kernel_nofault(mode, &inode->i_mode) ||
+ get_kernel_nofault(opflags, &inode->i_opflags) ||
+ get_kernel_nofault(flags, &inode->i_flags)) {
+ pr_warn("%s: unreadable inode:%px\n", reason, inode);
+ return;
+ }
- pr_warn("%s encountered for inode %px\n"
- "fs %s mode %ho opflags 0x%hx flags 0x%x state 0x%x count %d\n",
- reason, inode, sb->s_type->name, inode->i_mode, inode->i_opflags,
- inode->i_flags, inode_state_read_once(inode), atomic_read(&inode->i_count));
-}
+ state = inode_state_read_once(inode);
+ count = atomic_read(&inode->i_count);
+ if (!sb ||
+ get_kernel_nofault(s_type, &sb->s_type) || !s_type ||
+ get_kernel_nofault(fs_name_ptr, &s_type->name) || !fs_name_ptr ||
+ strncpy_from_kernel_nofault(fs_name, fs_name_ptr, sizeof(fs_name) - 1) < 0)
+ strscpy(fs_name, "<unknown, sb unreadable>");
+
+ pr_warn("%s: inode:%px fs:%s mode:%ho opflags:%#x flags:%#x state:%#x count:%d\n",
+ reason, inode, fs_name, mode, opflags, flags, state, count);
+}
EXPORT_SYMBOL(dump_inode);
#endif
--
2.50.1
Amazon Web Services EMEA SARL, 38 avenue John F. Kennedy, L-1855 Luxembourg, R.C.S. Luxembourg B186284
Amazon Web Services EMEA SARL, Irish Branch, One Burlington Plaza, Burlington Road, Dublin 4, Ireland, branch registration number 908705
On Mon, 12 Jan 2026 18:14:43 +0000, Yuto Ohnuki wrote:
> 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.
>
> [...]
Applied to the vfs-7.0.misc branch of the vfs/vfs.git tree.
Patches in the vfs-7.0.misc branch should appear in linux-next soon.
Please report any outstanding bugs that were missed during review in a
new review to the original patch series allowing us to drop it.
It's encouraged to provide Acked-bys and Reviewed-bys even though the
patch has now been applied. If possible patch trailers will be updated.
Note that commit hashes shown below are subject to change due to rebase,
trailer updates or similar. If in doubt, please check the listed branch.
tree: https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git
branch: vfs-7.0.misc
[1/1] fs: improve dump_inode() to safely access inode fields
https://git.kernel.org/vfs/vfs/c/92828c00fcd3
On Mon, Jan 12, 2026 at 7:14 PM Yuto Ohnuki <ytohnuki@amazon.com> wrote:
>
> 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>
> ---
> Changes in v3:
> - Avoided pr_warn duplication for long-term maintainability.
> - Changed "invalid inode" to "unreadable inode", and clearly denote the
> situation where sb is unreadable as suggested by Mateusz Guzik.
> - Added passed reason to all pr_warn outputs.
> - Used %# format specifier for printing hex values, verified to
> work as expected.
> - Link to v2: https://lore.kernel.org/linux-fsdevel/20260109154019.74717-1-ytohnuki@amazon.com/
>
> Changes in v2:
> - Merged NULL inode->i_sb check with invalid sb check as pointed out
> by Jan Kara.
> - Link to v1: https://lore.kernel.org/linux-fsdevel/20260101165304.34516-1-ytohnuki@amazon.com/
> ---
> fs/inode.c | 47 ++++++++++++++++++++++++++++++++++-------------
> 1 file changed, 34 insertions(+), 13 deletions(-)
>
> diff --git a/fs/inode.c b/fs/inode.c
> index 521383223d8a..440ae05f9df5 100644
> --- a/fs/inode.c
> +++ b/fs/inode.c
> @@ -2984,24 +2984,45 @@ umode_t mode_strip_sgid(struct mnt_idmap *idmap,
> EXPORT_SYMBOL(mode_strip_sgid);
>
> #ifdef CONFIG_DEBUG_VFS
> -/*
> - * Dump an inode.
> - *
> - * TODO: add a proper inode dumping routine, this is a stub to get debug off the
> - * ground.
> +/**
> + * dump_inode - dump an inode.
> + * @inode: inode to dump
> + * @reason: reason for dumping
> *
> - * TODO: handle getting to fs type with get_kernel_nofault()?
> - * See dump_mapping() above.
> + * If inode is an invalid pointer, we don't want to crash accessing it,
> + * so probe everything depending on it carefully with get_kernel_nofault().
> */
> void dump_inode(struct inode *inode, const char *reason)
> {
> - struct super_block *sb = inode->i_sb;
> + struct super_block *sb;
> + struct file_system_type *s_type;
> + const char *fs_name_ptr;
> + char fs_name[32] = {};
> + umode_t mode;
> + unsigned short opflags;
> + unsigned int flags;
> + unsigned int state;
> + int count;
> +
> + if (get_kernel_nofault(sb, &inode->i_sb) ||
> + get_kernel_nofault(mode, &inode->i_mode) ||
> + get_kernel_nofault(opflags, &inode->i_opflags) ||
> + get_kernel_nofault(flags, &inode->i_flags)) {
> + pr_warn("%s: unreadable inode:%px\n", reason, inode);
> + return;
> + }
>
> - pr_warn("%s encountered for inode %px\n"
> - "fs %s mode %ho opflags 0x%hx flags 0x%x state 0x%x count %d\n",
> - reason, inode, sb->s_type->name, inode->i_mode, inode->i_opflags,
> - inode->i_flags, inode_state_read_once(inode), atomic_read(&inode->i_count));
> -}
> + state = inode_state_read_once(inode);
> + count = atomic_read(&inode->i_count);
>
> + if (!sb ||
> + get_kernel_nofault(s_type, &sb->s_type) || !s_type ||
> + get_kernel_nofault(fs_name_ptr, &s_type->name) || !fs_name_ptr ||
> + strncpy_from_kernel_nofault(fs_name, fs_name_ptr, sizeof(fs_name) - 1) < 0)
> + strscpy(fs_name, "<unknown, sb unreadable>");
> +
> + pr_warn("%s: inode:%px fs:%s mode:%ho opflags:%#x flags:%#x state:%#x count:%d\n",
> + reason, inode, fs_name, mode, opflags, flags, state, count);
> +}
> EXPORT_SYMBOL(dump_inode);
> #endif
nice, thank you
Reviewed-by: Mateusz Guzik <mjguzik@gmail.com>
> --
> 2.50.1
>
>
>
>
> Amazon Web Services EMEA SARL, 38 avenue John F. Kennedy, L-1855 Luxembourg, R.C.S. Luxembourg B186284
>
> Amazon Web Services EMEA SARL, Irish Branch, One Burlington Plaza, Burlington Road, Dublin 4, Ireland, branch registration number 908705
>
>
>
© 2016 - 2026 Red Hat, Inc.