• Roman Borisov's avatar
    fs/namespace.c: bound mount propagation fix · 7c6e984d
    Roman Borisov authored
    This issue was discovered by users of busybox.  And the bug is actual for
    busybox users, I don't know how it affects others.  Apparently, mount is
    called with and without MS_SILENT, and this affects mount() behaviour.
    But MS_SILENT is only supposed to affect kernel logging verbosity.
    
    The following script was run in an empty test directory:
    
    mkdir -p mount.dir mount.shared1 mount.shared2
    touch mount.dir/a mount.dir/b
    mount -vv --bind         mount.shared1 mount.shared1
    mount -vv --make-rshared mount.shared1
    mount -vv --bind         mount.shared2 mount.shared2
    mount -vv --make-rshared mount.shared2
    mount -vv --bind mount.shared2 mount.shared1
    mount -vv --bind mount.dir     mount.shared2
    ls -R mount.dir mount.shared1 mount.shared2
    umount mount.dir mount.shared1 mount.shared2 2>/dev/null
    umount mount.dir mount.shared1 mount.shared2 2>/dev/null
    umount mount.dir mount.shared1 mount.shared2 2>/dev/null
    rm -f mount.dir/a mount.dir/b mount.dir/c
    rmdir mount.dir mount.shared1 mount.shared2
    
    mount -vv was used to show the mount() call arguments and result.
    Output shows that flag argument has 0x00008000 = MS_SILENT bit:
    
    mount: mount('mount.shared1','mount.shared1','(null)',0x00009000,'(null)'):0
    mount: mount('','mount.shared1','',0x0010c000,''):0
    mount: mount('mount.shared2','mount.shared2','(null)',0x00009000,'(null)'):0
    mount: mount('','mount.shared2','',0x0010c000,''):0
    mount: mount('mount.shared2','mount.shared1','(null)',0x00009000,'(null)'):0
    mount: mount('mount.dir','mount.shared2','(null)',0x00009000,'(null)'):0
    mount.dir:
    a
    b
    
    mount.shared1:
    
    mount.shared2:
    a
    b
    
    After adding --loud option to remove MS_SILENT bit from just one mount cmd:
    
    mkdir -p mount.dir mount.shared1 mount.shared2
    touch mount.dir/a mount.dir/b
    mount -vv --bind         mount.shared1 mount.shared1 2>&1
    mount -vv --make-rshared mount.shared1               2>&1
    mount -vv --bind         mount.shared2 mount.shared2 2>&1
    mount -vv --loud --make-rshared mount.shared2               2>&1  # <-HERE
    mount -vv --bind mount.shared2 mount.shared1         2>&1
    mount -vv --bind mount.dir     mount.shared2         2>&1
    ls -R mount.dir mount.shared1 mount.shared2      2>&1
    umount mount.dir mount.shared1 mount.shared2 2>/dev/null
    umount mount.dir mount.shared1 mount.shared2 2>/dev/null
    umount mount.dir mount.shared1 mount.shared2 2>/dev/null
    rm -f mount.dir/a mount.dir/b mount.dir/c
    rmdir mount.dir mount.shared1 mount.shared2
    
    The result is different now - look closely at mount.shared1 directory listing.
    Now it does show files 'a' and 'b':
    
    mount: mount('mount.shared1','mount.shared1','(null)',0x00009000,'(null)'):0
    mount: mount('','mount.shared1','',0x0010c000,''):0
    mount: mount('mount.shared2','mount.shared2','(null)',0x00009000,'(null)'):0
    mount: mount('','mount.shared2','',0x00104000,''):0
    mount: mount('mount.shared2','mount.shared1','(null)',0x00009000,'(null)'):0
    mount: mount('mount.dir','mount.shared2','(null)',0x00009000,'(null)'):0
    
    mount.dir:
    a
    b
    
    mount.shared1:
    a
    b
    
    mount.shared2:
    a
    b
    
    The analysis shows that MS_SILENT flag which is ON by default in any
    busybox-> mount operations cames to flags_to_propagation_type function and
    causes the error return while is_power_of_2 checking because the function
    expects only one bit set.  This doesn't allow to do busybox->mount with
    any --make-[r]shared, --make-[r]private etc options.
    
    Moreover, the recently added flags_to_propagation_type() function doesn't
    allow us to do such operations as --make-[r]private --make-[r]shared etc.
    when MS_SILENT is on.  The idea or clearing the MS_SILENT flag came from
    to Denys Vlasenko.
    Signed-off-by: default avatarRoman Borisov <ext-roman.borisov@nokia.com>
    Reported-by: default avatarDenys Vlasenko <vda.linux@googlemail.com>
    Cc: Chuck Ebbert <cebbert@redhat.com>
    Cc: Alexander Shishkin <virtuoso@slind.org>
    Cc: Al Viro <viro@zeniv.linux.org.uk>
    Cc: Christoph Hellwig <hch@lst.de>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
    7c6e984d
namespace.c 65 KB