autofs: add: new_inode check in autofs_fill_super()

Add missing NULL check of root_inode in autofs_fill_super().

While we are at it simplify the logic by taking advantage of the VFS
cleanup procedures and get rid of the goto error handling, as suggested
by Al Viro.

Signed-off-by: Ian Kent <raven@themaw.net>
Link: https://lore.kernel.org/r/20231119225319.331156-1-raven@themaw.net
Reviewed-by: Bill O'Donnell <bodonnel@redhat.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Bill O'Donnell <billodo@redhat.com>
Reported-by: <syzbot+662f87a8ef490f45fa64@syzkaller.appspotmail.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
Ian Kent 2023-11-20 06:53:19 +08:00 committed by Christian Brauner
parent fe2c34bab6
commit 66917f85db
1 changed files with 21 additions and 35 deletions

View File

@ -309,9 +309,7 @@ static int autofs_fill_super(struct super_block *s, struct fs_context *fc)
struct autofs_fs_context *ctx = fc->fs_private; struct autofs_fs_context *ctx = fc->fs_private;
struct autofs_sb_info *sbi = s->s_fs_info; struct autofs_sb_info *sbi = s->s_fs_info;
struct inode *root_inode; struct inode *root_inode;
struct dentry *root;
struct autofs_info *ino; struct autofs_info *ino;
int ret = -ENOMEM;
pr_debug("starting up, sbi = %p\n", sbi); pr_debug("starting up, sbi = %p\n", sbi);
@ -328,56 +326,44 @@ static int autofs_fill_super(struct super_block *s, struct fs_context *fc)
*/ */
ino = autofs_new_ino(sbi); ino = autofs_new_ino(sbi);
if (!ino) if (!ino)
goto fail; return -ENOMEM;
root_inode = autofs_get_inode(s, S_IFDIR | 0755); root_inode = autofs_get_inode(s, S_IFDIR | 0755);
if (!root_inode)
return -ENOMEM;
root_inode->i_uid = ctx->uid; root_inode->i_uid = ctx->uid;
root_inode->i_gid = ctx->gid; root_inode->i_gid = ctx->gid;
root_inode->i_fop = &autofs_root_operations;
root_inode->i_op = &autofs_dir_inode_operations;
root = d_make_root(root_inode); s->s_root = d_make_root(root_inode);
if (!root) if (unlikely(!s->s_root)) {
goto fail_ino; autofs_free_ino(ino);
return -ENOMEM;
root->d_fsdata = ino; }
s->s_root->d_fsdata = ino;
if (ctx->pgrp_set) { if (ctx->pgrp_set) {
sbi->oz_pgrp = find_get_pid(ctx->pgrp); sbi->oz_pgrp = find_get_pid(ctx->pgrp);
if (!sbi->oz_pgrp) { if (!sbi->oz_pgrp)
ret = invalf(fc, "Could not find process group %d", return invalf(fc, "Could not find process group %d",
ctx->pgrp); ctx->pgrp);
goto fail_dput; } else
}
} else {
sbi->oz_pgrp = get_task_pid(current, PIDTYPE_PGID); sbi->oz_pgrp = get_task_pid(current, PIDTYPE_PGID);
}
if (autofs_type_trigger(sbi->type)) if (autofs_type_trigger(sbi->type))
__managed_dentry_set_managed(root); /* s->s_root won't be contended so there's little to
* be gained by not taking the d_lock when setting
root_inode->i_fop = &autofs_root_operations; * d_flags, even when a lot mounts are being done.
root_inode->i_op = &autofs_dir_inode_operations; */
managed_dentry_set_managed(s->s_root);
pr_debug("pipe fd = %d, pgrp = %u\n", pr_debug("pipe fd = %d, pgrp = %u\n",
sbi->pipefd, pid_nr(sbi->oz_pgrp)); sbi->pipefd, pid_nr(sbi->oz_pgrp));
sbi->flags &= ~AUTOFS_SBI_CATATONIC; sbi->flags &= ~AUTOFS_SBI_CATATONIC;
/*
* Success! Install the root dentry now to indicate completion.
*/
s->s_root = root;
return 0; return 0;
/*
* Failure ... clean up.
*/
fail_dput:
dput(root);
goto fail;
fail_ino:
autofs_free_ino(ino);
fail:
return ret;
} }
/* /*