Skip to content

Commit 5f24a87

Browse files
committed
SUNRPC: Fix a crash in gss_krb5_checksum()
Anna says: > KASAN reports [...] a slab-out-of-bounds in gss_krb5_checksum(), > and it can cause my client to panic when running cthon basic > tests with krb5p. > Running faddr2line gives me: > > gss_krb5_checksum+0x4b6/0x630: > ahash_request_free at > /home/anna/Programs/linux-nfs.git/./include/crypto/hash.h:619 > (inlined by) gss_krb5_checksum at > /home/anna/Programs/linux-nfs.git/net/sunrpc/auth_gss/gss_krb5_crypto.c:358 My diagnosis is that the memcpy() at the end of gss_krb5_checksum() reads past the end of the buffer containing the checksum data because the callers have ignored gss_krb5_checksum()'s API contract: * Caller provides the truncation length of the output token (h) in * cksumout.len. Instead they provide the fixed length of the hmac buffer. This length happens to be larger than the value returned by crypto_ahash_digestsize(). Change these errant callers to work like krb5_etm_{en,de}crypt(). As a defensive measure, bound the length of the byte copy at the end of gss_krb5_checksum(). Kunit sez: Testing complete. Ran 68 tests: passed: 68 Elapsed time: 81.680s total, 5.875s configuring, 75.610s building, 0.103s running Reported-by: Anna Schumaker <schumaker.anna@gmail.com> Fixes: 8270dbf ("SUNRPC: Obscure Kerberos integrity keys") Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
1 parent 27c934d commit 5f24a87

File tree

1 file changed

+5
-5
lines changed

1 file changed

+5
-5
lines changed

net/sunrpc/auth_gss/gss_krb5_crypto.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,9 @@ gss_krb5_checksum(struct crypto_ahash *tfm, char *header, int hdrlen,
353353
err = crypto_ahash_final(req);
354354
if (err)
355355
goto out_free_ahash;
356-
memcpy(cksumout->data, checksumdata, cksumout->len);
356+
357+
memcpy(cksumout->data, checksumdata,
358+
min_t(int, cksumout->len, crypto_ahash_digestsize(tfm)));
357359

358360
out_free_ahash:
359361
ahash_request_free(req);
@@ -809,8 +811,7 @@ gss_krb5_aes_encrypt(struct krb5_ctx *kctx, u32 offset,
809811
buf->tail[0].iov_len += GSS_KRB5_TOK_HDR_LEN;
810812
buf->len += GSS_KRB5_TOK_HDR_LEN;
811813

812-
/* Do the HMAC */
813-
hmac.len = GSS_KRB5_MAX_CKSUM_LEN;
814+
hmac.len = kctx->gk5e->cksumlength;
814815
hmac.data = buf->tail[0].iov_base + buf->tail[0].iov_len;
815816

816817
/*
@@ -873,8 +874,7 @@ gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, u32 len,
873874
if (ret)
874875
goto out_err;
875876

876-
/* Calculate our hmac over the plaintext data */
877-
our_hmac_obj.len = sizeof(our_hmac);
877+
our_hmac_obj.len = kctx->gk5e->cksumlength;
878878
our_hmac_obj.data = our_hmac;
879879
ret = gss_krb5_checksum(ahash, NULL, 0, &subbuf, 0, &our_hmac_obj);
880880
if (ret)

0 commit comments

Comments
 (0)