aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ.Bruce Fields <bfields@fieldses.org>2006-10-04 05:16:07 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-04 10:55:19 -0400
commit5b304bc5bfccc82b856e876e829c260df8e67ff2 (patch)
tree1ef7b419ff3d0a43ea745b375a8aa8209b59d28e
parent3c15a486643a103eaf068e5fb3b7f9d720d579a7 (diff)
[PATCH] knfsd: svcrpc: gss: fix failure on SVC_DENIED in integrity case
If the request is denied after gss_accept was called, we shouldn't try to wrap the reply. We were checking the accept_stat but not the reply_stat. To check the reply_stat in _release, we need a pointer to before (rather than after) the verifier, so modify body_start appropriately. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu> Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c30
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:
903struct gss_svc_data { 903struct 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:
1150u32 * 1149u32 *
1151svcauth_gss_prepare_to_wrap(struct xdr_buf *resbuf, struct gss_svc_data *gsd) 1150svcauth_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