| From e3a43f2a95393000778f8f302d48795add2fc4a8 Mon Sep 17 00:00:00 2001 |
| From: Greg Kurz <groug@kaod.org> |
| Date: Fri, 4 Jun 2021 18:11:51 +0200 |
| Subject: fuse: Fix crash if superblock of submount gets killed early |
| |
| From: Greg Kurz <groug@kaod.org> |
| |
| commit e3a43f2a95393000778f8f302d48795add2fc4a8 upstream. |
| |
| As soon as fuse_dentry_automount() does up_write(&sb->s_umount), the |
| superblock can theoretically be killed. If this happens before the |
| submount was added to the &fc->mounts list, fuse_mount_remove() later |
| crashes in list_del_init() because it assumes the submount to be |
| already there. |
| |
| Add the submount before dropping sb->s_umount to fix the inconsistency. |
| It is okay to nest fc->killsb under sb->s_umount, we already do this |
| on the ->kill_sb() path. |
| |
| Signed-off-by: Greg Kurz <groug@kaod.org> |
| Fixes: bf109c64040f ("fuse: implement crossmounts") |
| Cc: stable@vger.kernel.org # v5.10+ |
| Reviewed-by: Max Reitz <mreitz@redhat.com> |
| Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| fs/fuse/dir.c | 8 ++++---- |
| 1 file changed, 4 insertions(+), 4 deletions(-) |
| |
| --- a/fs/fuse/dir.c |
| +++ b/fs/fuse/dir.c |
| @@ -347,15 +347,15 @@ static struct vfsmount *fuse_dentry_auto |
| goto out_put_sb; |
| } |
| |
| + down_write(&fc->killsb); |
| + list_add_tail(&fm->fc_entry, &fc->mounts); |
| + up_write(&fc->killsb); |
| + |
| sb->s_flags |= SB_ACTIVE; |
| fsc->root = dget(sb->s_root); |
| /* We are done configuring the superblock, so unlock it */ |
| up_write(&sb->s_umount); |
| |
| - down_write(&fc->killsb); |
| - list_add_tail(&fm->fc_entry, &fc->mounts); |
| - up_write(&fc->killsb); |
| - |
| /* Create the submount */ |
| mnt = vfs_create_mount(fsc); |
| if (IS_ERR(mnt)) { |