Merge branch 'pm-qos'
[firefly-linux-kernel-4.4.55.git] / fs / nfs / nfs4xdr.c
index 1bfbd67c556d753a21f046c87edc3c9b07b0b8f0..8dba6bd485578695fb791f8aa548bc8ac99b4391 100644 (file)
@@ -5072,18 +5072,14 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
                 * are stored with the acl data to handle the problem of
                 * variable length bitmaps.*/
                res->acl_data_offset = xdr_stream_pos(xdr) - pg_offset;
-
-               /* We ignore &savep and don't do consistency checks on
-                * the attr length.  Let userspace figure it out.... */
                res->acl_len = attrlen;
-               if (attrlen > (xdr->nwords << 2)) {
-                       if (res->acl_flags & NFS4_ACL_LEN_REQUEST) {
-                               /* getxattr interface called with a NULL buf */
-                               goto out;
-                       }
+
+               /* Check for receive buffer overflow */
+               if (res->acl_len > (xdr->nwords << 2) ||
+                   res->acl_len + res->acl_data_offset > xdr->buf->page_len) {
+                       res->acl_flags |= NFS4_ACL_TRUNC;
                        dprintk("NFS: acl reply: attrlen %u > page_len %u\n",
                                        attrlen, xdr->nwords << 2);
-                       return -EINVAL;
                }
        } else
                status = -EOPNOTSUPP;
@@ -6229,7 +6225,8 @@ static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
        status = decode_open(xdr, res);
        if (status)
                goto out;
-       if (decode_getfh(xdr, &res->fh) != 0)
+       status = decode_getfh(xdr, &res->fh);
+       if (status)
                goto out;
        decode_getfattr(xdr, res->f_attr, res->server);
 out: