Re: [RFC PATCH] quota: allow unprivileged users to query ID 0 default limits

Ravi Singh
2026-03-17T06:59:58Z

On Thu, Mar 12, 2026 at 3:15 PM Andreas Dilger <adilger@dilger.ca> wrote:
>
> On Mar 12, 2026, at 03:08, Ravi Singh <ravising@redhat.com> wrote:
> >
> > Default quota limits are stored on the ID 0 dquot record and are
> > applied by the kernel to all users who have no explicit limits set.
> > However, check_quotactl_permission() only allows unprivileged users to
> > query their own user or group quota via Q_GETQUOTA/Q_XGETQUOTA. This
> > means unprivileged users cannot discover what default limits apply to
> > them.
> >
> > Allow any user to query ID 0's quota via Q_GETQUOTA/Q_XGETQUOTA.
> > Note that this does expose ID 0's usage counters and timers in
> > addition to the default limits. This enables userspace tools like
> > xfs_quota to fetch default limits and display them to unprivileged
> > users.
>
> Showing the root user's quota usage may be confusing for the regular
> user. It seems better to filter out the quota usage in this case and
> only expose the limits?

Agreed, exposing root's usage data is unnecessary.

> Alternately, should users without an explicit quota limit have the
> default limits merged into their returned values, rather than them
> needing to query id=0 separately for the limits?

Yes, this is the better approach. I've reworked the patch to handle
this in xfs_qm_scall_getquota(), when xfs_qm_dqget() returns
-ENOENT for a non-zero ID, we now return zero usage with default
limits from xfs_get_defquota() instead of propagating the error.

This avoids any VFS permission changes and keeps root's usage data
private. The user queries their own ID through the existing
permission check, and the kernel returns the effective limits directly.

v2 posted as a separate thread.

Thanks,
Ravi

> Cheers, Andreas
> >
> > This change does not affect Q_XGETNEXTQUOTA, Q_SETQLIM, or any other
> > quota command -- those still require CAP_SYS_ADMIN.
> >
> > Signed-off-by: Ravi Singh <ravising@redhat.com>
> > ---
> > fs/quota/quota.c | 3 +++
> > 1 file changed, 3 insertions(+)
> >
> > diff --git a/fs/quota/quota.c b/fs/quota/quota.c
> > index 33bacd707..8b21f3c1b 100644
> > --- a/fs/quota/quota.c
> > +++ b/fs/quota/quota.c
> > @@ -42,6 +42,9 @@ static int check_quotactl_permission(struct super_block *sb, int type, int cmd,
> > if ((type == USRQUOTA && uid_eq(current_euid(), make_kuid(current_user_ns(), id))) ||
> > (type == GRPQUOTA && in_egroup_p(make_kgid(current_user_ns(), id))))
> > break;
> > + /* Allow unprivileged read of ID 0 (default quota limits) */
> > + if (id == 0)
> > + break;
> > fallthrough;
> > default:
> > if (!capable(CAP_SYS_ADMIN))
> > --
> > 2.49.0
> >
> >
>