diff options
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
| -rw-r--r-- | fs/nfs/nfs4xdr.c | 17 | 
1 files changed, 7 insertions, 10 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 1bfbd67c556..8dba6bd4855 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -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:  |