From patchwork Thu Jan 27 16:08:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever III X-Patchwork-Id: 12726993 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5547FC433F5 for ; Thu, 27 Jan 2022 16:08:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235080AbiA0QIg (ORCPT ); Thu, 27 Jan 2022 11:08:36 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44800 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235046AbiA0QIf (ORCPT ); Thu, 27 Jan 2022 11:08:35 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 730B4C061714; Thu, 27 Jan 2022 08:08:35 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id E0D84B8013C; Thu, 27 Jan 2022 16:08:33 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 68C1AC340E8; Thu, 27 Jan 2022 16:08:32 +0000 (UTC) From: Chuck Lever To: linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH RFC 1/6] NFSD: Fix NFSv4 SETATTR's handling of large file sizes Date: Thu, 27 Jan 2022 11:08:31 -0500 Message-Id: <164329971128.5879.15718457509790221509.stgit@bazille.1015granger.net> X-Mailer: git-send-email 2.34.0 In-Reply-To: <164329914731.5879.7791856151631542523.stgit@bazille.1015granger.net> References: <164329914731.5879.7791856151631542523.stgit@bazille.1015granger.net> User-Agent: StGit/1.4 MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=1431; h=from:subject:message-id; bh=N4VlS+H+hXv1KsZpGU4bMU80ctTAGt7gsU/48u+j7YY=; b=owEBbQKS/ZANAwAIATNqszNvZn+XAcsmYgBh8sN/1xgp/KJ1C4YDxiLct6MtQK0omHS36vYizANN +ybhZgiJAjMEAAEIAB0WIQQosuWwEobfJDzyPv4zarMzb2Z/lwUCYfLDfwAKCRAzarMzb2Z/l+rnD/ 93FOAGWnqD74YWfrQDyd2lcxKetMuBKVq+ww3aV2BEueLU7SzY9jKaXLU551j0mIWvPQ+uhklzqmLp nWDqvMe/CaXtVT3ARGjAHw4pSSK16Hy4OjgJb166QgIU+yTCWvpmUmiuepnjsr6H2AIKF5zDbhsFOe KNKMfX5L0mt6wJVtlhyiS9H8/m6QoFtHTGM9VQ8pPzPBYNx2eVNstwYUru/kzbYIy0Z02LKOPAFCdI bwBtOx6eXRKv5rV/rz5aESClfzdb3yIhI3Bz6VNJB807VeYG3JZ3trQy0XuvkZfy1Fx1vUqSdvIyQz 81LW4yZDV7MVPafoCu3tygGbu+yGfYat+OEobWerovWbPEast+pbT40a8O07Ow/i8VKjB8qYvz+vNk moYp01PtJKMtsDdGemPMx7YPisE3VXIsb5ZXG8rYv/9dv5UaEkRyMWZv5xQ4I7uUMemNMp57J9knBl r2B2Aa4G72bFP1Zuc0vZVaCYFJxNIjgTji8JGIePFm1QomBwmz2iBn/srTv/P02w7sMtUwtfATcn5N Kcq5pDSmR+bG8Oy1czOHDACYwRMiKG3oDUFlCebu1aiNLqflvredSNL9MVebGEl58LssT1tNCBEwva 6apBn/zkx56uz0keNWjDv18LSms7xpzE7b4o0AuS2z45krJjW/tjA7DlqK1g== X-Developer-Key: i=chuck.lever@oracle.com; a=openpgp; fpr=28B2E5B01286DF243CF23EFE336AB3336F667F97 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org iattr::ia_size is a loff_t. decode_fattr4() dumps a full u64 value in there. If that value is larger than S64_MAX, then ia_size has underflowed. In this case the negative size is passed through to the VFS and underlying filesystems. I've observed XFS behavior: it returns EIO but still attempts to access past the end of the device. IOW it assumes the caller has already sanity-checked the value. Have our server return NFS4ERR_FBIG to the client when the passed-in file size cannot be held in a loff_t variable. > 15.1.4.4. NFS4ERR_FBIG (Error Code 27) > > The file is too large. The operation would have caused the file to > grow beyond the server's limit. It's likely that other NFSv4 operations that take a fattr4 argument (such as OPEN) have a similar issue). Signed-off-by: Chuck Lever --- fs/nfsd/nfs4proc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index ed1ee25647be..b8ac2b9bce74 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -972,6 +972,9 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, int err; if (setattr->sa_iattr.ia_valid & ATTR_SIZE) { + if (setattr->sa_iattr.ia_size < 0) + return nfserr_fbig; + status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, &setattr->sa_stateid, WR_STATE, NULL, NULL); From patchwork Thu Jan 27 16:08:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever III X-Patchwork-Id: 12726994 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E7DA9C433EF for ; Thu, 27 Jan 2022 16:08:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235073AbiA0QIm (ORCPT ); Thu, 27 Jan 2022 11:08:42 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44822 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235028AbiA0QIl (ORCPT ); Thu, 27 Jan 2022 11:08:41 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8F3E6C061714; Thu, 27 Jan 2022 08:08:41 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 4F122B8013C; Thu, 27 Jan 2022 16:08:40 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id EC201C340E4; Thu, 27 Jan 2022 16:08:38 +0000 (UTC) From: Chuck Lever To: linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH RFC 2/6] NFSD: Fix NFSv3 SETATTR's handling of large file sizes Date: Thu, 27 Jan 2022 11:08:38 -0500 Message-Id: <164329971780.5879.14075937739339830206.stgit@bazille.1015granger.net> X-Mailer: git-send-email 2.34.0 In-Reply-To: <164329914731.5879.7791856151631542523.stgit@bazille.1015granger.net> References: <164329914731.5879.7791856151631542523.stgit@bazille.1015granger.net> User-Agent: StGit/1.4 MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=2256; h=from:subject:message-id; bh=KZ6nEjCBaasoWlPViPJLjrjxkT/Ax1Hk2VBhr26ctok=; b=owEBbQKS/ZANAwAIATNqszNvZn+XAcsmYgBh8sOFTCBYzUDyEwWX0eU8X+QTd97W25NKickI+VUK 2SklvM+JAjMEAAEIAB0WIQQosuWwEobfJDzyPv4zarMzb2Z/lwUCYfLDhQAKCRAzarMzb2Z/l7lJD/ 9evtlURpyyEV3mJsT6oMaPu0aLir9EJzTg6ZBvtA+E8aONbOs2eZDjjxDY2nHuUUxKVlIu53IkE2f5 GN/LzrgBU7B6YyacRCyvveGwJDSaWm3Wl+i1VzlnpGDRnv1n8HGUNIwRtPIEOg2beVRAcUFrPa3hEV 0Fgubf/D9HADHGxMhC7pl+xjSApWm7Wdq7++pM9Xvgzh/28ytCv87Lans6SvigvLjEr1JQz5S+Olsd eP4U5DOk3DIvjuNstAYQ6lXEF+GSpbBKESzd372P/WYiXS7iB7XuShRJQhhRyNQmP0OA79Tq3fmB2I N0mzVi/pp+kl1vD/pY9RHbrN9GjinPs5ZROgUmEbEJARScYGUwexr6NrtHyGVQ8STC5kTN17xVwDsi 3JVy7g8dGt9kQwioQ4/ZFAYVkl8V9MKOy0Lc8cjbrjVSx6F0DeuHKZptG0rGewLokODH22HwvRDf+B m/zSiaT0fU2Cu9DKOHr5zu/xvaZiZ8F9qBJovfrKT6Ry9EqC3naPb/yzy4VkshQQkL8calIeoi5P02 bVRPSWQxoh3RXs4rNuydTFBYOAzoLF/w0EQWY7GolwkTv9Fvn1NFyJBudEoKYNMN54M0L7/K5+1nDv JOz0EEg7c3MkCvSTbZnG2Sldl3aS06yuH9evH2XeH0x+hTKsK/JAcIZtfyOg== X-Developer-Key: i=chuck.lever@oracle.com; a=openpgp; fpr=28B2E5B01286DF243CF23EFE336AB3336F667F97 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org iattr::ia_size is a loff_t, so the XDR decoders must be careful to deal with incoming client size values that are larger than s64_max. VFS size comparisons (like in inode_newsize_ok) should now work as expected -- it returns -EFBIG if the new size is larger than the underlying filesystem's s_maxbytes. However, RFC 1813 permits only WRITE to return NFS3ERR_FBIG. Add an extra check to prevent NFSv3 SETATTR from returning FBIG. Other NFSv3 procedures that take sattr3 arguments need to be audited for this issue. Signed-off-by: Chuck Lever --- fs/nfsd/nfs3proc.c | 19 ++++++++++++++++++- fs/nfsd/nfs3xdr.c | 2 +- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c index 8ef53f6726ec..aa0f0261ddac 100644 --- a/fs/nfsd/nfs3proc.c +++ b/fs/nfsd/nfs3proc.c @@ -66,13 +66,30 @@ nfsd3_proc_setattr(struct svc_rqst *rqstp) { struct nfsd3_sattrargs *argp = rqstp->rq_argp; struct nfsd3_attrstat *resp = rqstp->rq_resp; + struct iattr *iap = &argp->attrs; dprintk("nfsd: SETATTR(3) %s\n", SVCFH_fmt(&argp->fh)); fh_copy(&resp->fh, &argp->fh); - resp->status = nfsd_setattr(rqstp, &resp->fh, &argp->attrs, + + if (iap->ia_valid & ATTR_SIZE) { + struct super_block *sb; + + resp->status = fh_verify(rqstp, &resp->fh, S_IFREG, + NFSD_MAY_SATTR|NFSD_MAY_WRITE|NFSD_MAY_OWNER_OVERRIDE); + if (resp->status != nfs_ok) + goto out; + + resp->status = nfserr_inval; + sb = resp->fh.fh_dentry->d_sb; + if (iap->ia_size < 0 || iap->ia_size > sb->s_maxbytes) + goto out; + } + + resp->status = nfsd_setattr(rqstp, &resp->fh, iap, argp->check_guard, argp->guardtime); +out: return rpc_success; } diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index 7c45ba4db61b..2e47a07029f1 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c @@ -254,7 +254,7 @@ svcxdr_decode_sattr3(struct svc_rqst *rqstp, struct xdr_stream *xdr, if (xdr_stream_decode_u64(xdr, &newsize) < 0) return false; iap->ia_valid |= ATTR_SIZE; - iap->ia_size = min_t(u64, newsize, NFS_OFFSET_MAX); + iap->ia_size = newsize; } if (xdr_stream_decode_u32(xdr, &set_it) < 0) return false; From patchwork Thu Jan 27 16:08:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever III X-Patchwork-Id: 12726995 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1DC80C433F5 for ; Thu, 27 Jan 2022 16:08:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238433AbiA0QIs (ORCPT ); Thu, 27 Jan 2022 11:08:48 -0500 Received: from ams.source.kernel.org ([145.40.68.75]:49816 "EHLO ams.source.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235028AbiA0QIs (ORCPT ); Thu, 27 Jan 2022 11:08:48 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id CF62FB8018A; Thu, 27 Jan 2022 16:08:46 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 75BCFC340E4; Thu, 27 Jan 2022 16:08:45 +0000 (UTC) From: Chuck Lever To: linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH RFC 3/6] NFSD: COMMIT operations must not return NFS?ERR_INVAL Date: Thu, 27 Jan 2022 11:08:44 -0500 Message-Id: <164329972435.5879.13150991880289153111.stgit@bazille.1015granger.net> X-Mailer: git-send-email 2.34.0 In-Reply-To: <164329914731.5879.7791856151631542523.stgit@bazille.1015granger.net> References: <164329914731.5879.7791856151631542523.stgit@bazille.1015granger.net> User-Agent: StGit/1.4 MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=5689; h=from:subject:message-id; bh=tNAgDnoTq2BU4fHER56wSNp8P3VTE6ie3pIbOrhmBvM=; b=owEBbQKS/ZANAwAIATNqszNvZn+XAcsmYgBh8sOMRdtf4Q6WSvZZxV3Cu7tyJbR9xNUIZiQPnwxH ePxhd02JAjMEAAEIAB0WIQQosuWwEobfJDzyPv4zarMzb2Z/lwUCYfLDjAAKCRAzarMzb2Z/l+pLEA DCZRQpbcAAPg7o+VRdWL1BptDJJW9jNPb7KvKLDVm61ZtEM89QAF0YoDiYILlu9VliBziU23lRAS62 aFmjT5lpGB6kMqwIM09/OHtusuL0cxeRc72GE5aZPCM+QCdFX9Xlps30x7y/MPK2AQnhcIoPXrKqui qN5DZ29rTJvQBmnHGwiQwEIng7Bn0l6LMYYPG1FaHhEJkUFeaufKkYHzbm7BIZEpufBkqP3dk3rxtU LdsCp7hnMuMkzL9jCq+VAB6ULHX4/Qks6gN7gfttF/ek/qzC+NoWdM8M0X2KI6i7XpO6jrHpkpX9mn C/XFQtxWoxJGMUslyceBur54ffwaSZW/616azixoE5ebOBu9HRDZzdAR9eqv/Kdm8HKf3TOUyRMkO7 EZf1AdbZJRlIOBM8nt9sOozYQZNwcaIhNKDZaAG6qlsa1R/51u+OdXg+rWFQT1Pmmmnmdu13rbz8LB i2xoUpWZwtmlZggXYKxfejH76PY64gsRKVK4Mg9WihCrqpYVycT+/6O+5BUmbMQrf10NfzPgMUzzpu qoEL7sTAklGhf9Rdud1wCxLx3N+BiU/fboryUE1H9WTSOtr1z+7DsXyZf/5Fen7KRKl09cNrEF2gX2 YEVE1x5JcKKaJ9a8S5YfAxFHwJ8Yc5aWiD/UtPelXtX2T2XMk4qLmu9XhebA== X-Developer-Key: i=chuck.lever@oracle.com; a=openpgp; fpr=28B2E5B01286DF243CF23EFE336AB3336F667F97 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Since, well, forever, the Linux NFS server's nfsd_commit() function has returned nfserr_inval when the passed-in byte range arguments were non-sensical. However, according to RFC 1813 section 3.3.21, NFSv3 COMMIT requests are permitted to return only the following non-zero status codes: NFS3ERR_IO NFS3ERR_STALE NFS3ERR_BADHANDLE NFS3ERR_SERVERFAULT NFS3ERR_INVAL is not included in that list. Likewise, NFS4ERR_INVAL is not listed in the COMMIT row of Table 6 in RFC 8881. Instead of dropping or failing a COMMIT request in a byte range that is not supported, turn it into a valid request by treating one or both arguments as zero. Offset zero means start-of-file, count zero means until-end-of-file, so we only ever extend the commit range. NFS servers are always allowed to commit more and sooner than requested. The range check is no longer bounded by NFS_OFFSET_MAX, but rather by the value that is returned in the maxfilesize field of the NFSv3 FSINFO procedure or the NFSv4 maxfilesize file attribute. Note that this change results in a new pynfs failure: CMT4 st_commit.testCommitOverflow : RUNNING CMT4 st_commit.testCommitOverflow : FAILURE COMMIT with offset + count overflow should return NFS4ERR_INVAL, instead got NFS4_OK IMO the test is not correct as written: RFC 8881 does not allow the COMMIT operation to return NFS4ERR_INVAL. Reported-by: Dan Aloni Signed-off-by: Chuck Lever --- fs/nfsd/nfs3proc.c | 6 ------ fs/nfsd/vfs.c | 53 +++++++++++++++++++++++++++++++++++----------------- fs/nfsd/vfs.h | 4 ++-- 3 files changed, 38 insertions(+), 25 deletions(-) diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c index aa0f0261ddac..7bca219a8146 100644 --- a/fs/nfsd/nfs3proc.c +++ b/fs/nfsd/nfs3proc.c @@ -668,15 +668,9 @@ nfsd3_proc_commit(struct svc_rqst *rqstp) argp->count, (unsigned long long) argp->offset); - if (argp->offset > NFS_OFFSET_MAX) { - resp->status = nfserr_inval; - goto out; - } - fh_copy(&resp->fh, &argp->fh); resp->status = nfsd_commit(rqstp, &resp->fh, argp->offset, argp->count, resp->verf); -out: return rpc_success; } diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 99c2b9dfbb10..f9f72b1ecb73 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1110,42 +1110,61 @@ nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset, } #ifdef CONFIG_NFSD_V3 -/* - * Commit all pending writes to stable storage. +/** + * nfsd_commit - Commit pending writes to stable storage + * @rqstp: RPC request being processed + * @fhp: NFS filehandle + * @offset: raw offset from beginning of file + * @count: raw count of bytes to sync + * @verf: filled in with the server's current write verifier * - * Note: we only guarantee that data that lies within the range specified - * by the 'offset' and 'count' parameters will be synced. + * Note: we guarantee that data that lies within the range specified + * by the 'offset' and 'count' parameters will be synced. The server + * is permitted to sync data that lies outside this range at the + * same time. * * Unfortunately we cannot lock the file to make sure we return full WCC * data to the client, as locking happens lower down in the filesystem. + * + * Return values: + * An nfsstat value in network byte order. */ __be32 -nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp, - loff_t offset, unsigned long count, __be32 *verf) +nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp, u64 offset, + u32 count, __be32 *verf) { + u64 maxbytes; + loff_t start, end; struct nfsd_net *nn; struct nfsd_file *nf; - loff_t end = LLONG_MAX; - __be32 err = nfserr_inval; - - if (offset < 0) - goto out; - if (count != 0) { - end = offset + (loff_t)count - 1; - if (end < offset) - goto out; - } + __be32 err; err = nfsd_file_acquire(rqstp, fhp, NFSD_MAY_WRITE|NFSD_MAY_NOT_BREAK_LEASE, &nf); if (err) goto out; + + /* + * Convert the client-provided (offset, count) range to a + * (start, end) range. If the client-provided range falls + * outside the maximum file size of the underlying FS, + * clamp the sync range appropriately. + */ + start = 0; + end = LLONG_MAX; + maxbytes = (u64)fhp->fh_dentry->d_sb->s_maxbytes; + if (offset < maxbytes) { + start = offset; + if (count && (offset + count - 1 < maxbytes)) + end = offset + count - 1; + } + nn = net_generic(nf->nf_net, nfsd_net_id); if (EX_ISSYNC(fhp->fh_export)) { errseq_t since = READ_ONCE(nf->nf_file->f_wb_err); int err2; - err2 = vfs_fsync_range(nf->nf_file, offset, end, 0); + err2 = vfs_fsync_range(nf->nf_file, start, end, 0); switch (err2) { case 0: nfsd_copy_write_verifier(verf, nn); diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h index 9f56dcb22ff7..2c43d10e3cab 100644 --- a/fs/nfsd/vfs.h +++ b/fs/nfsd/vfs.h @@ -74,8 +74,8 @@ __be32 do_nfsd_create(struct svc_rqst *, struct svc_fh *, char *name, int len, struct iattr *attrs, struct svc_fh *res, int createmode, u32 *verifier, bool *truncp, bool *created); -__be32 nfsd_commit(struct svc_rqst *, struct svc_fh *, - loff_t, unsigned long, __be32 *verf); +__be32 nfsd_commit(struct svc_rqst *rqst, struct svc_fh *fhp, + u64 offset, u32 count, __be32 *verf); #endif /* CONFIG_NFSD_V3 */ #ifdef CONFIG_NFSD_V4 __be32 nfsd_getxattr(struct svc_rqst *rqstp, struct svc_fh *fhp, From patchwork Thu Jan 27 16:08:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever III X-Patchwork-Id: 12726996 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AC4A4C433FE for ; Thu, 27 Jan 2022 16:08:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243304AbiA0QIy (ORCPT ); Thu, 27 Jan 2022 11:08:54 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44876 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235028AbiA0QIx (ORCPT ); Thu, 27 Jan 2022 11:08:53 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2A17DC061714; Thu, 27 Jan 2022 08:08:53 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id BB1A56187A; Thu, 27 Jan 2022 16:08:52 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id F21B1C340E4; Thu, 27 Jan 2022 16:08:51 +0000 (UTC) From: Chuck Lever To: linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH RFC 4/6] NFSD: Replace directory offset placeholder Date: Thu, 27 Jan 2022 11:08:51 -0500 Message-Id: <164329973085.5879.646571358048546056.stgit@bazille.1015granger.net> X-Mailer: git-send-email 2.34.0 In-Reply-To: <164329914731.5879.7791856151631542523.stgit@bazille.1015granger.net> References: <164329914731.5879.7791856151631542523.stgit@bazille.1015granger.net> User-Agent: StGit/1.4 MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=1401; h=from:subject:message-id; bh=ygQDJkZe0ROoIfeyx+08PXyGOCpWwxtxOJwsrSj4nxk=; b=owEBbQKS/ZANAwAIATNqszNvZn+XAcsmYgBh8sOSkeaCbAX6y3q5XgrTPcO2rzoePl6Q5tA5/Zcr wXvg2aOJAjMEAAEIAB0WIQQosuWwEobfJDzyPv4zarMzb2Z/lwUCYfLDkgAKCRAzarMzb2Z/l4DSD/ 9UKJNt8F+KnnQKL1EUErYhfyMgPZOmLBY54lJ4puOcDZsQIxeD4CeJT7T1PYyaJiehzQK+x24L8Iw/ 2hLgWRHRXKmrq7VTytsu+d10ykqjoMO2Rqr3MYQUzMgAQgOJbD+erR9fa7w8SHL21VAhGs439AddmM 9eM97c5DMBVWB87PV/J3sGnDI6fBzucCfq90XualL6Sm8vnLJ0+7xaVJo1AdE+Fy+ZpxDSchdK4oMu aBViS4s1Gg1wIGkFFOY6r1tqjx0ZLWGXG3SaQkv6pKGmNlzZJs7puAA2B0KNBQR7AWfCyBFn1J8DGL zWMaH1RSoiNgLZSIfEYKf/HJDAFkfiG+mMijZZ+fPe69QfulKDHg6grKlbLHBUzxyCSgE48zlX4kAj 9kbDlLdfgYos/4kkynD+2ALwH2cjTyQg6hl9RU1izWmsSv6webGIP+8B4W5b37+RwI4uiR6mupK5VI YrzxpUq7p5XL3H4liIa5sROJObQ+nLSnil4WBsdZU2hl2G28lUhTHndBwyfdpXWFADSE1xf3uKig+y FKFonL010vJSl0FDL7l83fY2+rXVUPTHXSqxwULyWqtyWjjWkjSqKPO02fAgoA1ePcQxKgJvJaPlhm UoTyWm+4X8YENr+/mT/QE82zOgYUkE6fAloJPFJ6wWhn9INUnuyAlr/ihVjw== X-Developer-Key: i=chuck.lever@oracle.com; a=openpgp; fpr=28B2E5B01286DF243CF23EFE336AB3336F667F97 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org I'm about to remove NFS_OFFSET_MAX, so use a different symbolic constant to mark the place of the offset field in directory entries. OFFSET_MAX has the same value as NFS_OFFSET_MAX. Signed-off-by: Chuck Lever --- fs/nfsd/nfs3xdr.c | 2 +- fs/nfsd/nfs4xdr.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index 2e47a07029f1..0293b8d65f10 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c @@ -1060,7 +1060,7 @@ svcxdr_encode_entry3_common(struct nfsd3_readdirres *resp, const char *name, return false; /* cookie */ resp->cookie_offset = dirlist->len; - if (xdr_stream_encode_u64(xdr, NFS_OFFSET_MAX) < 0) + if (xdr_stream_encode_u64(xdr, OFFSET_MAX) < 0) return false; return true; diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 7d2217cdaeaa..64d73b750491 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -3505,7 +3505,7 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen, p = xdr_reserve_space(xdr, 3*4 + namlen); if (!p) goto fail; - p = xdr_encode_hyper(p, NFS_OFFSET_MAX); /* offset of next entry */ + p = xdr_encode_hyper(p, OFFSET_MAX); /* offset of next entry */ p = xdr_encode_array(p, name, namlen); /* name length & name */ nfserr = nfsd4_encode_dirent_fattr(xdr, cd, name, namlen); From patchwork Thu Jan 27 16:08:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever III X-Patchwork-Id: 12726997 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5308EC433EF for ; Thu, 27 Jan 2022 16:09:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243399AbiA0QJB (ORCPT ); Thu, 27 Jan 2022 11:09:01 -0500 Received: from ams.source.kernel.org ([145.40.68.75]:49850 "EHLO ams.source.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232851AbiA0QJB (ORCPT ); Thu, 27 Jan 2022 11:09:01 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id E4F8CB8018A; Thu, 27 Jan 2022 16:08:59 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 76C98C340E4; Thu, 27 Jan 2022 16:08:58 +0000 (UTC) From: Chuck Lever To: linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH RFC 5/6] NFSD: Remove NFS_OFFSET_MAX Date: Thu, 27 Jan 2022 11:08:57 -0500 Message-Id: <164329973737.5879.52128759560418285.stgit@bazille.1015granger.net> X-Mailer: git-send-email 2.34.0 In-Reply-To: <164329914731.5879.7791856151631542523.stgit@bazille.1015granger.net> References: <164329914731.5879.7791856151631542523.stgit@bazille.1015granger.net> User-Agent: StGit/1.4 MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=916; h=from:subject:message-id; bh=sFAQLFzvhA4p13xvl949Xf12gutHKeO97iVOSPTRk6k=; b=owEBbQKS/ZANAwAIATNqszNvZn+XAcsmYgBh8sOZl+LQLRwYtMep9u8pEj019hCcDoSoH+h9hNYw cP8j5uuJAjMEAAEIAB0WIQQosuWwEobfJDzyPv4zarMzb2Z/lwUCYfLDmQAKCRAzarMzb2Z/lyZ9D/ 9m5aUTsz7/N5QZT5E7PUM1SA/4w9+kG+gCiOehdWshrDOTeMW5Px+tqxj94Z/h0PJjOrUtvqVY0v3R hDyvV8EkHs3OOEhHptsWwUF15UNctW+w6H/Bt+JrIjsw5UbCr4t8KfsO4BeIAYLaGB4XTor4NtZErW 5dKBi9CAXwFhAtvVzwmF3SbZfabxHkeeL+XG0JJP4/p4QUCBKOe89VWDnpT4w8PkpRPs7wqrI1xtaS yN38oT2lWj6cPaiOEedbBqW8KorbRqVBHAJynhQ5nuQKJ4Vb6wIiAFJU1tINuojfBoZZuwcza9dadq nyQuT84LaSbIFVXBgdFU+xrjf1ZLHSerF9/1R71+A5Yv4LJJ/h0CMatmX8KL8SboXBCXYasvqps70H TTBNRAk5hyCu79qhh7C43HI5caO7M4NiIPLnutLx8NuEwLRT81Ov+fmIjlUMQTGC1YzHD83HkPZpOC PnhRaCAEBwon6+OXiCKNpN8GpDnASMNDT6QjIJUTDz/WjF6vLDA+Op05zpAhnEPfKMNJkGGrr0sgMo 8UGowFS/asje0SrWwvkXoUxpnLvXoUf0swh97TIF/3/zGGOmRZQo+l1kuOOcr4DTRRARmKbbgcBfTo 16ChJylvMSAxyJ4sY7RJJjA2fwONl0xVeoCgt4UhOyjGC12IY0iY9O7V9wHw== X-Developer-Key: i=chuck.lever@oracle.com; a=openpgp; fpr=28B2E5B01286DF243CF23EFE336AB3336F667F97 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org This constant was introduced way back in Linux v2.3.y before there was a kernel-wide OFFSET_MAX value. These days we prefer to check against the limits in the underlying filesystem instead. Signed-off-by: Chuck Lever --- include/linux/nfs.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/include/linux/nfs.h b/include/linux/nfs.h index 0dc7ad38a0da..b06375e88e58 100644 --- a/include/linux/nfs.h +++ b/include/linux/nfs.h @@ -36,14 +36,6 @@ static inline void nfs_copy_fh(struct nfs_fh *target, const struct nfs_fh *sourc memcpy(target->data, source->data, source->size); } - -/* - * This is really a general kernel constant, but since nothing like - * this is defined in the kernel headers, I have to do it here. - */ -#define NFS_OFFSET_MAX ((__s64)((~(__u64)0) >> 1)) - - enum nfs3_stable_how { NFS_UNSTABLE = 0, NFS_DATA_SYNC = 1, From patchwork Thu Jan 27 16:09:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever III X-Patchwork-Id: 12726998 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AFF06C433F5 for ; Thu, 27 Jan 2022 16:09:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243480AbiA0QJI (ORCPT ); Thu, 27 Jan 2022 11:09:08 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44930 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232851AbiA0QJG (ORCPT ); Thu, 27 Jan 2022 11:09:06 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 242C7C061714; Thu, 27 Jan 2022 08:09:06 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id B3F3C618A8; Thu, 27 Jan 2022 16:09:05 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id EE8FDC340E8; Thu, 27 Jan 2022 16:09:04 +0000 (UTC) From: Chuck Lever To: linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH RFC 6/6] NFSD: Clamp WRITE offsets Date: Thu, 27 Jan 2022 11:09:04 -0500 Message-Id: <164329974386.5879.9570306264604837233.stgit@bazille.1015granger.net> X-Mailer: git-send-email 2.34.0 In-Reply-To: <164329914731.5879.7791856151631542523.stgit@bazille.1015granger.net> References: <164329914731.5879.7791856151631542523.stgit@bazille.1015granger.net> User-Agent: StGit/1.4 MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=1764; h=from:subject:message-id; bh=GTLq72CbZ2YKLEMKSvDESFVcQNdG1hLyX3YuhtlMYXY=; b=owEBbQKS/ZANAwAIATNqszNvZn+XAcsmYgBh8sOfOwpoBVkKovhUsUkE5Ib8gOUmIEsFzKgqxNDI CAtJCRyJAjMEAAEIAB0WIQQosuWwEobfJDzyPv4zarMzb2Z/lwUCYfLDnwAKCRAzarMzb2Z/l/bAD/ 4wStVMzb4aek3np1pM4E9ybdY8naM+MLh7qcDp2Cm2xLa5LEu245UYoDIGbxNwRPQpRq45zQuinDeu 5wCCGrRkzLr0FAoMCBB2/knrHIVbqmEjvzHnky5rOneCoIrMDUlmbo1ZKF0EE+cSXLjR2X/n+4cWlj P4d9XFDq3dCThRx3t7EBbVIkuFpoD6T5iWYZZIIdvLODw/qFXB3LgElSCcNzmt+Na5MfnbcSNr2Rr8 0oiEheFTxYQroTAWRBFHq/AYxUlSCPLn5oBnjDQmMj1Z1j2DbIGxsI3BFBayeoaK3ITWB8BSGvb27e HZMGkiww1DCeBp57UGbnLE5mYnazIIfxZ9+admV5KhD+vqu1jLFWVPlZC1mHpjxWT6tM7gjO4ezvyf rPtyEn8ZGyDKkaEZNZ3IFQgLGKpxKUvfSjYaeeC0G77+VVp2Ruux7/liKpBdxe7lGH5e5UfKBVsdwg ZwZNYCd7Ox6JdpL+kXn85i3FfuX2w6ZlwyFR7aTg8YdU90FyYMQsDRwxUXScp4tvyS3dc3TYfjbMBa vwTlW5tlkUrw7r9413jLyqDHCaFyRJaIPUuRUW83rzCdExaRSNxjiwnGUFp2DoT8P6M/fWr5qsujxR 1RZ0XmmX9ruWw0v8tD7ern3Ws2HkbJWN01mTu6oKnoEBMSPBnztUBvdrPIhw== X-Developer-Key: i=chuck.lever@oracle.com; a=openpgp; fpr=28B2E5B01286DF243CF23EFE336AB3336F667F97 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Ensure that a client cannot specify a WRITE range that falls in a byte range outside what the kernel's internal types (such as loff_t, which is signed) can represent. The kiocb iterators, invoked in nfsd_vfs_write(), should properly limit write operations to within the underlying file system's s_maxbytes. Signed-off-by: Chuck Lever --- fs/nfsd/nfs3proc.c | 7 +++++++ fs/nfsd/nfs4proc.c | 4 +++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c index 7bca219a8146..ba72bbff53a5 100644 --- a/fs/nfsd/nfs3proc.c +++ b/fs/nfsd/nfs3proc.c @@ -216,6 +216,12 @@ nfsd3_proc_write(struct svc_rqst *rqstp) (unsigned long long) argp->offset, argp->stable? " stable" : ""); + resp->status = nfserr_fbig; + if (argp->offset >= OFFSET_MAX) + goto out; + if (argp->offset + argp->len >= OFFSET_MAX) + goto out; + fh_copy(&resp->fh, &argp->fh); resp->committed = argp->stable; nvecs = svc_fill_write_vector(rqstp, &argp->payload); @@ -224,6 +230,7 @@ nfsd3_proc_write(struct svc_rqst *rqstp) rqstp->rq_vec, nvecs, &cnt, resp->committed, resp->verf); resp->count = cnt; +out: return rpc_success; } diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index b8ac2b9bce74..2baf547b344f 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -1022,7 +1022,9 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, int nvecs; if (write->wr_offset >= OFFSET_MAX) - return nfserr_inval; + return nfserr_fbig; + if (write->wr_offset + write->wr_buflen >= OFFSET_MAX) + return nfserr_fbig; cnt = write->wr_buflen; trace_nfsd_write_start(rqstp, &cstate->current_fh,