• Miklos Szeredi's avatar
    ovl: fix d_real() for stacked fs · c4fcfc16
    Miklos Szeredi authored
    Handling of recursion in d_real() is completely broken.  Recursion is only
    done in the 'inode != NULL' case.  But when opening the file we have
    'inode == NULL' hence d_real() will return an overlay dentry.  This won't
    work since overlayfs doesn't define its own file operations, so all file
    ops will fail.
    
    Fix by doing the recursion first and the check against the inode second.
    
    Bash script to reproduce the issue written by Quentin:
    
     - 8< - - - - - 8< - - - - - 8< - - - - - 8< - - - -
    tmpdir=$(mktemp -d)
    pushd ${tmpdir}
    
    mkdir -p {upper,lower,work}
    echo -n 'rocks' > lower/ksplice
    mount -t overlay level_zero upper -o lowerdir=lower,upperdir=upper,workdir=work
    cat upper/ksplice
    
    tmpdir2=$(mktemp -d)
    pushd ${tmpdir2}
    
    mkdir -p {upper,work}
    mount -t overlay level_one upper -o lowerdir=${tmpdir}/upper,upperdir=upper,workdir=work
    ls -l upper/ksplice
    cat upper/ksplice
     - 8< - - - - - 8< - - - - - 8< - - - - - 8< - - - - 
    Reported-by: default avatarQuentin Casasnovas <quentin.casasnovas@oracle.com>
    Signed-off-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
    Fixes: 2d902671 ("vfs: merge .d_select_inode() into .d_real()")
    Cc: <stable@vger.kernel.org> # v4.8+
    c4fcfc16
super.c 31.6 KB