Re: [PATCH 1/2] ufs: create the root dentry after loading cylinder metadata

Jan Kara <[email protected]>
Newsgroups gmane.linux.kernel,gmane.linux.file-systems,gmane.linux.kernel.stable
Message-ID <q6zgjx7g3ciaxfbc6wnmgafuc6bsyz53opvljuogfblwxy45hb@nkpbchrwbngx>
On Sat 01-08-26 10:12:57, Ali Ahmet Memis wrote:
> 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: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> Cc: [email protected]
> Signed-off-by: Ali Ahmet Memis <[email protected]>

Looks good. Feel free to add:

Reviewed-by: Jan Kara <[email protected]>

								Honza

> ---
>  fs/ufs/super.c | 17 +++++++++--------
>  1 file changed, 9 insertions(+), 8 deletions(-)
> 
> diff --git a/fs/ufs/super.c b/fs/ufs/super.c
> index c4831a8b9..7deecb395 100644
> --- a/fs/ufs/super.c
> +++ b/fs/ufs/super.c
> @@ -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;
>  
> -- 
> 2.54.0
> 
-- 
Jan Kara <[email protected]>
SUSE Labs, CR
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.