[PATCH v1 18/27] SUNRPC: Convert unwrap data paths to use xdr_stream for replies
From: Chuck Lever <cel@kernel.org>
Date: 2023-01-08 16:30:48
Subsystem:
kernel nfsd, sunrpc, and lockd servers, networking [general], nfs, sunrpc, and lockd clients, the rest · Maintainers:
Chuck Lever, Jeff Layton, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Trond Myklebust, Anna Schumaker, Linus Torvalds
From: Chuck Lever <redacted> 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. Signed-off-by: Chuck Lever <redacted> --- include/linux/sunrpc/svc.h | 26 ++++++++++++++++++++++++-- net/sunrpc/auth_gss/svcauth_gss.c | 18 ++++++++---------- 2 files changed, 32 insertions(+), 12 deletions(-)
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index ed722dd33b46..dd9f68acd9f1 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h@@ -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 */
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index 759169baa52f..fd1fd4143a8e 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c@@ -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;