Commit 846b5756 authored by Chuck Lever's avatar Chuck Lever

SUNRPC: Add an XDR decoding helper for struct opaque_auth

RFC 5531 defines the body of an RPC Call message like this:

	struct call_body {
		unsigned int rpcvers;
		unsigned int prog;
		unsigned int vers;
		unsigned int proc;
		opaque_auth cred;
		opaque_auth verf;
		/* procedure-specific parameters start here */
	};

In the current server code, decoding a struct opaque_auth type is
open-coded in several places, and is thus difficult to harden
everywhere.

Introduce a helper for decoding an opaque_auth within the context
of a xdr_stream. This helper can be shared with all authentication
flavor implemenations, even on the client-side.

Done as part of hardening the server-side RPC header decoding paths.
Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent 1e9e177d
......@@ -346,6 +346,9 @@ ssize_t xdr_stream_decode_string(struct xdr_stream *xdr, char *str,
size_t size);
ssize_t xdr_stream_decode_string_dup(struct xdr_stream *xdr, char **str,
size_t maxlen, gfp_t gfp_flags);
ssize_t xdr_stream_decode_opaque_auth(struct xdr_stream *xdr, u32 *flavor,
void **body, unsigned int *body_len);
/**
* xdr_align_size - Calculate padded size of an object
* @n: Size of an object being XDR encoded (in bytes)
......
......@@ -2274,3 +2274,31 @@ ssize_t xdr_stream_decode_string_dup(struct xdr_stream *xdr, char **str,
return ret;
}
EXPORT_SYMBOL_GPL(xdr_stream_decode_string_dup);
/**
* xdr_stream_decode_opaque_auth - Decode struct opaque_auth (RFC5531 S8.2)
* @xdr: pointer to xdr_stream
* @flavor: location to store decoded flavor
* @body: location to store decode body
* @body_len: location to store length of decoded body
*
* Return values:
* On success, returns the number of buffer bytes consumed
* %-EBADMSG on XDR buffer overflow
* %-EMSGSIZE if the decoded size of the body field exceeds 400 octets
*/
ssize_t xdr_stream_decode_opaque_auth(struct xdr_stream *xdr, u32 *flavor,
void **body, unsigned int *body_len)
{
ssize_t ret, len;
len = xdr_stream_decode_u32(xdr, flavor);
if (unlikely(len < 0))
return len;
ret = xdr_stream_decode_opaque_inline(xdr, body, RPC_MAX_AUTH_SIZE);
if (unlikely(ret < 0))
return ret;
*body_len = ret;
return len + ret;
}
EXPORT_SYMBOL_GPL(xdr_stream_decode_opaque_auth);
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