|
@@ -83,23 +83,15 @@ static __be32 *read_buf(struct xdr_stream *xdr, size_t nbytes)
|
|
|
return p;
|
|
return p;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static __be32 decode_string(struct xdr_stream *xdr, unsigned int *len, const char **str)
|
|
|
|
|
|
|
+static __be32 decode_string(struct xdr_stream *xdr, unsigned int *len,
|
|
|
|
|
+ const char **str, size_t maxlen)
|
|
|
{
|
|
{
|
|
|
- __be32 *p;
|
|
|
|
|
-
|
|
|
|
|
- p = read_buf(xdr, 4);
|
|
|
|
|
- if (unlikely(p == NULL))
|
|
|
|
|
- return htonl(NFS4ERR_RESOURCE);
|
|
|
|
|
- *len = ntohl(*p);
|
|
|
|
|
-
|
|
|
|
|
- if (*len != 0) {
|
|
|
|
|
- p = read_buf(xdr, *len);
|
|
|
|
|
- if (unlikely(p == NULL))
|
|
|
|
|
- return htonl(NFS4ERR_RESOURCE);
|
|
|
|
|
- *str = (const char *)p;
|
|
|
|
|
- } else
|
|
|
|
|
- *str = NULL;
|
|
|
|
|
|
|
+ ssize_t err;
|
|
|
|
|
|
|
|
|
|
+ err = xdr_stream_decode_opaque_inline(xdr, (void **)str, maxlen);
|
|
|
|
|
+ if (err < 0)
|
|
|
|
|
+ return cpu_to_be32(NFS4ERR_RESOURCE);
|
|
|
|
|
+ *len = err;
|
|
|
return 0;
|
|
return 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -162,15 +154,9 @@ static __be32 decode_compound_hdr_arg(struct xdr_stream *xdr, struct cb_compound
|
|
|
__be32 *p;
|
|
__be32 *p;
|
|
|
__be32 status;
|
|
__be32 status;
|
|
|
|
|
|
|
|
- status = decode_string(xdr, &hdr->taglen, &hdr->tag);
|
|
|
|
|
|
|
+ status = decode_string(xdr, &hdr->taglen, &hdr->tag, CB_OP_TAGLEN_MAXSZ);
|
|
|
if (unlikely(status != 0))
|
|
if (unlikely(status != 0))
|
|
|
return status;
|
|
return status;
|
|
|
- /* We do not like overly long tags! */
|
|
|
|
|
- if (hdr->taglen > CB_OP_TAGLEN_MAXSZ) {
|
|
|
|
|
- printk("NFS: NFSv4 CALLBACK %s: client sent tag of length %u\n",
|
|
|
|
|
- __func__, hdr->taglen);
|
|
|
|
|
- return htonl(NFS4ERR_RESOURCE);
|
|
|
|
|
- }
|
|
|
|
|
p = read_buf(xdr, 12);
|
|
p = read_buf(xdr, 12);
|
|
|
if (unlikely(p == NULL))
|
|
if (unlikely(p == NULL))
|
|
|
return htonl(NFS4ERR_RESOURCE);
|
|
return htonl(NFS4ERR_RESOURCE);
|