Skip to content

Commit

Permalink
nfsd4: fix bad bounds checking
Browse files Browse the repository at this point in the history
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.

Cc: [email protected]
Signed-off-by: J. Bruce Fields <[email protected]>
  • Loading branch information
J. Bruce Fields committed Mar 1, 2016
1 parent b7052cd commit 4aed9c4
Showing 1 changed file with 8 additions and 5 deletions.
13 changes: 8 additions & 5 deletions fs/nfsd/nfs4xdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1072,8 +1072,9 @@ nfsd4_decode_rename(struct nfsd4_compoundargs *argp, struct nfsd4_rename *rename

READ_BUF(4);
rename->rn_snamelen = be32_to_cpup(p++);
READ_BUF(rename->rn_snamelen + 4);
READ_BUF(rename->rn_snamelen);
SAVEMEM(rename->rn_sname, rename->rn_snamelen);
READ_BUF(4);
rename->rn_tnamelen = be32_to_cpup(p++);
READ_BUF(rename->rn_tnamelen);
SAVEMEM(rename->rn_tname, rename->rn_tnamelen);
Expand Down Expand Up @@ -1155,13 +1156,14 @@ nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclient
READ_BUF(8);
setclientid->se_callback_prog = be32_to_cpup(p++);
setclientid->se_callback_netid_len = be32_to_cpup(p++);

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);
setclientid->se_callback_addr_len = be32_to_cpup(p++);

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);
setclientid->se_callback_ident = be32_to_cpup(p++);

DECODE_TAIL;
Expand Down Expand Up @@ -1835,8 +1837,9 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)

READ_BUF(4);
argp->taglen = be32_to_cpup(p++);
READ_BUF(argp->taglen + 8);
READ_BUF(argp->taglen);
SAVEMEM(argp->tag, argp->taglen);
READ_BUF(8);
argp->minorversion = be32_to_cpup(p++);
argp->opcnt = be32_to_cpup(p++);
max_reply += 4 + (XDR_QUADLEN(argp->taglen) << 2);
Expand Down

0 comments on commit 4aed9c4

Please sign in to comment.