diff options
| -rw-r--r-- | net/sunrpc/auth_gss/svcauth_gss.c | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index eeb1cce96649..447d9aef4605 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c | |||
| @@ -903,9 +903,9 @@ out_seq: | |||
| 903 | struct gss_svc_data { | 903 | struct gss_svc_data { |
| 904 | /* decoded gss client cred: */ | 904 | /* decoded gss client cred: */ |
| 905 | struct rpc_gss_wire_cred clcred; | 905 | struct rpc_gss_wire_cred clcred; |
| 906 | /* pointer to the beginning of the procedure-specific results, | 906 | /* save a pointer to the beginning of the encoded verifier, |
| 907 | * which may be encrypted/checksummed in svcauth_gss_release: */ | 907 | * for use in encryption/checksumming in svcauth_gss_release: */ |
| 908 | __be32 *body_start; | 908 | __be32 *verf_start; |
| 909 | struct rsc *rsci; | 909 | struct rsc *rsci; |
| 910 | }; | 910 | }; |
| 911 | 911 | ||
| @@ -968,7 +968,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp) | |||
| 968 | if (!svcdata) | 968 | if (!svcdata) |
| 969 | goto auth_err; | 969 | goto auth_err; |
| 970 | rqstp->rq_auth_data = svcdata; | 970 | rqstp->rq_auth_data = svcdata; |
| 971 | svcdata->body_start = NULL; | 971 | svcdata->verf_start = NULL; |
| 972 | svcdata->rsci = NULL; | 972 | svcdata->rsci = NULL; |
| 973 | gc = &svcdata->clcred; | 973 | gc = &svcdata->clcred; |
| 974 | 974 | ||
| @@ -1097,6 +1097,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp) | |||
| 1097 | goto complete; | 1097 | goto complete; |
| 1098 | case RPC_GSS_PROC_DATA: | 1098 | case RPC_GSS_PROC_DATA: |
| 1099 | *authp = rpcsec_gsserr_ctxproblem; | 1099 | *authp = rpcsec_gsserr_ctxproblem; |
| 1100 | svcdata->verf_start = resv->iov_base + resv->iov_len; | ||
| 1100 | if (gss_write_verf(rqstp, rsci->mechctx, gc->gc_seq)) | 1101 | if (gss_write_verf(rqstp, rsci->mechctx, gc->gc_seq)) |
| 1101 | goto auth_err; | 1102 | goto auth_err; |
| 1102 | rqstp->rq_cred = rsci->cred; | 1103 | rqstp->rq_cred = rsci->cred; |
| @@ -1110,7 +1111,6 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp) | |||
| 1110 | gc->gc_seq, rsci->mechctx)) | 1111 | gc->gc_seq, rsci->mechctx)) |
| 1111 | goto auth_err; | 1112 | goto auth_err; |
| 1112 | /* placeholders for length and seq. number: */ | 1113 | /* placeholders for length and seq. number: */ |
| 1113 | svcdata->body_start = resv->iov_base + resv->iov_len; | ||
| 1114 | svc_putnl(resv, 0); | 1114 | svc_putnl(resv, 0); |
| 1115 | svc_putnl(resv, 0); | 1115 | svc_putnl(resv, 0); |
| 1116 | break; | 1116 | break; |
| @@ -1119,7 +1119,6 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp) | |||
| 1119 | gc->gc_seq, rsci->mechctx)) | 1119 | gc->gc_seq, rsci->mechctx)) |
| 1120 | goto auth_err; | 1120 | goto auth_err; |
| 1121 | /* placeholders for length and seq. number: */ | 1121 | /* placeholders for length and seq. number: */ |
| 1122 | svcdata->body_start = resv->iov_base + resv->iov_len; | ||
| 1123 | svc_putnl(resv, 0); | 1122 | svc_putnl(resv, 0); |
| 1124 | svc_putnl(resv, 0); | 1123 | svc_putnl(resv, 0); |
| 1125 | break; | 1124 | break; |
| @@ -1150,14 +1149,21 @@ out: | |||
| 1150 | u32 * | 1149 | u32 * |
| 1151 | svcauth_gss_prepare_to_wrap(struct xdr_buf *resbuf, struct gss_svc_data *gsd) | 1150 | svcauth_gss_prepare_to_wrap(struct xdr_buf *resbuf, struct gss_svc_data *gsd) |
| 1152 | { | 1151 | { |
| 1153 | u32 *p; | 1152 | u32 *p, verf_len; |
| 1154 | 1153 | ||
| 1155 | p = gsd->body_start; | 1154 | p = gsd->verf_start; |
| 1156 | gsd->body_start = NULL; | 1155 | gsd->verf_start = NULL; |
| 1156 | |||
| 1157 | /* If the reply stat is nonzero, don't wrap: */ | ||
| 1158 | if (*(p-1) != rpc_success) | ||
| 1159 | return NULL; | ||
| 1160 | /* Skip the verifier: */ | ||
| 1161 | p += 1; | ||
| 1162 | verf_len = ntohl(*p++); | ||
| 1163 | p += XDR_QUADLEN(verf_len); | ||
| 1157 | /* move accept_stat to right place: */ | 1164 | /* move accept_stat to right place: */ |
| 1158 | memcpy(p, p + 2, 4); | 1165 | memcpy(p, p + 2, 4); |
| 1159 | /* Don't wrap in failure case: */ | 1166 | /* Also don't wrap if the accept stat is nonzero: */ |
| 1160 | /* Counting on not getting here if call was not even accepted! */ | ||
| 1161 | if (*p != rpc_success) { | 1167 | if (*p != rpc_success) { |
| 1162 | resbuf->head[0].iov_len -= 2 * 4; | 1168 | resbuf->head[0].iov_len -= 2 * 4; |
| 1163 | return NULL; | 1169 | return NULL; |
| @@ -1283,7 +1289,7 @@ svcauth_gss_release(struct svc_rqst *rqstp) | |||
| 1283 | if (gc->gc_proc != RPC_GSS_PROC_DATA) | 1289 | if (gc->gc_proc != RPC_GSS_PROC_DATA) |
| 1284 | goto out; | 1290 | goto out; |
| 1285 | /* Release can be called twice, but we only wrap once. */ | 1291 | /* Release can be called twice, but we only wrap once. */ |
| 1286 | if (gsd->body_start == NULL) | 1292 | if (gsd->verf_start == NULL) |
| 1287 | goto out; | 1293 | goto out; |
| 1288 | /* normally not set till svc_send, but we need it here: */ | 1294 | /* normally not set till svc_send, but we need it here: */ |
| 1289 | /* XXX: what for? Do we mess it up the moment we call svc_putu32 | 1295 | /* XXX: what for? Do we mess it up the moment we call svc_putu32 |
