Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 299893
b: refs/heads/master
c: 5a00689
h: refs/heads/master
i:
  299891: b7bd5e7
v: v3
  • Loading branch information
Sachin Prabhu authored and Trond Myklebust committed Apr 27, 2012
1 parent 2b2aeb4 commit d337c6a
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 14 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 10bd295a0b6488ebe634b72a11d8986bd3af3819
refs/heads/master: 5a00689930ab975fdd1b37b034475017e460cf2a
16 changes: 10 additions & 6 deletions trunk/fs/nfs/nfs4proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -3684,19 +3684,23 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
if (npages == 0)
npages = 1;

/* Add an extra page to handle the bitmap returned */
npages++;

for (i = 0; i < npages; i++) {
pages[i] = alloc_page(GFP_KERNEL);
if (!pages[i])
goto out_free;
}
if (npages > 1) {
/* for decoding across pages */
res.acl_scratch = alloc_page(GFP_KERNEL);
if (!res.acl_scratch)
goto out_free;
}

/* for decoding across pages */
res.acl_scratch = alloc_page(GFP_KERNEL);
if (!res.acl_scratch)
goto out_free;

args.acl_len = npages * PAGE_SIZE;
args.acl_pgbase = 0;

/* Let decode_getfacl know not to fail if the ACL data is larger than
* the page we send as a guess */
if (buf == NULL)
Expand Down
18 changes: 11 additions & 7 deletions trunk/fs/nfs/nfs4xdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -4902,11 +4902,19 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
bitmap[3] = {0};
struct kvec *iov = req->rq_rcv_buf.head;
int status;
size_t page_len = xdr->buf->page_len;

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;

if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
goto out;
if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
Expand All @@ -4916,28 +4924,24 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
return -EIO;
if (likely(bitmap[0] & FATTR4_WORD0_ACL)) {
size_t hdrlen;
u32 recvd;

/* 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 = be32_to_cpup(bm_p) + 2;
res->acl_data_offset <<= 2;

/* We ignore &savep and don't do consistency checks on
* the attr length. Let userspace figure it out.... */
hdrlen = (u8 *)xdr->p - (u8 *)iov->iov_base;
attrlen += res->acl_data_offset;
recvd = req->rq_rcv_buf.len - hdrlen;
if (attrlen > recvd) {
if (attrlen > page_len) {
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 > recvd %u\n",
attrlen, recvd);
dprintk("NFS: acl reply: attrlen %zu > page_len %u\n",
attrlen, page_len);
return -EINVAL;
}
xdr_read_pages(xdr, attrlen);
Expand Down

0 comments on commit d337c6a

Please sign in to comment.