Skip to content

Commit a7e429a

Browse files
committed
SUNRPC: Fix GSS privacy computation of auth->au_ralign
When the au_ralign field was added to gss_unwrap_resp_priv, the wrong calculation was used. Setting au_rslack == au_ralign is probably correct for kerberos_v1 privacy, but kerberos_v2 privacy adds additional GSS data after the clear text RPC message. au_ralign needs to be smaller than au_rslack in that fairly common case. When xdr_buf_trim() is restored to gss_unwrap_kerberos_v2(), it does exactly what I feared it would: it trims off part of the clear text RPC message. However, that's because rpc_prepare_reply_pages() does not set up the rq_rcv_buf's tail correctly because au_ralign is too large. Fixing the au_ralign computation also corrects the alignment of rq_rcv_buf->pages so that the client does not have to shift reply data payloads after they are received. Fixes: 35e77d2 ("SUNRPC: Add rpc_auth::au_ralign field") Signed-off-by: Chuck Lever <[email protected]>
1 parent 31c9590 commit a7e429a

File tree

3 files changed

+19
-9
lines changed

3 files changed

+19
-9
lines changed

include/linux/sunrpc/gss_api.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
struct gss_ctx {
2222
struct gss_api_mech *mech_type;
2323
void *internal_ctx_id;
24+
unsigned int slack, align;
2425
};
2526

2627
#define GSS_C_NO_BUFFER ((struct xdr_netobj) 0)

net/sunrpc/auth_gss/auth_gss.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2032,7 +2032,6 @@ gss_unwrap_resp_priv(struct rpc_task *task, struct rpc_cred *cred,
20322032
struct xdr_buf *rcv_buf = &rqstp->rq_rcv_buf;
20332033
struct kvec *head = rqstp->rq_rcv_buf.head;
20342034
struct rpc_auth *auth = cred->cr_auth;
2035-
unsigned int savedlen = rcv_buf->len;
20362035
u32 offset, opaque_len, maj_stat;
20372036
__be32 *p;
20382037

@@ -2059,10 +2058,9 @@ gss_unwrap_resp_priv(struct rpc_task *task, struct rpc_cred *cred,
20592058
*/
20602059
xdr_init_decode(xdr, rcv_buf, p, rqstp);
20612060

2062-
auth->au_rslack = auth->au_verfsize + 2 +
2063-
XDR_QUADLEN(savedlen - rcv_buf->len);
2064-
auth->au_ralign = auth->au_verfsize + 2 +
2065-
XDR_QUADLEN(savedlen - rcv_buf->len);
2061+
auth->au_rslack = auth->au_verfsize + 2 + ctx->gc_gss_ctx->slack;
2062+
auth->au_ralign = auth->au_verfsize + 2 + ctx->gc_gss_ctx->align;
2063+
20662064
return 0;
20672065
unwrap_failed:
20682066
trace_rpcgss_unwrap_failed(task);

net/sunrpc/auth_gss/gss_krb5_wrap.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,8 @@ gss_wrap_kerberos_v1(struct krb5_ctx *kctx, int offset,
262262

263263
static u32
264264
gss_unwrap_kerberos_v1(struct krb5_ctx *kctx, int offset, int len,
265-
struct xdr_buf *buf)
265+
struct xdr_buf *buf, unsigned int *slack,
266+
unsigned int *align)
266267
{
267268
int signalg;
268269
int sealalg;
@@ -280,6 +281,7 @@ gss_unwrap_kerberos_v1(struct krb5_ctx *kctx, int offset, int len,
280281
u32 conflen = kctx->gk5e->conflen;
281282
int crypt_offset;
282283
u8 *cksumkey;
284+
unsigned int saved_len = buf->len;
283285

284286
dprintk("RPC: gss_unwrap_kerberos\n");
285287

@@ -383,6 +385,10 @@ gss_unwrap_kerberos_v1(struct krb5_ctx *kctx, int offset, int len,
383385
if (gss_krb5_remove_padding(buf, blocksize))
384386
return GSS_S_DEFECTIVE_TOKEN;
385387

388+
/* slack must include room for krb5 padding */
389+
*slack = XDR_QUADLEN(saved_len - buf->len);
390+
/* The GSS blob always precedes the RPC message payload */
391+
*align = *slack;
386392
return GSS_S_COMPLETE;
387393
}
388394

@@ -489,7 +495,8 @@ gss_wrap_kerberos_v2(struct krb5_ctx *kctx, u32 offset,
489495

490496
static u32
491497
gss_unwrap_kerberos_v2(struct krb5_ctx *kctx, int offset, int len,
492-
struct xdr_buf *buf)
498+
struct xdr_buf *buf, unsigned int *slack,
499+
unsigned int *align)
493500
{
494501
time64_t now;
495502
u8 *ptr;
@@ -583,6 +590,8 @@ gss_unwrap_kerberos_v2(struct krb5_ctx *kctx, int offset, int len,
583590
/* Trim off the trailing "extra count" and checksum blob */
584591
buf->len -= ec + GSS_KRB5_TOK_HDR_LEN + tailskip;
585592

593+
*align = XDR_QUADLEN(GSS_KRB5_TOK_HDR_LEN + headskip);
594+
*slack = *align + XDR_QUADLEN(ec + GSS_KRB5_TOK_HDR_LEN + tailskip);
586595
return GSS_S_COMPLETE;
587596
}
588597

@@ -617,9 +626,11 @@ gss_unwrap_kerberos(struct gss_ctx *gctx, int offset,
617626
case ENCTYPE_DES_CBC_RAW:
618627
case ENCTYPE_DES3_CBC_RAW:
619628
case ENCTYPE_ARCFOUR_HMAC:
620-
return gss_unwrap_kerberos_v1(kctx, offset, len, buf);
629+
return gss_unwrap_kerberos_v1(kctx, offset, len, buf,
630+
&gctx->slack, &gctx->align);
621631
case ENCTYPE_AES128_CTS_HMAC_SHA1_96:
622632
case ENCTYPE_AES256_CTS_HMAC_SHA1_96:
623-
return gss_unwrap_kerberos_v2(kctx, offset, len, buf);
633+
return gss_unwrap_kerberos_v2(kctx, offset, len, buf,
634+
&gctx->slack, &gctx->align);
624635
}
625636
}

0 commit comments

Comments
 (0)