Commit a0952771 authored by Trond Myklebust's avatar Trond Myklebust Committed by Linus Torvalds

[PATCH] Fix buffer reservations in nfs4xdr.c

This fixes a couple of incorrect XDR buffer reservations.  The values
passed to RESERVE_SPACE() must reflect precisely the number of bytes
that we wish to send down the wire.
parent 5ab96f44
......@@ -161,9 +161,13 @@ encode_attrs(struct xdr_stream *xdr, struct iattr *iap)
* = 36 bytes, plus any contribution from variable-length fields
* such as owner/group/acl's.
*/
len = 36;
len = 16;
/* Sigh */
if (iap->ia_valid & ATTR_SIZE)
len += 8;
if (iap->ia_valid & ATTR_MODE)
len += 4;
if (iap->ia_valid & ATTR_UID) {
status = owner_namelen = encode_uid(owner_name, iap->ia_uid);
if (status < 0) {
......@@ -171,7 +175,7 @@ encode_attrs(struct xdr_stream *xdr, struct iattr *iap)
iap->ia_uid);
goto out;
}
len += XDR_QUADLEN(owner_namelen);
len += 4 + (XDR_QUADLEN(owner_namelen) << 2);
}
if (iap->ia_valid & ATTR_GID) {
status = owner_grouplen = encode_gid(owner_group, iap->ia_gid);
......@@ -180,8 +184,16 @@ encode_attrs(struct xdr_stream *xdr, struct iattr *iap)
iap->ia_gid);
goto out;
}
len += XDR_QUADLEN(owner_grouplen);
len += 4 + (XDR_QUADLEN(owner_grouplen) << 2);
}
if (iap->ia_valid & ATTR_ATIME_SET)
len += 16;
else if (iap->ia_valid & ATTR_ATIME)
len += 4;
if (iap->ia_valid & ATTR_MTIME_SET)
len += 16;
else if (iap->ia_valid & ATTR_MTIME)
len += 4;
RESERVE_SPACE(len);
/*
......@@ -204,13 +216,11 @@ encode_attrs(struct xdr_stream *xdr, struct iattr *iap)
bmval1 |= FATTR4_WORD1_OWNER;
WRITE32(owner_namelen);
WRITEMEM(owner_name, owner_namelen);
p += owner_namelen;
}
if (iap->ia_valid & ATTR_GID) {
bmval1 |= FATTR4_WORD1_OWNER_GROUP;
WRITE32(owner_grouplen);
WRITEMEM(owner_group, owner_grouplen);
p += owner_namelen;
}
if (iap->ia_valid & ATTR_ATIME_SET) {
bmval1 |= FATTR4_WORD1_TIME_ACCESS_SET;
......@@ -238,6 +248,11 @@ encode_attrs(struct xdr_stream *xdr, struct iattr *iap)
/*
* Now we backfill the bitmap and the attribute buffer length.
*/
if (len != ((char *)p - (char *)q) + 4) {
printk ("encode_attr: Attr length calculation error! %u != %u\n",
len, ((char *)p - (char *)q) + 4);
BUG();
}
len = (char *)p - (char *)q - 12;
*q++ = htonl(bmval0);
*q++ = htonl(bmval1);
......@@ -265,7 +280,7 @@ encode_close(struct xdr_stream *xdr, struct nfs4_close *close)
{
uint32_t *p;
RESERVE_SPACE(20);
RESERVE_SPACE(8+sizeof(nfs4_stateid));
WRITE32(OP_CLOSE);
WRITE32(close->cl_seqid);
WRITEMEM(close->cl_stateid, sizeof(nfs4_stateid));
......@@ -380,7 +395,7 @@ encode_open(struct xdr_stream *xdr, struct nfs4_open *open)
uint32_t *p;
/* seqid, share_access, share_deny, clientid, ownerlen, owner, opentype */
RESERVE_SPACE(52);
RESERVE_SPACE(36);
WRITE32(OP_OPEN);
WRITE32(0); /* seqid */
WRITE32(open->op_share_access);
......@@ -392,7 +407,7 @@ encode_open(struct xdr_stream *xdr, struct nfs4_open *open)
if (open->op_opentype == NFS4_OPEN_CREATE) {
if (open->op_createmode == NFS4_CREATE_EXCLUSIVE) {
RESERVE_SPACE(12);
RESERVE_SPACE(4+sizeof(nfs4_verifier));
WRITE32(open->op_createmode);
WRITEMEM(open->op_verifier, sizeof(nfs4_verifier));
}
......@@ -427,7 +442,7 @@ encode_open_confirm(struct xdr_stream *xdr, struct nfs4_open_confirm *open_confi
* Note: In this "stateless" implementation, the OPEN_CONFIRM
* seqid is always equal to 1.
*/
RESERVE_SPACE(24);
RESERVE_SPACE(8+sizeof(nfs4_stateid));
WRITE32(OP_OPEN_CONFIRM);
WRITEMEM(open_confirm->oc_stateid, sizeof(nfs4_stateid));
WRITE32(1);
......@@ -494,7 +509,7 @@ encode_readdir(struct xdr_stream *xdr, struct nfs4_readdir *readdir, struct rpc_
int replen;
uint32_t *p;
RESERVE_SPACE(40);
RESERVE_SPACE(32+sizeof(nfs4_verifier));
WRITE32(OP_READDIR);
WRITE64(readdir->rd_cookie);
WRITEMEM(readdir->rd_req_verifier, sizeof(nfs4_verifier));
......@@ -558,7 +573,7 @@ encode_rename(struct xdr_stream *xdr, struct nfs4_rename *rename)
WRITE32(rename->rn_oldnamelen);
WRITEMEM(rename->rn_oldname, rename->rn_oldnamelen);
RESERVE_SPACE(8 + rename->rn_newnamelen);
RESERVE_SPACE(4 + rename->rn_newnamelen);
WRITE32(rename->rn_newnamelen);
WRITEMEM(rename->rn_newname, rename->rn_newnamelen);
......@@ -605,7 +620,7 @@ encode_setattr(struct xdr_stream *xdr, struct nfs4_setattr *setattr)
int status;
uint32_t *p;
RESERVE_SPACE(20);
RESERVE_SPACE(4+sizeof(nfs4_stateid));
WRITE32(OP_SETATTR);
WRITEMEM(setattr->st_stateid, sizeof(nfs4_stateid));
......@@ -626,7 +641,7 @@ encode_setclientid(struct xdr_stream *xdr, struct nfs4_setclientid *setclientid)
len2 = strlen(setclientid->sc_netid);
len3 = strlen(setclientid->sc_uaddr);
total_len = XDR_QUADLEN(len1) + XDR_QUADLEN(len2) + XDR_QUADLEN(len3);
total_len = (total_len << 2) + 32;
total_len = (total_len << 2) + 24 + sizeof(nfs4_verifier);
RESERVE_SPACE(total_len);
WRITE32(OP_SETCLIENTID);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment