From 62b5194f627571c019907edb11bb7bc2edd59933 Mon Sep 17 00:00:00 2001 From: Akihiro Suda Date: Thu, 25 Mar 2021 18:56:23 +0900 Subject: [PATCH] btrfs: Allow unprivileged user to delete subvolumes (kernel >= 4.18) Fix issue 41762 Cherry-pick "drivers: btrfs: Allow unprivileged user to delete subvolumes" from containers/storage https://github.com/containers/storage/pull/508/commits/831e32b6bdcb530acc4c1cb9059d3c6dba14208c > In btrfs, subvolume can be deleted by IOC_SNAP_DESTROY ioctl but there > is one catch: unprivileged IOC_SNAP_DESTROY call is restricted by default. > > This is because IOC_SNAP_DESTROY only performs permission checks on > the top directory(subvolume) and unprivileged user might delete dirs/files > which cannot be deleted otherwise. This restriction can be relaxed if > user_subvol_rm_allowed mount option is used. > > Although the above ioctl had been the only way to delete a subvolume, > btrfs now allows deletion of subvolume just like regular directory > (i.e. rmdir sycall) since kernel 4.18. > > So if we fail to cleanup subvolume in subvolDelete(), just fallback to > system.EnsureRmoveall() to try to cleanup subvolumes again. > (Note: quota needs privilege, so if quota is enabled we do not fallback) > > This fix will allow non-privileged container works with btrfs backend. Signed-off-by: Akihiro Suda --- daemon/graphdriver/btrfs/btrfs.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/daemon/graphdriver/btrfs/btrfs.go b/daemon/graphdriver/btrfs/btrfs.go index f9127472f8..0499489d16 100644 --- a/daemon/graphdriver/btrfs/btrfs.go +++ b/daemon/graphdriver/btrfs/btrfs.go @@ -633,7 +633,14 @@ func (d *Driver) Remove(id string) error { d.updateQuotaStatus() if err := subvolDelete(d.subvolumesDir(), id, d.quotaEnabled); err != nil { - return err + if d.quotaEnabled { + return err + } + // If quota is not enabled, fallback to rmdir syscall to delete subvolumes. + // This would allow unprivileged user to delete their owned subvolumes + // in kernel >= 4.18 without user_subvol_rm_allowed mount option. + // + // From https://github.com/containers/storage/pull/508/commits/831e32b6bdcb530acc4c1cb9059d3c6dba14208c } if err := system.EnsureRemoveAll(dir); err != nil { return err