From: trondmy@kernel.org
To: linux-nfs@vger.kernel.org
Subject: [PATCH v2 13/15] NFSv4.2: Don't error when exiting early on a READ_PLUS buffer overflow
Date: Fri, 11 Dec 2020 12:25:19 -0500 [thread overview]
Message-ID: <20201211172521.5567-14-trondmy@kernel.org> (raw)
In-Reply-To: <20201211172521.5567-13-trondmy@kernel.org>
From: Trond Myklebust <trond.myklebust@hammerspace.com>
Expanding the READ_PLUS extents can cause the read buffer to overflow.
If it does, then don't error, but just exit early.
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
---
fs/nfs/nfs42xdr.c | 36 +++++++++++++++++-------------------
1 file changed, 17 insertions(+), 19 deletions(-)
diff --git a/fs/nfs/nfs42xdr.c b/fs/nfs/nfs42xdr.c
index 6ba2a28e7e03..9ef5261a1a70 100644
--- a/fs/nfs/nfs42xdr.c
+++ b/fs/nfs/nfs42xdr.c
@@ -1025,16 +1025,16 @@ static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *re
return decode_op_hdr(xdr, OP_DEALLOCATE);
}
-static int decode_read_plus_data(struct xdr_stream *xdr, struct nfs_pgio_res *res,
- uint32_t *eof)
+static int decode_read_plus_data(struct xdr_stream *xdr,
+ struct nfs_pgio_res *res)
{
uint32_t count, recvd;
uint64_t offset;
__be32 *p;
p = xdr_inline_decode(xdr, 8 + 4);
- if (unlikely(!p))
- return -EIO;
+ if (!p)
+ return 1;
p = xdr_decode_hyper(p, &offset);
count = be32_to_cpup(p);
@@ -1043,13 +1043,8 @@ static int decode_read_plus_data(struct xdr_stream *xdr, struct nfs_pgio_res *re
recvd = count;
res->count += recvd;
- if (count > recvd) {
- dprintk("NFS: server cheating in read reply: "
- "count %u > recvd %u\n", count, recvd);
- *eof = 0;
+ if (count > recvd)
return 1;
- }
-
return 0;
}
@@ -1061,8 +1056,8 @@ static int decode_read_plus_hole(struct xdr_stream *xdr,
__be32 *p;
p = xdr_inline_decode(xdr, 8 + 8);
- if (unlikely(!p))
- return -EIO;
+ if (!p)
+ return 1;
p = xdr_decode_hyper(p, &offset);
p = xdr_decode_hyper(p, &length);
@@ -1089,10 +1084,8 @@ static int decode_read_plus_hole(struct xdr_stream *xdr,
recvd = xdr_expand_hole(xdr, res->count, length);
res->count += recvd;
- if (recvd < length) {
- *eof = 0;
+ if (recvd < length)
return 1;
- }
return 0;
}
@@ -1121,12 +1114,12 @@ static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res)
for (i = 0; i < segments; i++) {
p = xdr_inline_decode(xdr, 4);
- if (unlikely(!p))
- return -EIO;
+ if (!p)
+ goto early_out;
type = be32_to_cpup(p++);
if (type == NFS4_CONTENT_DATA)
- status = decode_read_plus_data(xdr, res, &eof);
+ status = decode_read_plus_data(xdr, res);
else if (type == NFS4_CONTENT_HOLE)
status = decode_read_plus_hole(xdr, args, res, &eof);
else
@@ -1135,12 +1128,17 @@ static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res)
if (status < 0)
return status;
if (status > 0)
- break;
+ goto early_out;
}
out:
res->eof = eof;
return 0;
+early_out:
+ if (unlikely(!i))
+ return -EIO;
+ res->eof = 0;
+ return 0;
}
static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res)
--
2.29.2
next prev parent reply other threads:[~2020-12-11 19:10 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-12-11 17:25 [PATCH v2 00/15] Fixes for the NFSv4.2 READ_PLUS operation trondmy
2020-12-11 17:25 ` [PATCH v2 01/15] SUNRPC: _shift_data_left/right_pages should check the shift length trondmy
2020-12-11 17:25 ` [PATCH v2 02/15] SUNRPC: Fixes for xdr_align_data() trondmy
2020-12-11 17:25 ` [PATCH v2 03/15] SUNRPC: Fix xdr_expand_hole() trondmy
2020-12-11 17:25 ` [PATCH v2 04/15] SUNRPC: Cleanup xdr_shrink_bufhead() trondmy
2020-12-11 17:25 ` [PATCH v2 05/15] SUNRPC: _copy_to/from_pages() now check for zero length trondmy
2020-12-11 17:25 ` [PATCH v2 06/15] SUNRPC: Clean up open coded setting of the xdr_stream 'nwords' field trondmy
2020-12-11 17:25 ` [PATCH v2 07/15] SUNRPC: Cleanup - constify a number of xdr_buf helpers trondmy
2020-12-11 17:25 ` [PATCH v2 08/15] SUNRPC: When expanding the buffer, we may need grow the sparse pages trondmy
2020-12-11 17:25 ` [PATCH v2 09/15] NFSv4.2: Ensure we always reset the result->count in decode_read_plus() trondmy
2020-12-11 17:25 ` [PATCH v2 10/15] NFSv4.2: decode_read_plus_data() must skip padding after data segment trondmy
2020-12-11 17:25 ` [PATCH v2 11/15] NFSv4.2: decode_read_plus_hole() needs to check the extent offset trondmy
2020-12-11 17:25 ` [PATCH v2 12/15] NFSv4.2: Handle hole lengths that exceed the READ_PLUS read buffer trondmy
2020-12-11 17:25 ` trondmy [this message]
2020-12-11 17:25 ` [PATCH v2 14/15] NFSv4.2: Deal with potential READ_PLUS data extent buffer overflow trondmy
2020-12-11 17:25 ` [PATCH v2 15/15] NFSv4.2/pnfs: Don't use READ_PLUS with pNFS yet trondmy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201211172521.5567-14-trondmy@kernel.org \
--to=trondmy@kernel.org \
--cc=linux-nfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.