From nobody Sat Dec 18 01:39:52 2021 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id D05F718FC8ED; Sat, 18 Dec 2021 01:39:52 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4JG7nh460Zz4qPN; Sat, 18 Dec 2021 01:39:52 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 6C8F6268D8; Sat, 18 Dec 2021 01:39:52 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 1BI1dquR095581; Sat, 18 Dec 2021 01:39:52 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 1BI1dqJm095580; Sat, 18 Dec 2021 01:39:52 GMT (envelope-from git) Date: Sat, 18 Dec 2021 01:39:52 GMT Message-Id: <202112180139.1BI1dqJm095580@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Rick Macklem Subject: git: f15f29c975f1 - stable/13 - nfsd: Fix Verify for attributes like FilesAvail List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: rmacklem X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: f15f29c975f1374d67ae722df9f9bc7b55d4c42a Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1639791592; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=YOWrQoU+2ssndd9jUS+EH1YQGDHJWEAKWByz1SGVPJI=; b=J1YEEP96X+VgbfuTDpcGnelt+xXLfcmG2L304vZuw5HDWer39PIJLwMzsuAV/xvTPT+c5i fJsY5x8DHFezIbAQyTUEeuI0L2lgTmdWYWPzi/eZRdr1MNDGRCBTM7KXmcNnsHHkrKk0d5 K/Koz9qsp+JMVjuCAlaEQPC05lmlf7tILl5bXbMZoY93N4F+fIuj/CpXuJt4cifMqljQ4X Ol6fW0cEJkQmnZ2mp7BD6FL90bmxGr9d9iIwfNy1zGLFD7MlJt4bjv3LTqa4CsxfUy1UW/ VAi+QBmLXhvZAN7laZChxl6F5ujYtpONI12x5yZ7OCI7gmgrjT7QNQnyo/bYwg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1639791592; a=rsa-sha256; cv=none; b=eN4zKi2RaFt1ftZ5io4lmvbZqeJd5uG7npWFi5PTeKkgF2FnTmPDr70z3uy8/SQGs/gUMV PiWvNDxigDsDj59fAlkl0JNwi8buA/7HS8c580zTNKh/qixGFaYJr54Hwbq/7VLVCUPZzx 7gkZlo9JiLQEbnuO27i8XoRmagI6+I7ScgTLl8TX/itB1kIY3Qmsowoc2APyGBxohdI2JW vHnzBCQ0D8yPhSgN1uJeEoM5HKS3JE3vDNrLAZGpvL+ScKGPCJ4W0wQWtgJetpjyClD8sj bbbEbEH2VjhW/6/3ewyaVno5eaelUdS0J9lyE0c8HGWTmI2BUWoHZeX4CrAN1w== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=f15f29c975f1374d67ae722df9f9bc7b55d4c42a commit f15f29c975f1374d67ae722df9f9bc7b55d4c42a Author: Rick Macklem AuthorDate: 2021-12-04 22:38:55 +0000 Commit: Rick Macklem CommitDate: 2021-12-18 01:36:41 +0000 nfsd: Fix Verify for attributes like FilesAvail When the Verify operation calls nfsv4_loadattr(), it provides the "struct statfs" information that can be used for doing a compare for FilesAvail, FilesFree, FilesTotal, SpaceAvail, SpaceFree and SpaceTotal. However, the code erroneously used the "struct nfsstatfs *" argument that is NULL. This patch fixes these cases to use the correct argument structure. For the case of FilesAvail, the code in nfsv4_fillattr() was factored out into a separate function called nfsv4_filesavail(), so that it can be called from nfsv4_loadattr() as well as nfsv4_fillattr(). In fact, most of the code in nfsv4_filesavail() is old OpenBSD code that does not build/run on FreeBSD, but I left it in place, in case it is of some use someday. I am not aware of any extant NFSv4 client that does Verify on these attributes. PR: 260176 (cherry picked from commit 2d90ef47141d3ea0f88b43a1b6daf08d68ba8aba) --- sys/fs/nfs/nfs_commonsubs.c | 91 ++++++++++++++++++++++++++++++--------------- 1 file changed, 61 insertions(+), 30 deletions(-) diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c index 5a944ffa8c1a..0351111867b0 100644 --- a/sys/fs/nfs/nfs_commonsubs.c +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -220,6 +220,7 @@ static int nfs_bigreply[NFSV42_NPROCS] = { 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, /* local functions */ static int nfsrv_skipace(struct nfsrv_descript *nd, int *acesizep); static void nfsv4_wanted(struct nfsv4lock *lp); +static uint32_t nfsv4_filesavail(struct statfs *, struct mount *); static int nfsrv_cmpmixedcase(u_char *cp, u_char *cp2, int len); static int nfsrv_getuser(int procnum, uid_t uid, gid_t gid, char *name); static void nfsrv_removeuser(struct nfsusrgrp *usrp, int isuser); @@ -1629,8 +1630,8 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp, case NFSATTRBIT_FILESAVAIL: NFSM_DISSECT(tl, u_int32_t *, NFSX_HYPER); if (compare) { - if (!(*retcmpp) && - sfp->sf_afiles != fxdr_hyper(tl)) + uquad = nfsv4_filesavail(sbp, vp->v_mount); + if (!(*retcmpp) && uquad != fxdr_hyper(tl)) *retcmpp = NFSERR_NOTSAME; } else if (sfp != NULL) { sfp->sf_afiles = fxdr_hyper(tl); @@ -1640,8 +1641,8 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp, case NFSATTRBIT_FILESFREE: NFSM_DISSECT(tl, u_int32_t *, NFSX_HYPER); if (compare) { - if (!(*retcmpp) && - sfp->sf_ffiles != fxdr_hyper(tl)) + uquad = (uint64_t)sbp->f_ffree; + if (!(*retcmpp) && uquad != fxdr_hyper(tl)) *retcmpp = NFSERR_NOTSAME; } else if (sfp != NULL) { sfp->sf_ffiles = fxdr_hyper(tl); @@ -1651,8 +1652,8 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp, case NFSATTRBIT_FILESTOTAL: NFSM_DISSECT(tl, u_int32_t *, NFSX_HYPER); if (compare) { - if (!(*retcmpp) && - sfp->sf_tfiles != fxdr_hyper(tl)) + uquad = sbp->f_files; + if (!(*retcmpp) && uquad != fxdr_hyper(tl)) *retcmpp = NFSERR_NOTSAME; } else if (sfp != NULL) { sfp->sf_tfiles = fxdr_hyper(tl); @@ -2002,8 +2003,13 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp, case NFSATTRBIT_SPACEAVAIL: NFSM_DISSECT(tl, u_int32_t *, NFSX_HYPER); if (compare) { - if (!(*retcmpp) && - sfp->sf_abytes != fxdr_hyper(tl)) + if (priv_check_cred(cred, + PRIV_VFS_BLOCKRESERVE)) + uquad = sbp->f_bfree; + else + uquad = (uint64_t)sbp->f_bavail; + uquad *= sbp->f_bsize; + if (!(*retcmpp) && uquad != fxdr_hyper(tl)) *retcmpp = NFSERR_NOTSAME; } else if (sfp != NULL) { sfp->sf_abytes = fxdr_hyper(tl); @@ -2013,8 +2019,9 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp, case NFSATTRBIT_SPACEFREE: NFSM_DISSECT(tl, u_int32_t *, NFSX_HYPER); if (compare) { - if (!(*retcmpp) && - sfp->sf_fbytes != fxdr_hyper(tl)) + uquad = sbp->f_bfree; + uquad *= sbp->f_bsize; + if (!(*retcmpp) && uquad != fxdr_hyper(tl)) *retcmpp = NFSERR_NOTSAME; } else if (sfp != NULL) { sfp->sf_fbytes = fxdr_hyper(tl); @@ -2024,8 +2031,9 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp, case NFSATTRBIT_SPACETOTAL: NFSM_DISSECT(tl, u_int32_t *, NFSX_HYPER); if (compare) { - if (!(*retcmpp) && - sfp->sf_tbytes != fxdr_hyper(tl)) + uquad = sbp->f_blocks; + uquad *= sbp->f_bsize; + if (!(*retcmpp) && uquad != fxdr_hyper(tl)) *retcmpp = NFSERR_NOTSAME; } else if (sfp != NULL) { sfp->sf_tbytes = fxdr_hyper(tl); @@ -2723,24 +2731,7 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp, retnum += NFSX_HYPER; break; case NFSATTRBIT_FILESAVAIL: - /* - * Check quota and use min(quota, f_ffree). - */ - freenum = fs->f_ffree; -#ifdef QUOTA - /* - * ufs_quotactl() insists that the uid argument - * equal p_ruid for non-root quota access, so - * we'll just make sure that's the case. - */ - savuid = p->p_cred->p_ruid; - p->p_cred->p_ruid = cred->cr_uid; - if (!VFS_QUOTACTL(mp, QCMD(Q_GETQUOTA,USRQUOTA), - cred->cr_uid, &dqb)) - freenum = min(dqb.dqb_isoftlimit-dqb.dqb_curinodes, - freenum); - p->p_cred->p_ruid = savuid; -#endif /* QUOTA */ + freenum = nfsv4_filesavail(fs, mp); NFSM_BUILD(tl, u_int32_t *, NFSX_HYPER); *tl++ = 0; *tl = txdr_unsigned(freenum); @@ -3066,6 +3057,46 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp, return (retnum + prefixnum); } +/* + * Calculate the files available attribute value. + */ +static uint32_t +nfsv4_filesavail(struct statfs *fs, struct mount *mp) +{ + uint32_t freenum; +#ifdef QUOTA + struct dqblk dqb; + uid_t savuid; + NFSPROC_T *p; +#endif + + /* + * Check quota and use min(quota, f_ffree). + */ + freenum = fs->f_ffree; +#ifdef QUOTA + /* + * This is old OpenBSD code that does not build + * for FreeBSD. I do not know if doing this is + * useful, so I will just leave the code here. + */ + p = curthread(); + /* + * ufs_quotactl() insists that the uid argument + * equal p_ruid for non-root quota access, so + * we'll just make sure that's the case. + */ + savuid = p->p_cred->p_ruid; + p->p_cred->p_ruid = cred->cr_uid; + if (!VFS_QUOTACTL(mp, QCMD(Q_GETQUOTA,USRQUOTA), + cred->cr_uid, &dqb)) + freenum = min(dqb.dqb_isoftlimit-dqb.dqb_curinodes, + freenum); + p->p_cred->p_ruid = savuid; +#endif /* QUOTA */ + return (freenum); +} + /* * Put the attribute bits onto an mbuf list. * Return the number of bytes of output generated.