| From 6260d9a56ab352b54891ec66ab0eced57d55abc6 Mon Sep 17 00:00:00 2001 |
| From: Chuck Lever <chuck.lever@oracle.com> |
| Date: Tue, 25 Jan 2022 16:36:22 -0500 |
| Subject: NFSD: Clamp WRITE offsets |
| |
| From: Chuck Lever <chuck.lever@oracle.com> |
| |
| commit 6260d9a56ab352b54891ec66ab0eced57d55abc6 upstream. |
| |
| 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. |
| |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Chuck Lever <chuck.lever@oracle.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| fs/nfsd/nfs3proc.c | 5 +++++ |
| fs/nfsd/nfs4proc.c | 5 +++-- |
| 2 files changed, 8 insertions(+), 2 deletions(-) |
| |
| --- a/fs/nfsd/nfs3proc.c |
| +++ b/fs/nfsd/nfs3proc.c |
| @@ -191,6 +191,11 @@ nfsd3_proc_write(struct svc_rqst *rqstp, |
| (unsigned long long) argp->offset, |
| argp->stable? " stable" : ""); |
| |
| + resp->status = nfserr_fbig; |
| + if (argp->offset > (u64)OFFSET_MAX || |
| + argp->offset + argp->len > (u64)OFFSET_MAX) |
| + return rpc_success; |
| + |
| fh_copy(&resp->fh, &argp->fh); |
| resp->committed = argp->stable; |
| nfserr = nfsd_write(rqstp, &resp->fh, NULL, |
| --- a/fs/nfsd/nfs4proc.c |
| +++ b/fs/nfsd/nfs4proc.c |
| @@ -982,8 +982,9 @@ nfsd4_write(struct svc_rqst *rqstp, stru |
| unsigned long cnt; |
| int nvecs; |
| |
| - if (write->wr_offset >= OFFSET_MAX) |
| - return nfserr_inval; |
| + if (write->wr_offset > (u64)OFFSET_MAX || |
| + write->wr_offset + write->wr_buflen > (u64)OFFSET_MAX) |
| + return nfserr_fbig; |
| |
| status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, |
| stateid, WR_STATE, &filp, NULL); |