]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
NFSv4.2: Deal with potential READ_PLUS data extent buffer overflow
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Tue, 8 Dec 2020 14:03:51 +0000 (09:03 -0500)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Mon, 14 Dec 2020 11:51:08 +0000 (06:51 -0500)
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 <trond.myklebust@hammerspace.com>
fs/nfs/nfs42xdr.c

index 9ef5261a1a70d524ac2f70255dfd6c5221659ca9..8386ca45a43f8f214afe675b4a7543fb721c7e1c 100644 (file)
@@ -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