mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 11:25:21 +01:00
zfs_domount: fix vfs_t double-free on root setup failure
When zfs_root() or d_make_root() fails, zfs_domount() calls zfs_umount(), which frees zfsvfs->z_vfs via zfsvfs_free(). After the vfs_t lifetime was matched to fs_context, that vfs_t is still owned by the caller in fc->fs_private. zpl_get_tree() then returns without clearing fs_private, and put_fs_context() frees it again. Detach z_vfs before zfs_umount() so the caller retains ownership, matching the other zfs_domount() error paths. This is a follow-up to the vfs_t lifetime change in #18377. Reviewed-by: Rob Norris <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Wale Zhang <[email protected]> Closes #19167
This commit is contained in:
1 file changed
+4
@@ -1491,6 +1491,8 @@ zfs_domount(struct super_block *sb, const char *osname,
|
||||
/* Allocate a root inode for the filesystem. */
|
||||
error = zfs_root(zfsvfs, &root_inode);
|
||||
if (error) {
|
||||
/* Caller still owns vfs_t; detach before zfs_umount(). */
|
||||
zfsvfs->z_vfs = NULL;
|
||||
(void) zfs_umount(sb);
|
||||
zfsvfs = NULL; /* avoid double-free; first in zfs_umount */
|
||||
goto out;
|
||||
@@ -1499,6 +1501,8 @@ zfs_domount(struct super_block *sb, const char *osname,
|
||||
/* Allocate a root dentry for the filesystem */
|
||||
sb->s_root = d_make_root(root_inode);
|
||||
if (sb->s_root == NULL) {
|
||||
/* Caller still owns vfs_t; detach before zfs_umount(). */
|
||||
zfsvfs->z_vfs = NULL;
|
||||
(void) zfs_umount(sb);
|
||||
zfsvfs = NULL; /* avoid double-free; first in zfs_umount */
|
||||
error = SET_ERROR(ENOMEM);
|
||||
|
||||
Reference in new issue
Block a user