1. 03 Feb, 2017 1 commit
    • Eric W. Biederman's avatar
      mnt: Tuck mounts under others instead of creating shadow/side mounts. · 1064f874
      Eric W. Biederman authored
      Ever since mount propagation was introduced in cases where a mount in
      propagated to parent mount mountpoint pair that is already in use the
      code has placed the new mount behind the old mount in the mount hash
      table.
      
      This implementation detail is problematic as it allows creating
      arbitrary length mount hash chains.
      
      Furthermore it invalidates the constraint maintained elsewhere in the
      mount code that a parent mount and a mountpoint pair will have exactly
      one mount upon them.  Making it hard to deal with and to talk about
      this special case in the mount code.
      
      Modify mount propagation to notice when there is already a mount at
      the parent mount and mountpoint where a new mount is propagating to
      and place that preexisting mount on top of the new mount.
      
      Modify unmount propagation to notice when a mount that is being
      unmounted has another mount on top of it (and no other children), and
      to replace the unmounted mount with the mount on top of it.
      
      Move the MNT_UMUONT test from __lookup_mnt_last into
      __propagate_umount as that is the only call of __lookup_mnt_last where
      MNT_UMOUNT may be set on any mount visible in the mount hash table.
      
      These modifications allow:
       - __lookup_mnt_last to be removed.
       - attach_shadows to be renamed __attach_mnt and its shadow
         handling to be removed.
       - commit_tree to be simplified
       - copy_tree to be simplified
      
      The result is an easier to understand tree of mounts that does not
      allow creation of arbitrary length hash chains in the mount hash table.
      
      The result is also a very slight userspace visible difference in semantics.
      The following two cases now behave identically, where before order
      mattered:
      
      case 1: (explicit user action)
      	B is a slave of A
      	mount something on A/a , it will propagate to B/a
      	and than mount something on B/a
      
      case 2: (tucked mount)
      	B is a slave of A
      	mount something on B/a
      	and than mount something on A/a
      
      Histroically umount A/a would fail in case 1 and succeed in case 2.
      Now umount A/a succeeds in both configurations.
      
      This very small change in semantics appears if anything to be a bug
      fix to me and my survey of userspace leads me to believe that no programs
      will notice or care of this subtle semantic change.
      
      v2: Updated to mnt_change_mountpoint to not call dput or mntput
      and instead to decrement the counts directly.  It is guaranteed
      that there will be other references when mnt_change_mountpoint is
      called so this is safe.
      
      v3: Moved put_mountpoint under mount_lock in attach_recursive_mnt
          As the locking in fs/namespace.c changed between v2 and v3.
      
      v4: Reworked the logic in propagate_mount_busy and __propagate_umount
          that detects when a mount completely covers another mount.
      
      v5: Removed unnecessary tests whose result is alwasy true in
          find_topper and attach_recursive_mnt.
      
      v6: Document the user space visible semantic difference.
      
      Cc: stable@vger.kernel.org
      Fixes: b90fa9ae ("[PATCH] shared mount handling: bind and rbind")
      Tested-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
      Signed-off-by: 's avatar"Eric W. Biederman" <ebiederm@xmission.com>
      1064f874
  2. 30 Sep, 2016 1 commit
    • Eric W. Biederman's avatar
      mnt: Add a per mount namespace limit on the number of mounts · d2921684
      Eric W. Biederman authored
      CAI Qian <caiqian@redhat.com> pointed out that the semantics
      of shared subtrees make it possible to create an exponentially
      increasing number of mounts in a mount namespace.
      
          mkdir /tmp/1 /tmp/2
          mount --make-rshared /
          for i in $(seq 1 20) ; do mount --bind /tmp/1 /tmp/2 ; done
      
      Will create create 2^20 or 1048576 mounts, which is a practical problem
      as some people have managed to hit this by accident.
      
      As such CVE-2016-6213 was assigned.
      
      Ian Kent <raven@themaw.net> described the situation for autofs users
      as follows:
      
      > The number of mounts for direct mount maps is usually not very large because of
      > the way they are implemented, large direct mount maps can have performance
      > problems. There can be anywhere from a few (likely case a few hundred) to less
      > than 10000, plus mounts that have been triggered and not yet expired.
      >
      > Indirect mounts have one autofs mount at the root plus the number of mounts that
      > have been triggered and not yet expired.
      >
      > The number of autofs indirect map entries can range from a few to the common
      > case of several thousand and in rare cases up to between 30000 and 50000. I've
      > not heard of people with maps larger than 50000 entries.
      >
      > The larger the number of map entries the greater the possibility for a large
      > number of active mounts so it's not hard to expect cases of a 1000 or somewhat
      > more active mounts.
      
      So I am setting the default number of mounts allowed per mount
      namespace at 100,000.  This is more than enough for any use case I
      know of, but small enough to quickly stop an exponential increase
      in mounts.  Which should be perfect to catch misconfigurations and
      malfunctioning programs.
      
      For anyone who needs a higher limit this can be changed by writing
      to the new /proc/sys/fs/mount-max sysctl.
      Tested-by: 's avatarCAI Qian <caiqian@redhat.com>
      Signed-off-by: 's avatar"Eric W. Biederman" <ebiederm@xmission.com>
      d2921684
  3. 23 Jul, 2015 1 commit
    • Eric W. Biederman's avatar
      mnt: Clarify and correct the disconnect logic in umount_tree · f2d0a123
      Eric W. Biederman authored
      rmdir mntpoint will result in an infinite loop when there is
      a mount locked on the mountpoint in another mount namespace.
      
      This is because the logic to test to see if a mount should
      be disconnected in umount_tree is buggy.
      
      Move the logic to decide if a mount should remain connected to
      it's mountpoint into it's own function disconnect_mount so that
      clarity of expression instead of terseness of expression becomes
      a virtue.
      
      When the conditions where it is invalid to leave a mount connected
      are first ruled out, the logic for deciding if a mount should
      be disconnected becomes much clearer and simpler.
      
      Fixes: e0c9c0af mnt: Update detach_mounts to leave mounts connected
      Fixes: ce07d891 mnt: Honor MNT_LOCKED when detaching mounts
      Cc: stable@vger.kernel.org
      Signed-off-by: 's avatar"Eric W. Biederman" <ebiederm@xmission.com>
      f2d0a123
  4. 09 Apr, 2015 1 commit
    • Eric W. Biederman's avatar
      mnt: Honor MNT_LOCKED when detaching mounts · ce07d891
      Eric W. Biederman authored
      Modify umount(MNT_DETACH) to keep mounts in the hash table that are
      locked to their parent mounts, when the parent is lazily unmounted.
      
      In mntput_no_expire detach the children from the hash table, depending
      on mnt_pin_kill in cleanup_mnt to decrement the mnt_count of the children.
      
      In __detach_mounts if there are any mounts that have been unmounted
      but still are on the list of mounts of a mountpoint, remove their
      children from the mount hash table and those children to the unmounted
      list so they won't linger potentially indefinitely waiting for their
      final mntput, now that the mounts serve no purpose.
      
      Cc: stable@vger.kernel.org
      Signed-off-by: 's avatar"Eric W. Biederman" <ebiederm@xmission.com>
      ce07d891
  5. 03 Apr, 2015 4 commits
    • Eric W. Biederman's avatar
      mnt: Don't propagate unmounts to locked mounts · 0c56fe31
      Eric W. Biederman authored
      If the first mount in shared subtree is locked don't unmount the
      shared subtree.
      
      This is ensured by walking through the mounts parents before children
      and marking a mount as unmountable if it is not locked or it is locked
      but it's parent is marked.
      
      This allows recursive mount detach to propagate through a set of
      mounts when unmounting them would not reveal what is under any locked
      mount.
      
      Cc: stable@vger.kernel.org
      Signed-off-by: 's avatar"Eric W. Biederman" <ebiederm@xmission.com>
      0c56fe31
    • Eric W. Biederman's avatar
      mnt: On an unmount propagate clearing of MNT_LOCKED · 5d88457e
      Eric W. Biederman authored
      A prerequisite of calling umount_tree is that the point where the tree
      is mounted at is valid to unmount.
      
      If we are propagating the effect of the unmount clear MNT_LOCKED in
      every instance where the same filesystem is mounted on the same
      mountpoint in the mount tree, as we know (by virtue of the fact
      that umount_tree was called) that it is safe to reveal what
      is at that mountpoint.
      
      Cc: stable@vger.kernel.org
      Signed-off-by: 's avatar"Eric W. Biederman" <ebiederm@xmission.com>
      5d88457e
    • Eric W. Biederman's avatar
      mnt: In umount_tree reuse mnt_list instead of mnt_hash · c003b26f
      Eric W. Biederman authored
      umount_tree builds a list of mounts that need to be unmounted.
      Utilize mnt_list for this purpose instead of mnt_hash.  This begins to
      allow keeping a mount on the mnt_hash after it is unmounted, which is
      necessary for a properly functioning MNT_LOCKED implementation.
      
      The fact that mnt_list is an ordinary list makding available list_move
      is nice bonus.
      
      Cc: stable@vger.kernel.org
      Signed-off-by: 's avatar"Eric W. Biederman" <ebiederm@xmission.com>
      c003b26f
    • Eric W. Biederman's avatar
      mnt: Improve the umount_tree flags · e819f152
      Eric W. Biederman authored
      - Remove the unneeded declaration from pnode.h
      - Mark umount_tree static as it has no callers outside of namespace.c
      - Define an enumeration of umount_tree's flags.
      - Pass umount_tree's flags in by name
      
      This removes the magic numbers 0, 1 and 2 making the code a little
      clearer and makes it possible for there to be lazy unmounts that don't
      propagate.  Which is what __detach_mounts actually wants for example.
      
      Cc: stable@vger.kernel.org
      Signed-off-by: 's avatar"Eric W. Biederman" <ebiederm@xmission.com>
      e819f152
  6. 02 Apr, 2014 1 commit
    • Al Viro's avatar
      smarter propagate_mnt() · f2ebb3a9
      Al Viro authored
      The current mainline has copies propagated to *all* nodes, then
      tears down the copies we made for nodes that do not contain
      counterparts of the desired mountpoint.  That sets the right
      propagation graph for the copies (at teardown time we move
      the slaves of removed node to a surviving peer or directly
      to master), but we end up paying a fairly steep price in
      useless allocations.  It's fairly easy to create a situation
      where N calls of mount(2) create exactly N bindings, with
      O(N^2) vfsmounts allocated and freed in process.
      
      Fortunately, it is possible to avoid those allocations/freeings.
      The trick is to create copies in the right order and find which
      one would've eventually become a master with the current algorithm.
      It turns out to be possible in O(nodes getting propagation) time
      and with no extra allocations at all.
      
      One part is that we need to make sure that eventual master will be
      created before its slaves, so we need to walk the propagation
      tree in a different order - by peer groups.  And iterate through
      the peers before dealing with the next group.
      
      Another thing is finding the (earlier) copy that will be a master
      of one we are about to create; to do that we are (temporary) marking
      the masters of mountpoints we are attaching the copies to.
      
      Either we are in a peer of the last mountpoint we'd dealt with,
      or we have the following situation: we are attaching to mountpoint M,
      the last copy S_0 had been attached to M_0 and there are sequences
      S_0...S_n, M_0...M_n such that S_{i+1} is a master of S_{i},
      S_{i} mounted on M{i} and we need to create a slave of the first S_{k}
      such that M is getting propagation from M_{k}.  It means that the master
      of M_{k} will be among the sequence of masters of M.  On the
      other hand, the nearest marked node in that sequence will either
      be the master of M_{k} or the master of M_{k-1} (the latter -
      in the case if M_{k-1} is a slave of something M gets propagation
      from, but in a wrong peer group).
      
      So we go through the sequence of masters of M until we find
      a marked one (P).  Let N be the one before it.  Then we go through
      the sequence of masters of S_0 until we find one (say, S) mounted
      on a node D that has P as master and check if D is a peer of N.
      If it is, S will be the master of new copy, if not - the master of S
      will be.
      
      That's it for the hard part; the rest is fairly simple.  Iterator
      is in next_group(), handling of one prospective mountpoint is
      propagate_one().
      
      It seems to survive all tests and gives a noticably better performance
      than the current mainline for setups that are seriously using shared
      subtrees.
      
      Cc: stable@vger.kernel.org
      Signed-off-by: 's avatarAl Viro <viro@zeniv.linux.org.uk>
      f2ebb3a9
  7. 30 Mar, 2014 1 commit
    • Al Viro's avatar
      switch mnt_hash to hlist · 38129a13
      Al Viro authored
      fixes RCU bug - walking through hlist is safe in face of element moves,
      since it's self-terminating.  Cyclic lists are not - if we end up jumping
      to another hash chain, we'll loop infinitely without ever hitting the
      original list head.
      
      [fix for dumb braino folded]
      
      Spotted by: Max Kellermann <mk@cm4all.com>
      Cc: stable@vger.kernel.org
      Signed-off-by: 's avatarAl Viro <viro@zeniv.linux.org.uk>
      38129a13
  8. 27 Aug, 2013 1 commit
    • Eric W. Biederman's avatar
      vfs: Don't copy mount bind mounts of /proc/<pid>/ns/mnt between namespaces · 4ce5d2b1
      Eric W. Biederman authored
      Don't copy bind mounts of /proc/<pid>/ns/mnt between namespaces.
      These files hold references to a mount namespace and copying them
      between namespaces could result in a reference counting loop.
      
      The current mnt_ns_loop test prevents loops on the assumption that
      mounts don't cross between namespaces.  Unfortunately unsharing a
      mount namespace and shared substrees can both cause mounts to
      propogate between mount namespaces.
      
      Add two flags CL_COPY_UNBINDABLE and CL_COPY_MNT_NS_FILE are added to
      control this behavior, and CL_COPY_ALL is redefined as both of them.
      Signed-off-by: 's avatar"Eric W. Biederman" <ebiederm@xmission.com>
      4ce5d2b1
  9. 09 Apr, 2013 2 commits
  10. 27 Mar, 2013 1 commit
  11. 19 Nov, 2012 1 commit
  12. 04 Jan, 2012 17 commits
  13. 03 Mar, 2010 2 commits
    • Valerie Aurora's avatar
      VFS: Clean up shared mount flag propagation · 495d6c9c
      Valerie Aurora authored
      The handling of mount flags in set_mnt_shared() got a little tangled
      up during previous cleanups, with the following problems:
      
      * MNT_PNODE_MASK is defined as a literal constant when it should be a
      bitwise xor of other MNT_* flags
      * set_mnt_shared() clears and then sets MNT_SHARED (part of MNT_PNODE_MASK)
      * MNT_PNODE_MASK could use a comment in mount.h
      * MNT_PNODE_MASK is a terrible name, change to MNT_SHARED_MASK
      
      This patch fixes these problems.
      Signed-off-by: 's avatarAl Viro <viro@zeniv.linux.org.uk>
      495d6c9c
    • Al Viro's avatar
      Kill CL_PROPAGATION, sanitize fs/pnode.c:get_source() · 796a6b52
      Al Viro authored
      First of all, get_source() never results in CL_PROPAGATION
      alone.  We either get CL_MAKE_SHARED (for the continuation
      of peer group) or CL_SLAVE (slave that is not shared) or both
      (beginning of peer group among slaves).  Massage the code to
      make that explicit, kill CL_PROPAGATION test in clone_mnt()
      (nothing sets CL_MAKE_SHARED without CL_PROPAGATION and in
      clone_mnt() we are checking CL_PROPAGATION after we'd found
      that there's no CL_SLAVE, so the check for CL_MAKE_SHARED
      would do just as well).
      
      Fix comments, while we are at it...
      Signed-off-by: 's avatarAl Viro <viro@zeniv.linux.org.uk>
      796a6b52
  14. 23 Apr, 2008 1 commit
  15. 22 Apr, 2008 1 commit
  16. 21 Oct, 2007 1 commit
  17. 08 Dec, 2006 1 commit
  18. 08 Nov, 2005 2 commits