svn commit: r350490 - in head/sys/ufs: ffs ufs
Kirk McKusick
mckusick at FreeBSD.org
Wed Jul 31 22:44:59 UTC 2019
Author: mckusick
Date: Wed Jul 31 22:44:58 2019
New Revision: 350490
URL: https://svnweb.freebsd.org/changeset/base/350490
Log:
When updating the user or group disk quotas for the return of inodes or
disk blocks, set the FORCE flag in the call to chkiq() or chkdq() since
the user is always allowed to return resources and hence there is no need
to check the user's credential .
Reported by: Christopher Krah, Thomas Barabosch, and Jan-Niclas Hilgert of Fraunhofer FKIE
Reported as: FS-1-UFS-1: Denial Of Service in mount (prison_priv_check)
Discussed with: kib
MFC: 1 week
Sponsored by: Netflix
Modified:
head/sys/ufs/ffs/ffs_inode.c
head/sys/ufs/ffs/ffs_softdep.c
head/sys/ufs/ufs/ufs_quota.c
head/sys/ufs/ufs/ufs_vnops.c
Modified: head/sys/ufs/ffs/ffs_inode.c
==============================================================================
--- head/sys/ufs/ffs/ffs_inode.c Wed Jul 31 21:48:35 2019 (r350489)
+++ head/sys/ufs/ffs/ffs_inode.c Wed Jul 31 22:44:58 2019 (r350490)
@@ -263,7 +263,7 @@ ffs_truncate(vp, length, flags, cred)
if ((error = ffs_syncvnode(vp, MNT_WAIT, 0)) != 0)
return (error);
#ifdef QUOTA
- (void) chkdq(ip, -extblocks, NOCRED, 0);
+ (void) chkdq(ip, -extblocks, NOCRED, FORCE);
#endif
vinvalbuf(vp, V_ALT, 0, 0);
vn_pages_remove(vp,
@@ -621,7 +621,7 @@ done:
DIP_SET(ip, i_blocks, 0);
ip->i_flag |= IN_CHANGE;
#ifdef QUOTA
- (void) chkdq(ip, -blocksreleased, NOCRED, 0);
+ (void) chkdq(ip, -blocksreleased, NOCRED, FORCE);
#endif
return (allerror);
Modified: head/sys/ufs/ffs/ffs_softdep.c
==============================================================================
--- head/sys/ufs/ffs/ffs_softdep.c Wed Jul 31 21:48:35 2019 (r350489)
+++ head/sys/ufs/ffs/ffs_softdep.c Wed Jul 31 22:44:58 2019 (r350490)
@@ -6682,7 +6682,7 @@ softdep_journal_freeblocks(ip, cred, length, flags)
#ifdef QUOTA
/* Reference the quotas in case the block count is wrong in the end. */
quotaref(vp, freeblks->fb_quota);
- (void) chkdq(ip, -datablocks, NOCRED, 0);
+ (void) chkdq(ip, -datablocks, NOCRED, FORCE);
#endif
freeblks->fb_chkcnt = -datablocks;
UFS_LOCK(ump);
@@ -6946,7 +6946,7 @@ softdep_setup_freeblocks(ip, length, flags)
#ifdef QUOTA
/* Reference the quotas in case the block count is wrong in the end. */
quotaref(ITOV(ip), freeblks->fb_quota);
- (void) chkdq(ip, -datablocks, NOCRED, 0);
+ (void) chkdq(ip, -datablocks, NOCRED, FORCE);
#endif
freeblks->fb_chkcnt = -datablocks;
UFS_LOCK(ump);
Modified: head/sys/ufs/ufs/ufs_quota.c
==============================================================================
--- head/sys/ufs/ufs/ufs_quota.c Wed Jul 31 21:48:35 2019 (r350489)
+++ head/sys/ufs/ufs/ufs_quota.c Wed Jul 31 22:44:58 2019 (r350490)
@@ -159,6 +159,7 @@ chkdq(struct inode *ip, ufs2_daddr_t change, struct uc
struct vnode *vp = ITOV(ip);
int i, error, warn, do_check;
+ MPASS(cred != NOCRED || (flags & FORCE) != 0);
/*
* Disk quotas must be turned off for system files. Currently
* snapshot and quota files.
@@ -311,6 +312,7 @@ chkiq(struct inode *ip, int change, struct ucred *cred
struct dquot *dq;
int i, error, warn, do_check;
+ MPASS(cred != NOCRED || (flags & FORCE) != 0);
#ifdef DIAGNOSTIC
if ((flags & CHOWN) == 0)
chkdquot(ip);
Modified: head/sys/ufs/ufs/ufs_vnops.c
==============================================================================
--- head/sys/ufs/ufs/ufs_vnops.c Wed Jul 31 21:48:35 2019 (r350489)
+++ head/sys/ufs/ufs/ufs_vnops.c Wed Jul 31 22:44:58 2019 (r350490)
@@ -811,8 +811,8 @@ ufs_chown(vp, uid, gid, cred, td)
ip->i_dquot[GRPQUOTA] = NODQUOT;
}
change = DIP(ip, i_blocks);
- (void) chkdq(ip, -change, cred, CHOWN);
- (void) chkiq(ip, -1, cred, CHOWN);
+ (void) chkdq(ip, -change, cred, CHOWN|FORCE);
+ (void) chkiq(ip, -1, cred, CHOWN|FORCE);
for (i = 0; i < MAXQUOTAS; i++) {
dqrele(vp, ip->i_dquot[i]);
ip->i_dquot[i] = NODQUOT;
More information about the svn-src-all
mailing list