From 163cdfca341b76c958567ae0966bd3575c5c6192 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 2 Jan 2023 12:07:52 -0500 Subject: [PATCH] SUNRPC: Decode most of RPC header with xdr_stream Done as part of hardening the server-side RPC header decoding path. Reviewed-by: Jeff Layton Signed-off-by: Chuck Lever --- net/sunrpc/svc.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index c3c80d2709fb..2cc804932543 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -1231,17 +1231,13 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) const struct svc_procedure *procp = NULL; struct svc_serv *serv = rqstp->rq_server; struct svc_process_info process; - __be32 *statp; - u32 vers; + __be32 *p, *statp; __be32 rpc_stat; int auth_res, rc; __be32 *reply_statp; rpc_stat = rpc_success; - if (argv->iov_len < 6*4) - goto err_short_len; - /* Will be turned off by GSS integrity and privacy services */ set_bit(RQ_SPLICE_OK, &rqstp->rq_flags); /* Will be turned off only when NFSv4 Sessions are used */ @@ -1253,15 +1249,18 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) svc_putnl(resv, RPC_REPLY); reply_statp = resv->iov_base + resv->iov_len; - vers = svc_getnl(argv); - if (vers != 2) /* RPC version number */ + svcxdr_init_decode(rqstp); + p = xdr_inline_decode(&rqstp->rq_arg_stream, XDR_UNIT * 4); + if (unlikely(!p)) + goto err_short_len; + if (*p++ != cpu_to_be32(RPC_VERSION)) goto err_bad_rpc; svc_putnl(resv, 0); /* ACCEPT */ - rqstp->rq_prog = svc_getnl(argv); /* program number */ - rqstp->rq_vers = svc_getnl(argv); /* version number */ - rqstp->rq_proc = svc_getnl(argv); /* procedure number */ + rqstp->rq_prog = be32_to_cpup(p++); + rqstp->rq_vers = be32_to_cpup(p++); + rqstp->rq_proc = be32_to_cpup(p); for (progp = serv->sv_program; progp; progp = progp->pg_next) if (rqstp->rq_prog == progp->pg_prog) @@ -1272,7 +1271,6 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) * We do this before anything else in order to get a decent * auth verifier. */ - svcxdr_init_decode(rqstp); auth_res = svc_authenticate(rqstp); /* Also give the program a chance to reject this call: */ if (auth_res == SVC_OK && progp) -- 2.20.1