aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs3xdr.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2012-06-20 22:35:05 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-06-28 17:20:43 -0400
commit64bd577ea0021f5903505de061b3b7d8a785ee94 (patch)
tree7081480d903325bb82d2384b69cff4579f289de1 /fs/nfs/nfs3xdr.c
parentc337d3655ce85e12c7c476cb81406521926cacd2 (diff)
NFS: Let xdr_read_pages() check for buffer overflows
xdr_read_pages will already do all of the buffer overflow checks that are currently being open-coded in the various callers. This patch simplifies the existing code by replacing the open coded checks. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs3xdr.c')
-rw-r--r--fs/nfs/nfs3xdr.c23
1 files changed, 3 insertions, 20 deletions
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
index 3c61c7f80a4b..d64a00ff5a16 100644
--- a/fs/nfs/nfs3xdr.c
+++ b/fs/nfs/nfs3xdr.c
@@ -246,7 +246,6 @@ static void encode_nfspath3(struct xdr_stream *xdr, struct page **pages,
246static int decode_nfspath3(struct xdr_stream *xdr) 246static int decode_nfspath3(struct xdr_stream *xdr)
247{ 247{
248 u32 recvd, count; 248 u32 recvd, count;
249 size_t hdrlen;
250 __be32 *p; 249 __be32 *p;
251 250
252 p = xdr_inline_decode(xdr, 4); 251 p = xdr_inline_decode(xdr, 4);
@@ -255,12 +254,9 @@ static int decode_nfspath3(struct xdr_stream *xdr)
255 count = be32_to_cpup(p); 254 count = be32_to_cpup(p);
256 if (unlikely(count >= xdr->buf->page_len || count > NFS3_MAXPATHLEN)) 255 if (unlikely(count >= xdr->buf->page_len || count > NFS3_MAXPATHLEN))
257 goto out_nametoolong; 256 goto out_nametoolong;
258 hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base; 257 recvd = xdr_read_pages(xdr, count);
259 recvd = xdr->buf->len - hdrlen;
260 if (unlikely(count > recvd)) 258 if (unlikely(count > recvd))
261 goto out_cheating; 259 goto out_cheating;
262
263 xdr_read_pages(xdr, count);
264 xdr_terminate_string(xdr->buf, count); 260 xdr_terminate_string(xdr->buf, count);
265 return 0; 261 return 0;
266 262
@@ -1587,7 +1583,6 @@ static int decode_read3resok(struct xdr_stream *xdr,
1587 struct nfs_readres *result) 1583 struct nfs_readres *result)
1588{ 1584{
1589 u32 eof, count, ocount, recvd; 1585 u32 eof, count, ocount, recvd;
1590 size_t hdrlen;
1591 __be32 *p; 1586 __be32 *p;
1592 1587
1593 p = xdr_inline_decode(xdr, 4 + 4 + 4); 1588 p = xdr_inline_decode(xdr, 4 + 4 + 4);
@@ -1598,13 +1593,10 @@ static int decode_read3resok(struct xdr_stream *xdr,
1598 ocount = be32_to_cpup(p++); 1593 ocount = be32_to_cpup(p++);
1599 if (unlikely(ocount != count)) 1594 if (unlikely(ocount != count))
1600 goto out_mismatch; 1595 goto out_mismatch;
1601 hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base; 1596 recvd = xdr_read_pages(xdr, count);
1602 recvd = xdr->buf->len - hdrlen;
1603 if (unlikely(count > recvd)) 1597 if (unlikely(count > recvd))
1604 goto out_cheating; 1598 goto out_cheating;
1605
1606out: 1599out:
1607 xdr_read_pages(xdr, count);
1608 result->eof = eof; 1600 result->eof = eof;
1609 result->count = count; 1601 result->count = count;
1610 return count; 1602 return count;
@@ -2039,16 +2031,7 @@ out_truncated:
2039 */ 2031 */
2040static int decode_dirlist3(struct xdr_stream *xdr) 2032static int decode_dirlist3(struct xdr_stream *xdr)
2041{ 2033{
2042 u32 recvd, pglen; 2034 return xdr_read_pages(xdr, xdr->buf->page_len);
2043 size_t hdrlen;
2044
2045 pglen = xdr->buf->page_len;
2046 hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
2047 recvd = xdr->buf->len - hdrlen;
2048 if (pglen > recvd)
2049 pglen = recvd;
2050 xdr_read_pages(xdr, pglen);
2051 return pglen;
2052} 2035}
2053 2036
2054static int decode_readdir3resok(struct xdr_stream *xdr, 2037static int decode_readdir3resok(struct xdr_stream *xdr,