• Vivek Goyal's avatar
    ovl: fix redirect traversal on metacopy dentries · 21d8d66a
    Vivek Goyal authored
    Amir pointed me to metacopy test cases in unionmount-testsuite and I
    decided to run "./run --ov=10 --meta" and it failed while running test
    "rename-mass-5.py".
    
    Problem is w.r.t absolute redirect traversal on intermediate metacopy
    dentry.  We do not store intermediate metacopy dentries and also skip
    current loop/layer and move onto lookup in next layer.  But at the end of
    loop, we have logic to reset "poe" and layer index if currnently looked up
    dentry has absolute redirect.  We skip all that and that means lookup in
    next layer will fail.
    
    Following is simple test case to reproduce this.
    
    - mkdir -p lower upper work merged lower/a lower/b
    - touch lower/a/foo.txt
    - mount -t overlay -o lowerdir=lower,upperdir=upper,workdir=work,metacopy=on none merged
    
    # Following will create absolute redirect "/a/foo.txt" on upper/b/bar.txt.
    - mv merged/a/foo.txt merged/b/bar.txt
    
    # unmount overlay and use upper as lower layer (lower2) for next mount.
    - umount merged
    - mv upper lower2
    - rm -rf work; mkdir -p upper work
    - mount -t overlay -o lowerdir=lower2:lower,upperdir=upper,workdir=work,metacopy=on none merged
    
    # Force a metacopy copy-up
    - chown bin:bin merged/b/bar.txt
    
    # unmount overlay and use upper as lower layer (lower3) for next mount.
    - umount merged
    - mv upper lower3
    - rm -rf work; mkdir -p upper work
    - mount -t overlay -o lowerdir=lower3:lower2:lower,upperdir=upper,workdir=work,metacopy=on none merged
    
    # ls merged/b/bar.txt
    ls: cannot access 'bar.txt': Input/output error
    
    Intermediate lower layer (lower2) has metacopy dentry b/bar.txt with
    absolute redirect "/a/foo.txt".  We skipped redirect processing at the end
    of loop which sets poe to roe and sets the appropriate next lower layer
    index.  And that means lookup failed in next layer.
    
    Fix this by continuing the loop for any intermediate dentries.  We still do
    not save these at lower stack.  With this fix applied unionmount-testsuite,
    "./run --ov-10 --meta" now passes.
    Signed-off-by: default avatarVivek Goyal <vgoyal@redhat.com>
    Reviewed-by: default avatarAmir Goldstein <amir73il@gmail.com>
    Signed-off-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
    21d8d66a
namei.c 27.4 KB