SUNRPC: Set rq_accept_statp inside ->accept methods
To navigate around the space that svcauth_gss_accept() reserves for the RPC payload body length and sequence number fields, svcauth_gss_release() does a little dance with the reply's accept_stat, moving the accept_stat value in the response buffer down by two words. Instead, let's have the ->accept() methods each set the proper final location of the accept_stat to avoid having to move things. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
parent
cee4db1945
commit
4bcf0343e8
4 changed files with 35 additions and 13 deletions
|
@ -544,4 +544,23 @@ static inline void svcxdr_set_auth_slack(struct svc_rqst *rqstp, int slack)
|
||||||
WARN_ON(xdr->p > xdr->end);
|
WARN_ON(xdr->p > xdr->end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* svcxdr_set_accept_stat - Reserve space for the accept_stat field
|
||||||
|
* @rqstp: RPC transaction context
|
||||||
|
*
|
||||||
|
* Return values:
|
||||||
|
* %true: Success
|
||||||
|
* %false: No response buffer space was available
|
||||||
|
*/
|
||||||
|
static inline bool svcxdr_set_accept_stat(struct svc_rqst *rqstp)
|
||||||
|
{
|
||||||
|
struct xdr_stream *xdr = &rqstp->rq_res_stream;
|
||||||
|
|
||||||
|
rqstp->rq_accept_statp = xdr_reserve_space(xdr, XDR_UNIT);
|
||||||
|
if (unlikely(!rqstp->rq_accept_statp))
|
||||||
|
return false;
|
||||||
|
*rqstp->rq_accept_statp = rpc_success;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* SUNRPC_SVC_H */
|
#endif /* SUNRPC_SVC_H */
|
||||||
|
|
|
@ -1220,7 +1220,7 @@ svcauth_gss_legacy_init(struct svc_rqst *rqstp,
|
||||||
if (!svcauth_gss_proc_init_verf(sn->rsc_cache, rqstp, &rsip->out_handle,
|
if (!svcauth_gss_proc_init_verf(sn->rsc_cache, rqstp, &rsip->out_handle,
|
||||||
&rsip->major_status, GSS_SEQ_WIN))
|
&rsip->major_status, GSS_SEQ_WIN))
|
||||||
goto out;
|
goto out;
|
||||||
if (xdr_stream_encode_u32(&rqstp->rq_res_stream, RPC_SUCCESS) < 0)
|
if (!svcxdr_set_accept_stat(rqstp))
|
||||||
goto out;
|
goto out;
|
||||||
if (!svcxdr_encode_gss_init_res(&rqstp->rq_res_stream, &rsip->out_handle,
|
if (!svcxdr_encode_gss_init_res(&rqstp->rq_res_stream, &rsip->out_handle,
|
||||||
&rsip->out_token, rsip->major_status,
|
&rsip->out_token, rsip->major_status,
|
||||||
|
@ -1348,7 +1348,7 @@ static int svcauth_gss_proxy_init(struct svc_rqst *rqstp,
|
||||||
if (!svcauth_gss_proc_init_verf(sn->rsc_cache, rqstp, &cli_handle,
|
if (!svcauth_gss_proc_init_verf(sn->rsc_cache, rqstp, &cli_handle,
|
||||||
&ud.major_status, GSS_SEQ_WIN))
|
&ud.major_status, GSS_SEQ_WIN))
|
||||||
goto out;
|
goto out;
|
||||||
if (xdr_stream_encode_u32(&rqstp->rq_res_stream, RPC_SUCCESS) < 0)
|
if (!svcxdr_set_accept_stat(rqstp))
|
||||||
goto out;
|
goto out;
|
||||||
if (!svcxdr_encode_gss_init_res(&rqstp->rq_res_stream, &cli_handle,
|
if (!svcxdr_encode_gss_init_res(&rqstp->rq_res_stream, &cli_handle,
|
||||||
&ud.out_token, ud.major_status,
|
&ud.out_token, ud.major_status,
|
||||||
|
@ -1640,16 +1640,18 @@ svcauth_gss_accept(struct svc_rqst *rqstp)
|
||||||
case RPC_GSS_PROC_DESTROY:
|
case RPC_GSS_PROC_DESTROY:
|
||||||
if (!svcauth_gss_encode_verf(rqstp, rsci->mechctx, gc->gc_seq))
|
if (!svcauth_gss_encode_verf(rqstp, rsci->mechctx, gc->gc_seq))
|
||||||
goto auth_err;
|
goto auth_err;
|
||||||
|
if (!svcxdr_set_accept_stat(rqstp))
|
||||||
|
goto auth_err;
|
||||||
/* Delete the entry from the cache_list and call cache_put */
|
/* Delete the entry from the cache_list and call cache_put */
|
||||||
sunrpc_cache_unhash(sn->rsc_cache, &rsci->h);
|
sunrpc_cache_unhash(sn->rsc_cache, &rsci->h);
|
||||||
if (xdr_stream_encode_u32(&rqstp->rq_res_stream, RPC_SUCCESS) < 0)
|
|
||||||
goto auth_err;
|
|
||||||
goto complete;
|
goto complete;
|
||||||
case RPC_GSS_PROC_DATA:
|
case RPC_GSS_PROC_DATA:
|
||||||
rqstp->rq_auth_stat = rpcsec_gsserr_ctxproblem;
|
rqstp->rq_auth_stat = rpcsec_gsserr_ctxproblem;
|
||||||
svcdata->verf_start = xdr_reserve_space(&rqstp->rq_res_stream, 0);
|
svcdata->verf_start = xdr_reserve_space(&rqstp->rq_res_stream, 0);
|
||||||
if (!svcauth_gss_encode_verf(rqstp, rsci->mechctx, gc->gc_seq))
|
if (!svcauth_gss_encode_verf(rqstp, rsci->mechctx, gc->gc_seq))
|
||||||
goto auth_err;
|
goto auth_err;
|
||||||
|
if (!svcxdr_set_accept_stat(rqstp))
|
||||||
|
goto auth_err;
|
||||||
rqstp->rq_cred = rsci->cred;
|
rqstp->rq_cred = rsci->cred;
|
||||||
get_group_info(rsci->cred.cr_group_info);
|
get_group_info(rsci->cred.cr_group_info);
|
||||||
rqstp->rq_auth_stat = rpc_autherr_badcred;
|
rqstp->rq_auth_stat = rpc_autherr_badcred;
|
||||||
|
@ -1706,7 +1708,6 @@ out:
|
||||||
static __be32 *
|
static __be32 *
|
||||||
svcauth_gss_prepare_to_wrap(struct svc_rqst *rqstp, struct gss_svc_data *gsd)
|
svcauth_gss_prepare_to_wrap(struct svc_rqst *rqstp, struct gss_svc_data *gsd)
|
||||||
{
|
{
|
||||||
struct xdr_buf *resbuf = &rqstp->rq_res;
|
|
||||||
__be32 *p;
|
__be32 *p;
|
||||||
u32 verf_len;
|
u32 verf_len;
|
||||||
|
|
||||||
|
@ -1721,13 +1722,11 @@ svcauth_gss_prepare_to_wrap(struct svc_rqst *rqstp, struct gss_svc_data *gsd)
|
||||||
p += 1;
|
p += 1;
|
||||||
verf_len = ntohl(*p++);
|
verf_len = ntohl(*p++);
|
||||||
p += XDR_QUADLEN(verf_len);
|
p += XDR_QUADLEN(verf_len);
|
||||||
/* move accept_stat to right place: */
|
|
||||||
memcpy(p, p + 2, 4);
|
/* Also don't wrap if the accept_stat is nonzero: */
|
||||||
/* Also don't wrap if the accept stat is nonzero: */
|
if (*rqstp->rq_accept_statp != rpc_success)
|
||||||
if (*p != rpc_success) {
|
|
||||||
resbuf->head[0].iov_len -= 2 * 4;
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
p++;
|
p++;
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1314,8 +1314,6 @@ svc_process_common(struct svc_rqst *rqstp)
|
||||||
trace_svc_process(rqstp, progp->pg_name);
|
trace_svc_process(rqstp, progp->pg_name);
|
||||||
|
|
||||||
aoffset = xdr_stream_pos(xdr);
|
aoffset = xdr_stream_pos(xdr);
|
||||||
rqstp->rq_accept_statp = xdr_reserve_space(&rqstp->rq_res_stream, XDR_UNIT);
|
|
||||||
*rqstp->rq_accept_statp = rpc_success;
|
|
||||||
|
|
||||||
/* un-reserve some of the out-queue now that we have a
|
/* un-reserve some of the out-queue now that we have a
|
||||||
* better idea of reply size
|
* better idea of reply size
|
||||||
|
|
|
@ -775,6 +775,8 @@ svcauth_null_accept(struct svc_rqst *rqstp)
|
||||||
if (xdr_stream_encode_opaque_auth(&rqstp->rq_res_stream,
|
if (xdr_stream_encode_opaque_auth(&rqstp->rq_res_stream,
|
||||||
RPC_AUTH_NULL, NULL, 0) < 0)
|
RPC_AUTH_NULL, NULL, 0) < 0)
|
||||||
return SVC_CLOSE;
|
return SVC_CLOSE;
|
||||||
|
if (!svcxdr_set_accept_stat(rqstp))
|
||||||
|
return SVC_CLOSE;
|
||||||
|
|
||||||
rqstp->rq_cred.cr_flavor = RPC_AUTH_NULL;
|
rqstp->rq_cred.cr_flavor = RPC_AUTH_NULL;
|
||||||
return SVC_OK;
|
return SVC_OK;
|
||||||
|
@ -866,6 +868,8 @@ svcauth_tls_accept(struct svc_rqst *rqstp)
|
||||||
RPC_AUTH_NULL, NULL, 0) < 0)
|
RPC_AUTH_NULL, NULL, 0) < 0)
|
||||||
return SVC_CLOSE;
|
return SVC_CLOSE;
|
||||||
}
|
}
|
||||||
|
if (!svcxdr_set_accept_stat(rqstp))
|
||||||
|
return SVC_CLOSE;
|
||||||
|
|
||||||
rqstp->rq_cred.cr_flavor = RPC_AUTH_TLS;
|
rqstp->rq_cred.cr_flavor = RPC_AUTH_TLS;
|
||||||
return SVC_OK;
|
return SVC_OK;
|
||||||
|
@ -960,6 +964,8 @@ svcauth_unix_accept(struct svc_rqst *rqstp)
|
||||||
if (xdr_stream_encode_opaque_auth(&rqstp->rq_res_stream,
|
if (xdr_stream_encode_opaque_auth(&rqstp->rq_res_stream,
|
||||||
RPC_AUTH_NULL, NULL, 0) < 0)
|
RPC_AUTH_NULL, NULL, 0) < 0)
|
||||||
return SVC_CLOSE;
|
return SVC_CLOSE;
|
||||||
|
if (!svcxdr_set_accept_stat(rqstp))
|
||||||
|
return SVC_CLOSE;
|
||||||
|
|
||||||
rqstp->rq_cred.cr_flavor = RPC_AUTH_UNIX;
|
rqstp->rq_cred.cr_flavor = RPC_AUTH_UNIX;
|
||||||
return SVC_OK;
|
return SVC_OK;
|
||||||
|
|
Loading…
Add table
Reference in a new issue