1. 30 10月, 2019 1 次提交
  2. 25 6月, 2019 1 次提交
    • A
      ovl: detect overlapping layers · f1c5aa5e
      Amir Goldstein 提交于
      [ Upstream commit 146d62e5a5867fbf84490d82455718bfb10fe824 ]
      
      Overlapping overlay layers are not supported and can cause unexpected
      behavior, but overlayfs does not currently check or warn about these
      configurations.
      
      User is not supposed to specify the same directory for upper and
      lower dirs or for different lower layers and user is not supposed to
      specify directories that are descendants of each other for overlay
      layers, but that is exactly what this zysbot repro did:
      
          https://syzkaller.appspot.com/x/repro.syz?x=12c7a94f400000
      
      Moving layer root directories into other layers while overlayfs
      is mounted could also result in unexpected behavior.
      
      This commit places "traps" in the overlay inode hash table.
      Those traps are dummy overlay inodes that are hashed by the layers
      root inodes.
      
      On mount, the hash table trap entries are used to verify that overlay
      layers are not overlapping.  While at it, we also verify that overlay
      layers are not overlapping with directories "in-use" by other overlay
      instances as upperdir/workdir.
      
      On lookup, the trap entries are used to verify that overlay layers
      root inodes have not been moved into other layers after mount.
      
      Some examples:
      
      $ ./run --ov --samefs -s
      ...
      ( mkdir -p base/upper/0/u base/upper/0/w base/lower lower upper mnt
        mount -o bind base/lower lower
        mount -o bind base/upper upper
        mount -t overlay none mnt ...
              -o lowerdir=lower,upperdir=upper/0/u,workdir=upper/0/w)
      
      $ umount mnt
      $ mount -t overlay none mnt ...
              -o lowerdir=base,upperdir=upper/0/u,workdir=upper/0/w
      
        [   94.434900] overlayfs: overlapping upperdir path
        mount: mount overlay on mnt failed: Too many levels of symbolic links
      
      $ mount -t overlay none mnt ...
              -o lowerdir=upper/0/u,upperdir=upper/0/u,workdir=upper/0/w
      
        [  151.350132] overlayfs: conflicting lowerdir path
        mount: none is already mounted or mnt busy
      
      $ mount -t overlay none mnt ...
              -o lowerdir=lower:lower/a,upperdir=upper/0/u,workdir=upper/0/w
      
        [  201.205045] overlayfs: overlapping lowerdir path
        mount: mount overlay on mnt failed: Too many levels of symbolic links
      
      $ mount -t overlay none mnt ...
              -o lowerdir=lower,upperdir=upper/0/u,workdir=upper/0/w
      $ mv base/upper/0/ base/lower/
      $ find mnt/0
        mnt/0
        mnt/0/w
        find: 'mnt/0/w/work': Too many levels of symbolic links
        find: 'mnt/0/u': Too many levels of symbolic links
      
      Reported-by: syzbot+9c69c282adc4edd2b540@syzkaller.appspotmail.com
      Signed-off-by: NAmir Goldstein <amir73il@gmail.com>
      Signed-off-by: NMiklos Szeredi <mszeredi@redhat.com>
      Signed-off-by: NSasha Levin <sashal@kernel.org>
      f1c5aa5e
  3. 20 7月, 2018 2 次提交
  4. 12 4月, 2018 3 次提交
    • A
      ovl: add support for "xino" mount and config options · 795939a9
      Amir Goldstein 提交于
      With mount option "xino=on", mounter declares that there are enough
      free high bits in underlying fs to hold the layer fsid.
      If overlayfs does encounter underlying inodes using the high xino
      bits reserved for layer fsid, a warning will be emitted and the original
      inode number will be used.
      
      The mount option name "xino" goes after a similar meaning mount option
      of aufs, but in overlayfs case, the mapping is stateless.
      
      An example for a use case of "xino=on" is when upper/lower is on an xfs
      filesystem. xfs uses 64bit inode numbers, but it currently never uses the
      upper 8bit for inode numbers exposed via stat(2) and that is not likely to
      change in the future without user opting-in for a new xfs feature. The
      actual number of unused upper bit is much larger and determined by the xfs
      filesystem geometry (64 - agno_log - agblklog - inopblog). That means
      that for all practical purpose, there are enough unused bits in xfs
      inode numbers for more than OVL_MAX_STACK unique fsid's.
      
      Another use case of "xino=on" is when upper/lower is on tmpfs. tmpfs inode
      numbers are allocated sequentially since boot, so they will practially
      never use the high inode number bits.
      
      For compatibility with applications that expect 32bit inodes, the feature
      can be disabled with "xino=off". The option "xino=auto" automatically
      detects underlying filesystem that use 32bit inodes and enables the
      feature. The Kconfig option OVERLAY_FS_XINO_AUTO and module parameter of
      the same name, determine if the default mode for overlayfs mount is
      "xino=auto" or "xino=off".
      Signed-off-by: NAmir Goldstein <amir73il@gmail.com>
      Signed-off-by: NMiklos Szeredi <mszeredi@redhat.com>
      795939a9
    • A
      ovl: constant st_ino for non-samefs with xino · e487d889
      Amir Goldstein 提交于
      On 64bit systems, when overlay layers are not all on the same fs, but
      all inode numbers of underlying fs are not using the high bits, use the
      high bits to partition the overlay st_ino address space.  The high bits
      hold the fsid (upper fsid is 0).  This way overlay inode numbers are unique
      and all inodes use overlay st_dev.  Inode numbers are also persistent
      for a given layer configuration.
      
      Currently, our only indication for available high ino bits is from a
      filesystem that supports file handles and uses the default encode_fh()
      operation, which encodes a 32bit inode number.
      Signed-off-by: NAmir Goldstein <amir73il@gmail.com>
      Signed-off-by: NMiklos Szeredi <mszeredi@redhat.com>
      e487d889
    • A
      ovl: allocate anon bdev per unique lower fs · 5148626b
      Amir Goldstein 提交于
      Instead of allocating an anonymous bdev per lower layer, allocate
      one anonymous bdev per every unique lower fs that is different than
      upper fs.
      
      Every unique lower fs is assigned an fsid > 0 and the number of
      unique lower fs are stored in ofs->numlowerfs.
      
      The assigned fsid is stored in the lower layer struct and will be
      used also for inode number multiplexing.
      Signed-off-by: NAmir Goldstein <amir73il@gmail.com>
      Signed-off-by: NMiklos Szeredi <mszeredi@redhat.com>
      5148626b
  5. 24 1月, 2018 3 次提交
    • A
      ovl: store 'has_upper' and 'opaque' as bit flags · c62520a8
      Amir Goldstein 提交于
      We need to make some room in struct ovl_entry to store information
      about redirected ancestors for NFS export, so cram two booleans as
      bit flags.
      Signed-off-by: NAmir Goldstein <amir73il@gmail.com>
      Signed-off-by: NMiklos Szeredi <mszeredi@redhat.com>
      c62520a8
    • A
      ovl: add support for "nfs_export" configuration · f168f109
      Amir Goldstein 提交于
      Introduce the "nfs_export" config, module and mount options.
      
      The NFS export feature depends on the "index" feature and enables two
      implicit overlayfs features: "index_all" and "verify_lower".
      The "index_all" feature creates an index on copy up of every file and
      directory. The "verify_lower" feature uses the full index to detect
      overlay filesystems inconsistencies on lookup, like redirect from
      multiple upper dirs to the same lower dir.
      
      NFS export can be enabled for non-upper mount with no index. However,
      because lower layer redirects cannot be verified with the index, enabling
      NFS export support on an overlay with no upper layer requires turning off
      redirect follow (e.g. "redirect_dir=nofollow").
      
      The full index may incur some overhead on mount time, especially when
      verifying that lower directory file handles are not stale.
      
      NFS export support, full index and consistency verification will be
      implemented by following patches.
      Signed-off-by: NAmir Goldstein <amir73il@gmail.com>
      Signed-off-by: NMiklos Szeredi <mszeredi@redhat.com>
      f168f109
    • A
      ovl: store layer index in ovl_layer · d583ed7d
      Amir Goldstein 提交于
      Store the fs root layer index inside ovl_layer struct, so we can
      get the root fs layer index from merge dir lower layer instead of
      find it with ovl_find_layer() helper.
      Signed-off-by: NAmir Goldstein <amir73il@gmail.com>
      Signed-off-by: NMiklos Szeredi <mszeredi@redhat.com>
      d583ed7d
  6. 17 12月, 2017 1 次提交
  7. 11 12月, 2017 1 次提交
    • M
      ovl: don't follow redirects if redirect_dir=off · 438c84c2
      Miklos Szeredi 提交于
      Overlayfs is following redirects even when redirects are disabled. If this
      is unintentional (probably the majority of cases) then this can be a
      problem.  E.g. upper layer comes from untrusted USB drive, and attacker
      crafts a redirect to enable read access to otherwise unreadable
      directories.
      
      If "redirect_dir=off", then turn off following as well as creation of
      redirects.  If "redirect_dir=follow", then turn on following, but turn off
      creation of redirects (which is what "redirect_dir=off" does now).
      
      This is a backward incompatible change, so make it dependent on a config
      option.
      Reported-by: NDavid Howells <dhowells@redhat.com>
      Signed-off-by: NMiklos Szeredi <mszeredi@redhat.com>
      438c84c2
  8. 09 11月, 2017 2 次提交
  9. 24 10月, 2017 1 次提交
  10. 05 10月, 2017 1 次提交
    • A
      ovl: fix regression caused by exclusive upper/work dir protection · 85fdee1e
      Amir Goldstein 提交于
      Enforcing exclusive ownership on upper/work dirs caused a docker
      regression: https://github.com/moby/moby/issues/34672.
      
      Euan spotted the regression and pointed to the offending commit.
      Vivek has brought the regression to my attention and provided this
      reproducer:
      
      Terminal 1:
      
        mount -t overlay -o workdir=work,lowerdir=lower,upperdir=upper none
              merged/
      
      Terminal 2:
      
        unshare -m
      
      Terminal 1:
      
        umount merged
        mount -t overlay -o workdir=work,lowerdir=lower,upperdir=upper none
              merged/
        mount: /root/overlay-testing/merged: none already mounted or mount point
               busy
      
      To fix the regression, I replaced the error with an alarming warning.
      With index feature enabled, mount does fail, but logs a suggestion to
      override exclusive dir protection by disabling index.
      Note that index=off mount does take the inuse locks, so a concurrent
      index=off will issue the warning and a concurrent index=on mount will fail.
      
      Documentation was updated to reflect this change.
      
      Fixes: 2cac0c00 ("ovl: get exclusive ownership on upper/work dirs")
      Cc: <stable@vger.kernel.org> # v4.13
      Reported-by: NEuan Kemp <euank@euank.com>
      Reported-by: NVivek Goyal <vgoyal@redhat.com>
      Signed-off-by: NAmir Goldstein <amir73il@gmail.com>
      Signed-off-by: NMiklos Szeredi <mszeredi@redhat.com>
      85fdee1e
  11. 05 7月, 2017 10 次提交
  12. 19 5月, 2017 1 次提交
    • A
      ovl: mark upper dir with type origin entries "impure" · ee1d6d37
      Amir Goldstein 提交于
      When moving a merge dir or non-dir with copy up origin into a non-merge
      upper dir (a.k.a pure upper dir), we are marking the target parent dir
      "impure". ovl_iterate() iterates pure upper dirs directly, because there is
      no need to filter out whiteouts and merge dir content with lower dir. But
      for the case of an "impure" upper dir, ovl_iterate() will not be able to
      iterate the real upper dir directly, because it will need to lookup the
      origin inode and use it to fill d_ino.
      Signed-off-by: NAmir Goldstein <amir73il@gmail.com>
      Signed-off-by: NMiklos Szeredi <mszeredi@redhat.com>
      ee1d6d37
  13. 18 5月, 2017 1 次提交
  14. 05 5月, 2017 1 次提交
  15. 07 2月, 2017 2 次提交
  16. 16 12月, 2016 4 次提交
    • M
      ovl: redirect on rename-dir · a6c60655
      Miklos Szeredi 提交于
      Current code returns EXDEV when a directory would need to be copied up to
      move.  We could copy up the directory tree in this case, but there's
      another, simpler solution: point to old lower directory from moved upper
      directory.
      
      This is achieved with a "trusted.overlay.redirect" xattr storing the path
      relative to the root of the overlay.  After such attribute has been set,
      the directory can be moved without further actions required.
      
      This is a backward incompatible feature, old kernels won't be able to
      correctly mount an overlay containing redirected directories.
      Signed-off-by: NMiklos Szeredi <mszeredi@redhat.com>
      a6c60655
    • M
      ovl: lookup redirects · 02b69b28
      Miklos Szeredi 提交于
      If a directory has the "trusted.overlay.redirect" xattr, it means that the
      value of the xattr should be used to find the underlying directory on the
      next lower layer.
      
      The redirect may be relative or absolute.  Absolute redirects begin with a
      slash.
      
      A relative redirect means: instead of the current dentry's name use the
      value of the redirect to find the directory in the next lower
      layer. Relative redirects must not contain a slash.
      
      An absolute redirect means: look up the directory relative to the root of
      the overlay using the value of the redirect in the next lower layer.
      
      Redirects work on lower layers as well.
      Signed-off-by: NMiklos Szeredi <mszeredi@redhat.com>
      02b69b28
    • M
      ovl: check namelen · 6b2d5fe4
      Miklos Szeredi 提交于
      We already calculate f_namelen in statfs as the maximum of the name lengths
      provided by the filesystems taking part in the overlay.
      Signed-off-by: NMiklos Szeredi <mszeredi@redhat.com>
      6b2d5fe4
    • M
      ovl: split super.c · bbb1e54d
      Miklos Szeredi 提交于
      fs/overlayfs/super.c is the biggest of the overlayfs source files and it
      contains various utility functions as well as the rather complicated lookup
      code.  Split these parts out to separate files.
      
      Before:
      
       1446 fs/overlayfs/super.c
      
      After:
      
        919 fs/overlayfs/super.c
        267 fs/overlayfs/namei.c
        235 fs/overlayfs/util.c
         51 fs/overlayfs/ovl_entry.h
      Signed-off-by: NMiklos Szeredi <mszeredi@redhat.com>
      bbb1e54d