[PATCH net v2 2/4] crypto/krb5, rxrpc: Fix lack of pre-decrypt/pre-verify length checks
Jeffrey E Altman
jaltman at auristor.com
Wed May 13 07:33:23 PDT 2026
On 5/13/2026 9:19 AM, David Howells wrote:
> Change the krb5 crypto library to provide facilities to precheck the length
> of the message about to be decrypted or verified.
>
> Fix AF_RXRPC to make use of this to validate DATA packets secured with
> RxGK.
>
> Fixes: 9d1d2b59341f ("rxrpc: rxgk: Implement the yfs-rxgk security class (GSSAPI)")
> Closes: https://sashiko.dev/#/patchset/20260511160753.607296-1-dhowells%40redhat.com
> Signed-off-by: David Howells <dhowells at redhat.com>
> cc: Marc Dionne <marc.dionne at auristor.com>
> cc: Jeffrey Altman <jaltman at auristor.com>
> cc: Herbert Xu <herbert at gondor.apana.org.au>
> cc: "David S. Miller" <davem at davemloft.net>
> cc: Eric Dumazet <edumazet at google.com>
> cc: Jakub Kicinski <kuba at kernel.org>
> cc: Paolo Abeni <pabeni at redhat.com>
> cc: Simon Horman <horms at kernel.org>
> cc: Chuck Lever <chuck.lever at oracle.com>
> cc: netdev at vger.kernel.org
> cc: linux-afs at lists.infradead.org
> cc: linux-nfs at vger.kernel.org
> cc: linux-crypto at vger.kernel.org
> cc: stable at vger.kernel.org
> ---
> Documentation/crypto/krb5.rst | 17 ++++++++---
> crypto/krb5/krb5_api.c | 54 +++++++++++++++++++++++++++++++----
> include/crypto/krb5.h | 9 ++++--
> include/trace/events/rxrpc.h | 1 +
> net/rxrpc/rxgk.c | 11 +++++--
> 5 files changed, 77 insertions(+), 15 deletions(-)
>
> diff --git a/Documentation/crypto/krb5.rst b/Documentation/crypto/krb5.rst
> index beffa0133446..f62e07ac6811 100644
> --- a/Documentation/crypto/krb5.rst
> +++ b/Documentation/crypto/krb5.rst
> @@ -158,13 +158,22 @@ returned.
> When a message has been received, the location and size of the data with the
> message can be determined by calling::
>
> - void crypto_krb5_where_is_the_data(const struct krb5_enctype *krb5,
> - enum krb5_crypto_mode mode,
> - size_t *_offset, size_t *_len);
> + int crypto_krb5_where_is_the_data(const struct krb5_enctype *krb5,
> + enum krb5_crypto_mode mode,
> + size_t *_offset, size_t *_len);
>
> The caller provides the offset and length of the message to the function, which
> then alters those values to indicate the region containing the data (plus any
> -padding). It is up to the caller to determine how much padding there is.
> +padding). It is up to the caller to determine how much padding there is. The
> +function returns an error if the length is too small or if the mode is
> +unsupported. An additional function::
> +
> + int crypto_krb5_check_data_len(const struct krb5_enctype *krb5,
> + enum krb5_crypto_mode mode,
> + size_t len, size_t min_content);
> +
> +is provided to just do a basic check that the decrypted/verified message would
> +have a sufficient minimum payload.
>
> Preparation Functions
> ---------------------
> diff --git a/crypto/krb5/krb5_api.c b/crypto/krb5/krb5_api.c
> index 23026d4206c8..c7ea40f900a7 100644
> --- a/crypto/krb5/krb5_api.c
> +++ b/crypto/krb5/krb5_api.c
> @@ -134,27 +134,69 @@ EXPORT_SYMBOL(crypto_krb5_how_much_data);
> * Find the offset and size of the data in a secure message so that this
> * information can be used in the metadata buffer which will get added to the
> * digest by crypto_krb5_verify_mic().
> + *
> + * Return: 0 if successful, -EBADMSG if the message is too short or -EINVAL if
> + * the mode is unsupported.
> */
> -void crypto_krb5_where_is_the_data(const struct krb5_enctype *krb5,
> - enum krb5_crypto_mode mode,
> - size_t *_offset, size_t *_len)
> +int crypto_krb5_where_is_the_data(const struct krb5_enctype *krb5,
> + enum krb5_crypto_mode mode,
> + size_t *_offset, size_t *_len)
> {
> switch (mode) {
> case KRB5_CHECKSUM_MODE:
> + if (*_len < krb5->cksum_len)
> + return -EBADMSG;
> *_offset += krb5->cksum_len;
> *_len -= krb5->cksum_len;
> - return;
> + return 0;
> case KRB5_ENCRYPT_MODE:
> + if (*_len < krb5->conf_len + krb5->cksum_len)
> + return -EBADMSG;
> *_offset += krb5->conf_len;
> *_len -= krb5->conf_len + krb5->cksum_len;
> - return;
> + return 0;
> default:
> WARN_ON_ONCE(1);
> - return;
> + return -EINVAL;
> }
> }
> EXPORT_SYMBOL(crypto_krb5_where_is_the_data);
>
> +/**
> + * crypto_krb5_check_data_len - Check a message is big enough
> + * @krb5: The encoding to use.
> + * @mode: Mode of operation.
> + * @len: The length of the secure blob.
> + * @min_content: Minimum length of the content inside the blob.
> + *
> + * Check that a message is large enough to hold whatever bits the encryption
> + * type wants to glue on (nonce, checksum) plus a minimum amount of content.
> + *
> + * Return: 0 if successful, -EBADMSG if the message is too short or -EINVAL if
> + * the mode is unsupported.
> + */
> +int crypto_krb5_check_data_len(const struct krb5_enctype *krb5,
> + enum krb5_crypto_mode mode,
> + size_t len, size_t min_content)
> +{
> + switch (mode) {
> + case KRB5_CHECKSUM_MODE:
> + if (len < krb5->cksum_len ||
> + len - krb5->cksum_len < min_content)
> + return -EBADMSG;
> + return 0;
> + case KRB5_ENCRYPT_MODE:
> + if (len < krb5->conf_len + krb5->cksum_len ||
> + len - (krb5->conf_len + krb5->cksum_len) < min_content)
> + return -EBADMSG;
> + return 0;
> + default:
> + WARN_ON_ONCE(1);
> + return -EINVAL;
> + }
> +}
> +EXPORT_SYMBOL(crypto_krb5_check_data_len);
> +
> /*
> * Prepare the encryption with derived key data.
> */
> diff --git a/include/crypto/krb5.h b/include/crypto/krb5.h
> index 71dd38f59be1..aac3ecf88467 100644
> --- a/include/crypto/krb5.h
> +++ b/include/crypto/krb5.h
> @@ -121,9 +121,12 @@ size_t crypto_krb5_how_much_buffer(const struct krb5_enctype *krb5,
> size_t crypto_krb5_how_much_data(const struct krb5_enctype *krb5,
> enum krb5_crypto_mode mode,
> size_t *_buffer_size, size_t *_offset);
> -void crypto_krb5_where_is_the_data(const struct krb5_enctype *krb5,
> - enum krb5_crypto_mode mode,
> - size_t *_offset, size_t *_len);
> +int crypto_krb5_where_is_the_data(const struct krb5_enctype *krb5,
> + enum krb5_crypto_mode mode,
> + size_t *_offset, size_t *_len);
> +int crypto_krb5_check_data_len(const struct krb5_enctype *krb5,
> + enum krb5_crypto_mode mode,
> + size_t len, size_t min_content);
> struct crypto_aead *crypto_krb5_prepare_encryption(const struct krb5_enctype *krb5,
> const struct krb5_buffer *TK,
> u32 usage, gfp_t gfp);
> diff --git a/include/trace/events/rxrpc.h b/include/trace/events/rxrpc.h
> index 573f2df3a2c9..704a10de6670 100644
> --- a/include/trace/events/rxrpc.h
> +++ b/include/trace/events/rxrpc.h
> @@ -71,6 +71,7 @@
> EM(rxkad_abort_resp_unknown_tkt, "rxkad-resp-unknown-tkt") \
> EM(rxkad_abort_resp_version, "rxkad-resp-version") \
> /* RxGK security errors */ \
> + EM(rxgk_abort_1_short_header, "rxgk1-short-hdr") \
> EM(rxgk_abort_1_verify_mic_eproto, "rxgk1-vfy-mic-eproto") \
> EM(rxgk_abort_2_decrypt_eproto, "rxgk2-dec-eproto") \
> EM(rxgk_abort_2_short_data, "rxgk2-short-data") \
> diff --git a/net/rxrpc/rxgk.c b/net/rxrpc/rxgk.c
> index 0d5e654da918..41180263e527 100644
> --- a/net/rxrpc/rxgk.c
> +++ b/net/rxrpc/rxgk.c
> @@ -480,8 +480,10 @@ static int rxgk_verify_packet_integrity(struct rxrpc_call *call,
>
> _enter("");
>
> - crypto_krb5_where_is_the_data(gk->krb5, KRB5_CHECKSUM_MODE,
> - &data_offset, &data_len);
> + if (crypto_krb5_where_is_the_data(gk->krb5, KRB5_CHECKSUM_MODE,
> + &data_offset, &data_len) < 0)
> + return rxrpc_abort_eproto(call, skb, RXKADSEALEDINCON,
> + rxgk_abort_1_short_header);
>
> hdr = kzalloc_obj(*hdr, GFP_NOFS);
> if (!hdr)
> @@ -529,6 +531,11 @@ static int rxgk_verify_packet_encrypted(struct rxrpc_call *call,
>
> _enter("");
>
> + if (crypto_krb5_check_data_len(gk->krb5, KRB5_ENCRYPT_MODE,
> + len, sizeof(*hdr)) < 0)
> + return rxrpc_abort_eproto(call, skb, RXKADSEALEDINCON,
> + rxgk_abort_2_short_header);
> +
> ret = rxgk_decrypt_skb(gk->krb5, gk->rx_enc, skb, &offset, &len, &ac);
> if (ret < 0) {
> if (ret != -ENOMEM)
Reviewed-by: Jeffrey Altman <jaltman at auristor.com>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4467 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-afs/attachments/20260513/18ed2e66/attachment-0001.p7s>
More information about the linux-afs
mailing list