Skip to content

Commit 4bcf034

Browse files
committed
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>
1 parent cee4db1 commit 4bcf034

File tree

4 files changed

+35
-13
lines changed

4 files changed

+35
-13
lines changed

include/linux/sunrpc/svc.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,4 +544,23 @@ static inline void svcxdr_set_auth_slack(struct svc_rqst *rqstp, int slack)
544544
WARN_ON(xdr->p > xdr->end);
545545
}
546546

547+
/**
548+
* svcxdr_set_accept_stat - Reserve space for the accept_stat field
549+
* @rqstp: RPC transaction context
550+
*
551+
* Return values:
552+
* %true: Success
553+
* %false: No response buffer space was available
554+
*/
555+
static inline bool svcxdr_set_accept_stat(struct svc_rqst *rqstp)
556+
{
557+
struct xdr_stream *xdr = &rqstp->rq_res_stream;
558+
559+
rqstp->rq_accept_statp = xdr_reserve_space(xdr, XDR_UNIT);
560+
if (unlikely(!rqstp->rq_accept_statp))
561+
return false;
562+
*rqstp->rq_accept_statp = rpc_success;
563+
return true;
564+
}
565+
547566
#endif /* SUNRPC_SVC_H */

net/sunrpc/auth_gss/svcauth_gss.c

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,7 +1220,7 @@ svcauth_gss_legacy_init(struct svc_rqst *rqstp,
12201220
if (!svcauth_gss_proc_init_verf(sn->rsc_cache, rqstp, &rsip->out_handle,
12211221
&rsip->major_status, GSS_SEQ_WIN))
12221222
goto out;
1223-
if (xdr_stream_encode_u32(&rqstp->rq_res_stream, RPC_SUCCESS) < 0)
1223+
if (!svcxdr_set_accept_stat(rqstp))
12241224
goto out;
12251225
if (!svcxdr_encode_gss_init_res(&rqstp->rq_res_stream, &rsip->out_handle,
12261226
&rsip->out_token, rsip->major_status,
@@ -1348,7 +1348,7 @@ static int svcauth_gss_proxy_init(struct svc_rqst *rqstp,
13481348
if (!svcauth_gss_proc_init_verf(sn->rsc_cache, rqstp, &cli_handle,
13491349
&ud.major_status, GSS_SEQ_WIN))
13501350
goto out;
1351-
if (xdr_stream_encode_u32(&rqstp->rq_res_stream, RPC_SUCCESS) < 0)
1351+
if (!svcxdr_set_accept_stat(rqstp))
13521352
goto out;
13531353
if (!svcxdr_encode_gss_init_res(&rqstp->rq_res_stream, &cli_handle,
13541354
&ud.out_token, ud.major_status,
@@ -1640,16 +1640,18 @@ svcauth_gss_accept(struct svc_rqst *rqstp)
16401640
case RPC_GSS_PROC_DESTROY:
16411641
if (!svcauth_gss_encode_verf(rqstp, rsci->mechctx, gc->gc_seq))
16421642
goto auth_err;
1643+
if (!svcxdr_set_accept_stat(rqstp))
1644+
goto auth_err;
16431645
/* Delete the entry from the cache_list and call cache_put */
16441646
sunrpc_cache_unhash(sn->rsc_cache, &rsci->h);
1645-
if (xdr_stream_encode_u32(&rqstp->rq_res_stream, RPC_SUCCESS) < 0)
1646-
goto auth_err;
16471647
goto complete;
16481648
case RPC_GSS_PROC_DATA:
16491649
rqstp->rq_auth_stat = rpcsec_gsserr_ctxproblem;
16501650
svcdata->verf_start = xdr_reserve_space(&rqstp->rq_res_stream, 0);
16511651
if (!svcauth_gss_encode_verf(rqstp, rsci->mechctx, gc->gc_seq))
16521652
goto auth_err;
1653+
if (!svcxdr_set_accept_stat(rqstp))
1654+
goto auth_err;
16531655
rqstp->rq_cred = rsci->cred;
16541656
get_group_info(rsci->cred.cr_group_info);
16551657
rqstp->rq_auth_stat = rpc_autherr_badcred;
@@ -1706,7 +1708,6 @@ svcauth_gss_accept(struct svc_rqst *rqstp)
17061708
static __be32 *
17071709
svcauth_gss_prepare_to_wrap(struct svc_rqst *rqstp, struct gss_svc_data *gsd)
17081710
{
1709-
struct xdr_buf *resbuf = &rqstp->rq_res;
17101711
__be32 *p;
17111712
u32 verf_len;
17121713

@@ -1721,13 +1722,11 @@ svcauth_gss_prepare_to_wrap(struct svc_rqst *rqstp, struct gss_svc_data *gsd)
17211722
p += 1;
17221723
verf_len = ntohl(*p++);
17231724
p += XDR_QUADLEN(verf_len);
1724-
/* move accept_stat to right place: */
1725-
memcpy(p, p + 2, 4);
1726-
/* Also don't wrap if the accept stat is nonzero: */
1727-
if (*p != rpc_success) {
1728-
resbuf->head[0].iov_len -= 2 * 4;
1725+
1726+
/* Also don't wrap if the accept_stat is nonzero: */
1727+
if (*rqstp->rq_accept_statp != rpc_success)
17291728
return NULL;
1730-
}
1729+
17311730
p++;
17321731
return p;
17331732
}

net/sunrpc/svc.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1314,8 +1314,6 @@ svc_process_common(struct svc_rqst *rqstp)
13141314
trace_svc_process(rqstp, progp->pg_name);
13151315

13161316
aoffset = xdr_stream_pos(xdr);
1317-
rqstp->rq_accept_statp = xdr_reserve_space(&rqstp->rq_res_stream, XDR_UNIT);
1318-
*rqstp->rq_accept_statp = rpc_success;
13191317

13201318
/* un-reserve some of the out-queue now that we have a
13211319
* better idea of reply size

net/sunrpc/svcauth_unix.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,8 @@ svcauth_null_accept(struct svc_rqst *rqstp)
775775
if (xdr_stream_encode_opaque_auth(&rqstp->rq_res_stream,
776776
RPC_AUTH_NULL, NULL, 0) < 0)
777777
return SVC_CLOSE;
778+
if (!svcxdr_set_accept_stat(rqstp))
779+
return SVC_CLOSE;
778780

779781
rqstp->rq_cred.cr_flavor = RPC_AUTH_NULL;
780782
return SVC_OK;
@@ -866,6 +868,8 @@ svcauth_tls_accept(struct svc_rqst *rqstp)
866868
RPC_AUTH_NULL, NULL, 0) < 0)
867869
return SVC_CLOSE;
868870
}
871+
if (!svcxdr_set_accept_stat(rqstp))
872+
return SVC_CLOSE;
869873

870874
rqstp->rq_cred.cr_flavor = RPC_AUTH_TLS;
871875
return SVC_OK;
@@ -960,6 +964,8 @@ svcauth_unix_accept(struct svc_rqst *rqstp)
960964
if (xdr_stream_encode_opaque_auth(&rqstp->rq_res_stream,
961965
RPC_AUTH_NULL, NULL, 0) < 0)
962966
return SVC_CLOSE;
967+
if (!svcxdr_set_accept_stat(rqstp))
968+
return SVC_CLOSE;
963969

964970
rqstp->rq_cred.cr_flavor = RPC_AUTH_UNIX;
965971
return SVC_OK;

0 commit comments

Comments
 (0)