From: Sachin Prabhu <sprabhu@redhat.com>
To: Trond Myklebust <Trond.Myklebust@netapp.com>
Cc: Dros Adamson <Weston.Adamson@netapp.com>,
Andy Adamson <William.Adamson@netapp.com>,
linux-nfs@vger.kernel.org
Subject: Re: [PATCH 1/3] NFSv4: Fix pointer arithmetic in decode_getacl
Date: Thu, 16 Aug 2012 14:29:34 +0100 [thread overview]
Message-ID: <1345123774.23681.10.camel@localhost> (raw)
In-Reply-To: <1344984447-17804-1-git-send-email-Trond.Myklebust@netapp.com>
On Tue, 2012-08-14 at 18:47 -0400, Trond Myklebust wrote:
> Resetting the cursor xdr->p to a previous value is not a safe
> practice: if the xdr_stream has crossed out of the initial iovec,
> then a bunch of other fields would need to be reset too.
>
> Fix this issue by using xdr_enter_page() so that the buffer gets
> page aligned at the bitmap _before_ we decode it.
>
> Also fix the confusion of the ACL length with the page buffer length
> by not adding the base offset to the ACL length...
>
> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
> Cc: stable@vger.kernel.org
> ---
> fs/nfs/nfs4proc.c | 2 +-
> fs/nfs/nfs4xdr.c | 21 +++++++--------------
> 2 files changed, 8 insertions(+), 15 deletions(-)
>
> diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
> index c77d296..286ab70 100644
> --- a/fs/nfs/nfs4proc.c
> +++ b/fs/nfs/nfs4proc.c
> @@ -3819,7 +3819,7 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
> if (ret)
> goto out_free;
>
> - acl_len = res.acl_len - res.acl_data_offset;
> + acl_len = res.acl_len;
> if (acl_len > args.acl_len)
> nfs4_write_cached_acl(inode, NULL, 0, acl_len);
> else
> diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
> index ca13483..54d3f5a 100644
> --- a/fs/nfs/nfs4xdr.c
> +++ b/fs/nfs/nfs4xdr.c
> @@ -5049,18 +5049,14 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
> uint32_t attrlen,
> bitmap[3] = {0};
> 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;
>
> + xdr_enter_page(xdr, xdr->buf->page_len);
> +
> 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;
> @@ -5074,23 +5070,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->p - bm_p) << 2;
The problem here is with an unbounded bitmap. In the case where the
server decides to send a large bitmap and the value of bitmap array + 2
(for the acl length attribute) is greater than the buffer allocated, we
will move to the tail section of the xdr and the pointer arithmetic here
will be wrong.
Maybe we are better off setting res->acl_data_offset as in the earlier
block. We will not need the variable bm_p in that case.
Sachin Prabhu
>
> /* 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 + res->acl_data_offset > xdr->buf->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 > page_len %zu\n",
> - attrlen, page_len);
> + dprintk("NFS: acl reply: attrlen %u > page_len %u\n",
> + attrlen, xdr->buf->page_len);
> return -EINVAL;
> }
> - xdr_read_pages(xdr, attrlen);
> - res->acl_len = attrlen;
> } else
> status = -EOPNOTSUPP;
>
next prev parent reply other threads:[~2012-08-16 13:30 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-08-14 22:47 [PATCH 1/3] NFSv4: Fix pointer arithmetic in decode_getacl Trond Myklebust
2012-08-14 22:47 ` [PATCH 2/3] NFSv4: Fix the acl cache size calculation Trond Myklebust
2012-08-14 22:47 ` [PATCH 3/3] NFSv4: Don't use private xdr_stream fields in decode_getacl Trond Myklebust
2012-08-16 13:29 ` Sachin Prabhu [this message]
2012-08-16 13:37 ` [PATCH 1/3] NFSv4: Fix pointer arithmetic " Myklebust, Trond
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1345123774.23681.10.camel@localhost \
--to=sprabhu@redhat.com \
--cc=Trond.Myklebust@netapp.com \
--cc=Weston.Adamson@netapp.com \
--cc=William.Adamson@netapp.com \
--cc=linux-nfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.