Skip to content
  • Eric W. Biederman's avatar
    mnt: In umount propagation reparent in a separate pass · 570487d3
    Eric W. Biederman authored
    It was observed that in some pathlogical cases that the current code
    does not unmount everything it should.  After investigation it
    was determined that the issue is that mnt_change_mntpoint can
    can change which mounts are available to be unmounted during mount
    propagation which is wrong.
    
    The trivial reproducer is:
    $ cat ./pathological.sh
    
    mount -t tmpfs test-base /mnt
    cd /mnt
    mkdir 1 2 1/1
    mount --bind 1 1
    mount --make-shared 1
    mount --bind 1 2
    mount --bind 1/1 1/1
    mount --bind 1/1 1/1
    echo
    grep test-base /proc/self/mountinfo
    umount 1/1
    echo
    grep test-base /proc/self/mountinfo
    
    $ unshare -Urm ./pathological.sh
    
    The expected output looks like:
    46 31 0:25 / /mnt rw,relatime - tmpfs test-base rw,uid=1000,gid=1000
    47 46 0:25 /1 /mnt/1 rw,relatime shared:1 - tmpfs test-base rw,uid=1000,gid=1000
    48 46 0:25 /1 /mnt/2 rw,relatime shared:1 - tmpfs test-base rw,uid=1000,gid=1000
    49 54 0:25 /1/1 /mnt/1/1 rw,relatime shared:1 - tmpfs test-base rw,uid=1000,gid=1000
    50 53 0:25 /1/1 /mnt/2/1 rw,relatime shared:1 - tmpfs test-base rw,uid=1000,gid=1000
    51 49 0:25 /1/1 /mnt/1/1 rw,relatime shared:1 - tmpfs test-base rw,uid=1000,gid=1000
    54 47 0:25 /1/1 /mnt/1/1 rw,relatime shared:1 - tmpfs test-base rw,uid=1000,gid=1000
    53 48 0:25 /1/1 /mnt/2/1 rw,relatime shared:1 - tmpfs test-base rw,uid=1000,gid=1000
    52 50 0:25 /1/1 /mnt/2/1 rw,relatime shared:1 - tmpfs test-base rw,uid=1000,gid=1000
    
    46 31 0:25 / /mnt rw,relatime - tmpfs test-base rw,uid=1000,gid=1000
    47 46 0:25 /1 /mnt/1 rw,relatime shared:1 - tmpfs test-base rw,uid=1000,gid=1000
    48 46 0:25 /1 /mnt/2 rw,relatime shared:1 - tmpfs test-base rw,uid=1000,gid=1000
    
    The output without the fix looks like:
    46 31 0:25 / /mnt rw,relatime - tmpfs test-base rw,uid=1000,gid=1000
    47 46 0:25 /1 /mnt/1 rw,relatime shared:1 - tmpfs test-base rw,uid=1000,gid=1000
    48 46 0:25 /1 /mnt/2 rw,relatime shared:1 - tmpfs test-base rw,uid=1000,gid=1000
    49 54 0:25 /1/1 /mnt/1/1 rw,relatime shared:1 - tmpfs test-base rw,uid=1000,gid=1000
    50 53 0:25 /1/1 /mnt/2/1 rw,relatime shared:1 - tmpfs test-base rw,uid=1000,gid=1000
    51 49 0:25 /1/1 /mnt/1/1 rw,relatime shared:1 - tmpfs test-base rw,uid=1000,gid=1000
    54 47 0:25 /1/1 /mnt/1/1 rw,relatime shared:1 - tmpfs test-base rw,uid=1000,gid=1000
    53 48 0:25 /1/1 /mnt/2/1 rw,relatime shared:1 - tmpfs test-base rw,uid=1000,gid=1000
    52 50 0:25 /1/1 /mnt/2/1 rw,relatime shared:1 - tmpfs test-base rw,uid=1000,gid=1000
    
    46 31 0:25 / /mnt rw,relatime - tmpfs test-base rw,uid=1000,gid=1000
    47 46 0:25 /1 /mnt/1 rw,relatime shared:1 - tmpfs test-base rw,uid=1000,gid=1000
    48 46 0:25 /1 /mnt/2 rw,relatime shared:1 - tmpfs test-base rw,uid=1000,gid=1000
    52 48 0:25 /1/1 /mnt/2/1 rw,relatime shared:1 - tmpfs test-base rw,uid=1000,gid=1000
    
    That last mount in the output was in the propgation tree to be unmounted but
    was missed because the mnt_change_mountpoint changed it's parent before the walk
    through the mount propagation tree observed it.
    
    Cc: stable@vger.kernel.org
    Fixes: 1064f874
    
     ("mnt: Tuck mounts under others instead of creating shadow/side mounts.")
    Acked-by: default avatarAndrei Vagin <avagin@virtuozzo.com>
    Reviewed-by: default avatarRam Pai <linuxram@us.ibm.com>
    Signed-off-by: default avatar"Eric W. Biederman" <ebiederm@xmission.com>
    570487d3