From: Trond Myklebust Date: Tue, 8 Dec 2020 14:03:51 +0000 (-0500) Subject: NFSv4.2: Deal with potential READ_PLUS data extent buffer overflow X-Git-Tag: v5.11-rc1~81^2~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7aedc687c9f62e0d22b3231a100030e02344be1a;p=thirdparty%2Fkernel%2Flinux.git NFSv4.2: Deal with potential READ_PLUS data extent buffer overflow If the server returns more data than we have buffer space for, then we need to truncate and exit early. Signed-off-by: Trond Myklebust --- diff --git a/fs/nfs/nfs42xdr.c b/fs/nfs/nfs42xdr.c index 9ef5261a1a70d..8386ca45a43f8 100644 --- a/fs/nfs/nfs42xdr.c +++ b/fs/nfs/nfs42xdr.c @@ -1026,6 +1026,7 @@ static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *re } static int decode_read_plus_data(struct xdr_stream *xdr, + struct nfs_pgio_args *args, struct nfs_pgio_res *res) { uint32_t count, recvd; @@ -1041,8 +1042,12 @@ static int decode_read_plus_data(struct xdr_stream *xdr, recvd = xdr_align_data(xdr, res->count, xdr_align_size(count)); if (recvd > count) recvd = count; + if (res->count + recvd > args->count) { + if (args->count > res->count) + res->count += args->count - res->count; + return 1; + } res->count += recvd; - if (count > recvd) return 1; return 0; @@ -1119,7 +1124,7 @@ static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res) type = be32_to_cpup(p++); if (type == NFS4_CONTENT_DATA) - status = decode_read_plus_data(xdr, res); + status = decode_read_plus_data(xdr, args, res); else if (type == NFS4_CONTENT_HOLE) status = decode_read_plus_hole(xdr, args, res, &eof); else