diff options
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
| -rw-r--r-- | fs/nfs/nfs4xdr.c | 26 | 
1 files changed, 10 insertions, 16 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index ca13483edd60..1bfbd67c556d 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -5045,22 +5045,19 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,  			 struct nfs_getaclres *res)  {  	unsigned int savep; -	__be32 *bm_p;  	uint32_t attrlen,  		 bitmap[3] = {0};  	int status; -	size_t page_len = xdr->buf->page_len; +	unsigned int pg_offset;  	res->acl_len = 0;  	if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)  		goto out; -	bm_p = xdr->p; -	res->acl_data_offset = be32_to_cpup(bm_p) + 2; -	res->acl_data_offset <<= 2; -	/* Check if the acl data starts beyond the allocated buffer */ -	if (res->acl_data_offset > page_len) -		return -ERANGE; +	xdr_enter_page(xdr, xdr->buf->page_len); + +	/* Calculate the offset of the page data */ +	pg_offset = xdr->buf->head[0].iov_len;  	if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)  		goto out; @@ -5074,23 +5071,20 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,  		/* The bitmap (xdr len + bitmaps) and the attr xdr len words  		 * are stored with the acl data to handle the problem of  		 * variable length bitmaps.*/ -		xdr->p = bm_p; +		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.... */ -		attrlen += res->acl_data_offset; -		if (attrlen > page_len) { +		res->acl_len = attrlen; +		if (attrlen > (xdr->nwords << 2)) {  			if (res->acl_flags & NFS4_ACL_LEN_REQUEST) {  				/* getxattr interface called with a NULL buf */ -				res->acl_len = attrlen;  				goto out;  			} -			dprintk("NFS: acl reply: attrlen %u > page_len %zu\n", -					attrlen, page_len); +			dprintk("NFS: acl reply: attrlen %u > page_len %u\n", +					attrlen, xdr->nwords << 2);  			return -EINVAL;  		} -		xdr_read_pages(xdr, attrlen); -		res->acl_len = attrlen;  	} else  		status = -EOPNOTSUPP;  |