Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

SUNRPC: Use unsigned string lengths in xdr_decode_string_inplace

XDR strings, opaques, and net objects should all use unsigned lengths.
To wit, RFC 4506 says:

4.2. Unsigned Integer

An XDR unsigned integer is a 32-bit datum that encodes a non-negative
integer in the range [0,4294967295].

...

4.11. String

The standard defines a string of n (numbered 0 through n-1) ASCII
bytes to be the number n encoded as an unsigned integer (as described
above), and followed by the n bytes of the string.

After this patch, xdr_decode_string_inplace now matches the other XDR
string and array helpers that take a string length argument. See:

xdr_encode_opaque_fixed, xdr_encode_opaque, xdr_encode_array

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Acked-By: NeilBrown <neilb@suse.de>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>

authored by

Chuck Lever and committed by
J. Bruce Fields
e5cff482 01b2969a

+7 -4
+2 -1
include/linux/sunrpc/xdr.h
··· 112 112 __be32 *xdr_encode_opaque_fixed(__be32 *p, const void *ptr, unsigned int len); 113 113 __be32 *xdr_encode_opaque(__be32 *p, const void *ptr, unsigned int len); 114 114 __be32 *xdr_encode_string(__be32 *p, const char *s); 115 - __be32 *xdr_decode_string_inplace(__be32 *p, char **sp, int *lenp, int maxlen); 115 + __be32 *xdr_decode_string_inplace(__be32 *p, char **sp, unsigned int *lenp, 116 + unsigned int maxlen); 116 117 __be32 *xdr_encode_netobj(__be32 *p, const struct xdr_netobj *); 117 118 __be32 *xdr_decode_netobj(__be32 *p, struct xdr_netobj *); 118 119
+5 -3
net/sunrpc/xdr.c
··· 96 96 EXPORT_SYMBOL(xdr_encode_string); 97 97 98 98 __be32 * 99 - xdr_decode_string_inplace(__be32 *p, char **sp, int *lenp, int maxlen) 99 + xdr_decode_string_inplace(__be32 *p, char **sp, 100 + unsigned int *lenp, unsigned int maxlen) 100 101 { 101 - unsigned int len; 102 + u32 len; 102 103 103 - if ((len = ntohl(*p++)) > maxlen) 104 + len = ntohl(*p++); 105 + if (len > maxlen) 104 106 return NULL; 105 107 *lenp = len; 106 108 *sp = (char *) p;