From: "Dr. Thomas Orgis" <thomas.orgis@uni-hamburg.de>
To: <linux-xfs@vger.kernel.org>
Subject: Re: XFS group quota circumvention via NFS and chgrp
Date: Thu, 18 Jun 2026 23:05:40 +0200 [thread overview]
Message-ID: <20260618230540.424cceee@plasteblaster> (raw)
In-Reply-To: <20260616110804.5d26ff85@plasteblaster>
Am Tue, 16 Jun 2026 11:08:04 +0200
schrieb "Dr. Thomas Orgis" <thomas.orgis@uni-hamburg.de>:
> Dear Linux XFS folks,
>
> I noticed that xfs group quotas can be circumvented via NFS* on vanilla
> Kernel 6.6.x (slightly differing versions on client and server) as
> follows:
I was asked off-list to provide an easier reproducer. Let's try this:
1. Prepare/start a VM in the terminal.
dd if=/dev/zero of=xfs.img bs=1M count=500
wget -O debian-live.iso https://gitlab.com/api/v4/projects/74667529/packages/generic/debian-libre-live/13.3.0/debian-live-13.3.0-amd64-libre-standard.iso
isoinfo -R -i debian-live.iso -x /live/vmlinuz > vmlinuz
isoinfo -R -i debian-live.iso -x /live/initrd.img > initrd.img
qemu-system-x86_64 -nographic -enable-kvm -smp 2 -m 4G \
-cdrom debian-live.iso -drive index=0,driver=raw,file=xfs.img \
-kernel vmlinuz -initrd initrd.img -append "boot=live components console=ttyS0 ro"
Login as user/live, and sudo su, or prepend sudo all the time below, if
you prefer.
2. In the VM, as root:
apt install -y nfs-kernel-server
mkfs.xfs -f /dev/sda
mount -o usrquota,grpquota /dev/sda /srv
xfs_quota -x -c 'limit -g bsoft=1m bhard=2m -d' /srv
echo "auxgrp:x:1001:user" >> /etc/group
mkdir -p /srv/share/user
chown user:user /srv/share/user
echo "/srv localhost(fsid=0,rw)" >> /etc/exports
echo "/srv/share localhost(fsid=1,rw)" >> /etc/exports
systemctl restart nfs-kernel-server
mount localhost:/share /mnt/
# First blob. Works.
su user -c 'dd if=/dev/zero of=/mnt/user/blob1 bs=2M count=1'
# Second blob. Fails:
su user -c 'dd if=/dev/zero of=/mnt/user/blob2 bs=2M count=1'
# Show the limited state.
xfs_quota -x -c report /srv
# Move one block to the other group, filling its quota.
su user -c 'chgrp auxgrp /mnt/user/blob1'
# Now write the second blob.
su user -c 'dd if=/dev/zero of=/mnt/user/blob2 bs=2M count=1'
# Magic: Move that away, getting out of auxgrp quota.
su user -c 'chgrp auxgrp /mnt/user/blob2'
xfs_quota -x -c report /srv
# For fun: Just fill the disk.
# side fact: I froze qemu with 100% CPU load when having a sync
# command in the loop instead of sleep. It's one of those days where
# I step onto bugs everywhere.
n=3
while su user -c "dd if=/dev/zero of=/mnt/user/blob$n bs=2M count=1" &&
sleep 0.1 &&
su user -c "chgrp auxgrp /mnt/user/blob$n"
do
n=$((n+1))
done
xfs_quota -x -c report /srv
Result after the individual writes:
User quota on /srv (/dev/sda)
Blocks
User ID Used Soft Hard Warn/Grace
---------- --------------------------------------------------
root 0 0 0 00 [--------]
user 4096 0 0 00 [--------]
Group quota on /srv (/dev/sda)
Blocks
Group ID Used Soft Hard Warn/Grace
---------- --------------------------------------------------
root 0 1024 2048 00 [--------]
user 0 1024 2048 00 [--------]
auxgrp 4096 1024 2048 00 [--none--]
This shouldn't be possible. Should it? After the writing loop, I get
2097152 bytes (2.1 MB, 2.0 MiB) copied, 0.0206776 s, 101 MB/s
1+0 records in
1+0 records out
2097152 bytes (2.1 MB, 2.0 MiB) copied, 0.0204505 s, 103 MB/s
dd: closing output file '/mnt/user/blob14': Disk quota exceeded
User quota on /srv (/dev/sda)
Blocks
User ID Used Soft Hard Warn/Grace
---------- --------------------------------------------------
root 0 0 0 00 [--------]
user 28612 0 0 00 [--------]
Group quota on /srv (/dev/sda)
Blocks
Group ID Used Soft Hard Warn/Grace
---------- --------------------------------------------------
root 0 1024 2048 00 [--------]
user 1988 1024 2048 00 [7 days]
auxgrp 26624 1024 2048 00 [--none--]
It quite consistently stops at blob14. I don't quite get why, though.
Inode size does not count into block quota for xfs, right? Why be able
to write 13 blobs, but not 14, when the quota is filled at one already?
Different questions. The main question is: Why I am able to move data
beyond the group quota?
Alrighty then,
Thomas
--
Dr. Thomas Orgis
HPC @ Universität Hamburg
prev parent reply other threads:[~2026-06-18 21:05 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-16 9:08 XFS group quota circumvention via NFS and chgrp Dr. Thomas Orgis
2026-06-18 21:05 ` Dr. Thomas Orgis [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260618230540.424cceee@plasteblaster \
--to=thomas.orgis@uni-hamburg.de \
--cc=linux-xfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.