@@ -1249,7 +1249,6 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *resv)
svc_putnl(resv, RPC_REPLY);
reply_statp = resv->iov_base + resv->iov_len;
- svcxdr_init_decode(rqstp);
p = xdr_inline_decode(&rqstp->rq_arg_stream, XDR_UNIT * 4);
if (unlikely(!p))
goto err_short_len;
@@ -1425,9 +1424,8 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *resv)
int
svc_process(struct svc_rqst *rqstp)
{
- struct kvec *argv = &rqstp->rq_arg.head[0];
struct kvec *resv = &rqstp->rq_res.head[0];
- __be32 dir;
+ __be32 *p;
#if IS_ENABLED(CONFIG_FAIL_SUNRPC)
if (!fail_sunrpc.ignore_server_disconnect &&
@@ -1450,16 +1448,21 @@ svc_process(struct svc_rqst *rqstp)
rqstp->rq_res.tail[0].iov_base = NULL;
rqstp->rq_res.tail[0].iov_len = 0;
- dir = svc_getu32(argv);
- if (dir != rpc_call)
+ svcxdr_init_decode(rqstp);
+ p = xdr_inline_decode(&rqstp->rq_arg_stream, XDR_UNIT * 2);
+ if (unlikely(!p))
+ goto out_drop;
+ rqstp->rq_xid = *p++;
+ if (unlikely(*p != rpc_call))
goto out_baddir;
+
if (!svc_process_common(rqstp, resv))
goto out_drop;
return svc_send(rqstp);
out_baddir:
svc_printk(rqstp, "bad direction 0x%08x, dropping request\n",
- be32_to_cpu(dir));
+ be32_to_cpu(*p));
rqstp->rq_server->sv_stats->rpcbadfmt++;
out_drop:
svc_drop(rqstp);
@@ -1476,7 +1479,6 @@ int
bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req,
struct svc_rqst *rqstp)
{
- struct kvec *argv = &rqstp->rq_arg.head[0];
struct kvec *resv = &rqstp->rq_res.head[0];
struct rpc_task *task;
int proc_error;
@@ -1511,12 +1513,16 @@ bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req,
/* reset result send buffer "put" position */
resv->iov_len = 0;
+ svcxdr_init_decode(rqstp);
+
/*
- * Skip the next two words because they've already been
- * processed in the transport
+ * Skip the XID and calldir fields because they've already
+ * been processed by the caller.
*/
- svc_getu32(argv); /* XID */
- svc_getnl(argv); /* CALLDIR */
+ if (!xdr_inline_decode(&rqstp->rq_arg_stream, XDR_UNIT * 2)) {
+ error = -EINVAL;
+ goto out;
+ }
/* Parse and execute the bc call */
proc_error = svc_process_common(rqstp, resv);
@@ -890,7 +890,6 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
xprt->xpt_ops->xpo_secure_port(rqstp);
rqstp->rq_chandle.defer = svc_defer;
- rqstp->rq_xid = svc_getu32(&rqstp->rq_arg.head[0]);
if (serv->sv_stats)
serv->sv_stats->netcnt++;