• Amir Goldstein's avatar
    ovl: detect overlapping layers · 99eb836c
    Amir Goldstein authored
    [ Upstream commit 146d62e5 ]
    
    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: default avatarAmir Goldstein <amir73il@gmail.com>
    Signed-off-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
    Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
    99eb836c
inode.c 25.4 KB