SUNRPC: Convert unwrap data paths to use xdr_stream for replies
authorChuck Lever <chuck.lever@oracle.com>
Sun, 8 Jan 2023 16:30:15 +0000 (11:30 -0500)
committerChuck Lever <chuck.lever@oracle.com>
Mon, 20 Feb 2023 14:20:28 +0000 (09:20 -0500)
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>
include/linux/sunrpc/svc.h
net/sunrpc/auth_gss/svcauth_gss.c

index ed722dd33b46618d2750e535df2269fb5c673ca8..dd9f68acd9f1bd1e209810f44ffd639577120e52 100644 (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 */
index 5c41c34dd83ebe637ced77c83eeab933a78abcb7..7f8cbd6e2d4efa933b19b1611dc5cad111827f70 100644 (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;