On Tue, Feb 09, 2021 at 11:49:12AM +0000, fdman...@kernel.org wrote: > From: Filipe Manana <fdman...@suse.com> > > We had a few bugs on the kernel side of send/receive where capabilities > ended up being lost after receiving a send stream. They all stem from the > fact that the kernel used to send all xattrs before issuing the chown > command, and the later clears any existing capabilities in a file or > directory. > > Initially a workaround was added to btrfs-progs' receive command, in commit > 123a2a085027e ("btrfs-progs: receive: restore capabilities after chown"), > and that fixed some instances of the problem. More recently, other instances > of the problem were found, a proper fix for the kernel was made, which fixes > the root problem by making send always emit the sexattr command for setting > capabilities after issuing a chown command. This was done in kernel commit > 89efda52e6b693 ("btrfs: send: emit file capabilities after chown"), which > landed in kernel 5.8. > > However, the workaround on the receive command now causes us to incorrectly > set a capability on a file that should not have it, because it assumes all > setxattr commands for a file always comes before a chown. > > Example reproducer: > > $ cat send-caps.sh > #!/bin/bash > > DEV1=/dev/sdh > DEV2=/dev/sdi > > MNT1=/mnt/sdh > MNT2=/mnt/sdi > > mkfs.btrfs -f $DEV1 > /dev/null > mkfs.btrfs -f $DEV2 > /dev/null > > mount $DEV1 $MNT1 > mount $DEV2 $MNT2 > > touch $MNT1/foo > touch $MNT1/bar > setcap cap_net_raw=p $MNT1/foo > > btrfs subvolume snapshot -r $MNT1 $MNT1/snap1 > > btrfs send $MNT1/snap1 | btrfs receive $MNT2 > > echo > echo "capabilities on destination filesystem:" > echo > getcap $MNT2/snap1/foo > getcap $MNT2/snap1/bar > > umount $MNT1 > umount $MNT2 > > When running the test script, we can see that both files foo and bar get > the capability set, when only file foo should have it: > > $ ./send-caps.sh > Create a readonly snapshot of '/mnt/sdh' in '/mnt/sdh/snap1' > At subvol /mnt/sdh/snap1 > At subvol snap1 > > capabilities on destination filesystem: > > /mnt/sdi/snap1/foo cap_net_raw=p > /mnt/sdi/snap1/bar cap_net_raw=p > > Since the kernel fix was backported to all currently supported stable > releases (5.10.x, 5.4.x, 4.19.x, 4.14.x, 4.9.x and 4.4.x), remove the > workaround from receive. Having such a workaround relying on the order > of commands in a send stream is always troublesome and doomed to break > one day. > > A test case for fstests will come soon. > > Reported-by: Richard Brown <rbr...@suse.de> > Signed-off-by: Filipe Manana <fdman...@suse.com>
Thanks. I'm going to add a btrfs-progs test case as well, based on the script in the changelog.