Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 322619
b: refs/heads/master
c: 1f1ea6c
h: refs/heads/master
i:
  322617: c2704ad
  322615: 4780cdc
v: v3
  • Loading branch information
Trond Myklebust authored and Trond Myklebust committed Sep 6, 2012
1 parent ee5c4f7 commit e279562
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 30 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: 21f498c2f73bd6150d82931f09965826dca0b5f2
refs/heads/master: 1f1ea6c2d9d8c0be9ec56454b05315273b5de8ce
31 changes: 12 additions & 19 deletions trunk/fs/nfs/nfs4proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -3739,7 +3739,7 @@ static void nfs4_write_cached_acl(struct inode *inode, struct page **pages, size
struct nfs4_cached_acl *acl;
size_t buflen = sizeof(*acl) + acl_len;

if (pages && buflen <= PAGE_SIZE) {
if (buflen <= PAGE_SIZE) {
acl = kmalloc(buflen, GFP_KERNEL);
if (acl == NULL)
goto out;
Expand Down Expand Up @@ -3784,7 +3784,6 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
};
unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE);
int ret = -ENOMEM, i;
size_t acl_len = 0;

/* As long as we're doing a round trip to the server anyway,
* let's be prepared for a page of acl data. */
Expand All @@ -3807,32 +3806,26 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
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)
res.acl_flags |= NFS4_ACL_LEN_REQUEST;

dprintk("%s buf %p buflen %zu npages %d args.acl_len %zu\n",
__func__, buf, buflen, npages, args.acl_len);
ret = nfs4_call_sync(NFS_SERVER(inode)->client, NFS_SERVER(inode),
&msg, &args.seq_args, &res.seq_res, 0);
if (ret)
goto out_free;

acl_len = res.acl_len;
if (acl_len > args.acl_len)
nfs4_write_cached_acl(inode, NULL, 0, acl_len);
else
nfs4_write_cached_acl(inode, pages, res.acl_data_offset,
acl_len);
if (buf) {
/* Handle the case where the passed-in buffer is too short */
if (res.acl_flags & NFS4_ACL_TRUNC) {
/* Did the user only issue a request for the acl length? */
if (buf == NULL)
goto out_ok;
ret = -ERANGE;
if (acl_len > buflen)
goto out_free;
_copy_from_pages(buf, pages, res.acl_data_offset,
acl_len);
goto out_free;
}
ret = acl_len;
nfs4_write_cached_acl(inode, pages, res.acl_data_offset, res.acl_len);
if (buf)
_copy_from_pages(buf, pages, res.acl_data_offset, res.acl_len);
out_ok:
ret = res.acl_len;
out_free:
for (i = 0; i < npages; i++)
if (pages[i])
Expand Down
14 changes: 5 additions & 9 deletions trunk/fs/nfs/nfs4xdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion trunk/include/linux/nfs_xdr.h
Original file line number Diff line number Diff line change
Expand Up @@ -652,7 +652,7 @@ struct nfs_getaclargs {
};

/* getxattr ACL interface flags */
#define NFS4_ACL_LEN_REQUEST 0x0001 /* zero length getxattr buffer */
#define NFS4_ACL_TRUNC 0x0001 /* ACL was truncated */
struct nfs_getaclres {
size_t acl_len;
size_t acl_data_offset;
Expand Down

0 comments on commit e279562

Please sign in to comment.