[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <lsq.1461711744.879775957@decadent.org.uk>
Date: Wed, 27 Apr 2016 01:02:24 +0200
From: Ben Hutchings <ben@...adent.org.uk>
To: linux-kernel@...r.kernel.org, stable@...r.kernel.org
CC: akpm@...ux-foundation.org, "J. Bruce Fields" <bfields@...hat.com>
Subject: [PATCH 3.2 016/115] nfsd4: fix bad bounds checking
3.2.80-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: "J. Bruce Fields" <bfields@...hat.com>
commit 4aed9c46afb80164401143aa0fdcfe3798baa9d5 upstream.
A number of spots in the xdr decoding follow a pattern like
n = be32_to_cpup(p++);
READ_BUF(n + 4);
where n is a u32. The only bounds checking is done in READ_BUF itself,
but since it's checking (n + 4), it won't catch cases where n is very
large, (u32)(-4) or higher. I'm not sure exactly what the consequences
are, but we've seen crashes soon after.
Instead, just break these up into two READ_BUF()s.
Signed-off-by: J. Bruce Fields <bfields@...hat.com>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <ben@...adent.org.uk>
---
fs/nfsd/nfs4xdr.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -931,8 +931,9 @@ nfsd4_decode_rename(struct nfsd4_compoun
READ_BUF(4);
READ32(rename->rn_snamelen);
- READ_BUF(rename->rn_snamelen + 4);
+ READ_BUF(rename->rn_snamelen);
SAVEMEM(rename->rn_sname, rename->rn_snamelen);
+ READ_BUF(4);
READ32(rename->rn_tnamelen);
READ_BUF(rename->rn_tnamelen);
SAVEMEM(rename->rn_tname, rename->rn_tnamelen);
@@ -1009,13 +1010,14 @@ nfsd4_decode_setclientid(struct nfsd4_co
READ_BUF(8);
READ32(setclientid->se_callback_prog);
READ32(setclientid->se_callback_netid_len);
-
- READ_BUF(setclientid->se_callback_netid_len + 4);
+ READ_BUF(setclientid->se_callback_netid_len);
SAVEMEM(setclientid->se_callback_netid_val, setclientid->se_callback_netid_len);
+ READ_BUF(4);
READ32(setclientid->se_callback_addr_len);
- READ_BUF(setclientid->se_callback_addr_len + 4);
+ READ_BUF(setclientid->se_callback_addr_len);
SAVEMEM(setclientid->se_callback_addr_val, setclientid->se_callback_addr_len);
+ READ_BUF(4);
READ32(setclientid->se_callback_ident);
DECODE_TAIL;
@@ -1584,8 +1586,9 @@ nfsd4_decode_compound(struct nfsd4_compo
*/
READ_BUF(4);
READ32(argp->taglen);
- READ_BUF(argp->taglen + 8);
+ READ_BUF(argp->taglen);
SAVEMEM(argp->tag, argp->taglen);
+ READ_BUF(8);
READ32(argp->minorversion);
READ32(argp->opcnt);
Powered by blists - more mailing lists