SUNRPC: Convert unwrap data paths to use xdr_stream for replies

We're now moving svcxdr_init_encode() to /before/ the flavor's
->accept method has set rq_auth_slack. Add a helper that can
set rq_auth_slack /after/ svcxdr_init_encode() has been called.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
Chuck Lever 2023-01-08 11:30:15 -05:00
parent df18f9ccb9
commit 7bb0dfb223
2 changed files with 32 additions and 12 deletions

View File

@ -577,12 +577,34 @@ static inline void svcxdr_init_encode(struct svc_rqst *rqstp)
xdr->buf = buf;
xdr->iov = resv;
xdr->p = resv->iov_base + resv->iov_len;
xdr->end = resv->iov_base + PAGE_SIZE - rqstp->rq_auth_slack;
xdr->end = resv->iov_base + PAGE_SIZE;
buf->len = resv->iov_len;
xdr->page_ptr = buf->pages - 1;
buf->buflen = PAGE_SIZE * (rqstp->rq_page_end - buf->pages);
buf->buflen -= rqstp->rq_auth_slack;
xdr->rqst = NULL;
}
/**
* svcxdr_set_auth_slack -
* @rqstp: RPC transaction
* @slack: buffer space to reserve for the transaction's security flavor
*
* Set the request's slack space requirement, and set aside that much
* space in the rqstp's rq_res.head for use when the auth wraps the Reply.
*/
static inline void svcxdr_set_auth_slack(struct svc_rqst *rqstp, int slack)
{
struct xdr_stream *xdr = &rqstp->rq_res_stream;
struct xdr_buf *buf = &rqstp->rq_res;
struct kvec *resv = buf->head;
rqstp->rq_auth_slack = slack;
xdr->end -= XDR_QUADLEN(slack);
buf->buflen -= rqstp->rq_auth_slack;
WARN_ON(xdr->iov != resv);
WARN_ON(xdr->p > xdr->end);
}
#endif /* SUNRPC_SVC_H */

View File

@ -1685,24 +1685,22 @@ svcauth_gss_accept(struct svc_rqst *rqstp)
svcxdr_init_encode(rqstp);
break;
case RPC_GSS_SVC_INTEGRITY:
/* placeholders for length and seq. number: */
svc_putnl(resv, 0);
svc_putnl(resv, 0);
svcxdr_init_encode(rqstp);
/* placeholders for body length and seq. number: */
xdr_reserve_space(&rqstp->rq_res_stream, XDR_UNIT * 2);
if (svcauth_gss_unwrap_integ(rqstp, gc->gc_seq,
rsci->mechctx))
goto garbage_args;
rqstp->rq_auth_slack = RPC_MAX_AUTH_SIZE;
svcxdr_init_encode(rqstp);
svcxdr_set_auth_slack(rqstp, RPC_MAX_AUTH_SIZE);
break;
case RPC_GSS_SVC_PRIVACY:
/* placeholders for length and seq. number: */
svc_putnl(resv, 0);
svc_putnl(resv, 0);
svcxdr_init_encode(rqstp);
/* placeholders for body length and seq. number: */
xdr_reserve_space(&rqstp->rq_res_stream, XDR_UNIT * 2);
if (svcauth_gss_unwrap_priv(rqstp, gc->gc_seq,
rsci->mechctx))
goto garbage_args;
rqstp->rq_auth_slack = RPC_MAX_AUTH_SIZE * 2;
svcxdr_init_encode(rqstp);
svcxdr_set_auth_slack(rqstp, RPC_MAX_AUTH_SIZE * 2);
break;
default:
goto auth_err;