mirror of
https://github.com/torvalds/linux.git
synced 2026-09-11 20:13:02 +02:00
ufs: create the root dentry after loading cylinder metadata
ufs_fill_super() installed sb->s_root before it loaded the cylinder
group structures for a writable mount:
sb->s_root = d_make_root(inode);
...
if (!sb_rdonly(sb))
if (!ufs_read_cylinder_structures(sb))
goto failed;
When ufs_read_cylinder_structures() failed, the error path freed the
in-core superblock information and set sb->s_fs_info to NULL while
sb->s_root stayed installed. get_tree_bdev() then reached
deactivate_locked_super(), and because s_root was present,
generic_shutdown_super() called sync_filesystem() and the put_super
operation. Both dereference UFS_SB(sb), which is now NULL, so a mount
that fails only while reading the cylinder groups oopses during
teardown. A crafted image whose first cylinder group cannot be read
reaches this path.
Load the cylinder group metadata first and create the root dentry last,
so the superblock is published to the VFS only once it is fully set up.
ufs_setup_cstotal() and ufs_read_cylinder_structures() take only the
super_block and do not use the root inode, so the reordering is safe.
Fixes: 1da177e4c3 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Ali Ahmet Memis <ali@iusegentoo.com>
Link: https://patch.msgid.link/20260801071306.59484-2-ali@iusegentoo.com
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
This commit is contained in:
parent
82e9343260
commit
55a4c98abb
|
|
@ -1199,6 +1199,15 @@ static int ufs_fill_super(struct super_block *sb, struct fs_context *fc)
|
|||
sb->s_maxbytes = ufs_max_bytes(sb);
|
||||
sb->s_max_links = UFS_LINK_MAX;
|
||||
|
||||
ufs_setup_cstotal(sb);
|
||||
/*
|
||||
* Read cylinder group structures
|
||||
*/
|
||||
if (!sb_rdonly(sb))
|
||||
if (!ufs_read_cylinder_structures(sb))
|
||||
goto failed;
|
||||
|
||||
/* create the root dentry last, once UFS_SB(sb) is fully set up */
|
||||
inode = ufs_iget(sb, UFS_ROOTINO);
|
||||
if (IS_ERR(inode)) {
|
||||
ret = PTR_ERR(inode);
|
||||
|
|
@ -1210,14 +1219,6 @@ static int ufs_fill_super(struct super_block *sb, struct fs_context *fc)
|
|||
goto failed;
|
||||
}
|
||||
|
||||
ufs_setup_cstotal(sb);
|
||||
/*
|
||||
* Read cylinder group structures
|
||||
*/
|
||||
if (!sb_rdonly(sb))
|
||||
if (!ufs_read_cylinder_structures(sb))
|
||||
goto failed;
|
||||
|
||||
UFSD("EXIT\n");
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user