[PATCH 6.1 274/609] mac802154: llsec: reject frames shorter than the authentication tag
Greg Kroah-Hartman <[email protected]>
| Newsgroups | org.kernel.vger.stable,dev.linux.lists.patches |
|---|---|
| Message-ID | <[email protected]> |
6.1-stable review patch. If anyone has any objections, please let me know. ------------------ From: Doruk Tan Ozturk <[email protected]> commit fd3a3f28ed60c6af4b2a39933b151d6b27842c3b upstream. llsec_do_decrypt_auth() computes the associated-data length for the AEAD request as assoclen += datalen - authlen; where datalen is the number of bytes after the MAC header and authlen (4, 8 or 16) is the length of the authentication tag. Nothing verifies that the frame actually carries at least authlen payload bytes. A secured frame whose payload is shorter than the tag makes datalen - authlen negative; assoclen is then passed to aead_request_set_ad() as an unsigned value close to 4 GiB, so crypto_aead_decrypt() walks far off the end of the scatterlist that only spans the real frame. The frame is fully attacker-controlled and reaches this path from any IEEE 802.15.4 peer in radio range. Reject frames whose payload is shorter than the authentication tag before the subtraction. Dynamically reproduced on a KASAN kernel as a general-protection-fault in the AEAD scatterwalk, and the fix confirmed. Fixes: 4c14a2fb5d14 ("mac802154: add llsec decryption method") Cc: [email protected] Reviewed-by: Simon Horman <[email protected]> Signed-off-by: Doruk Tan Ozturk <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]> --- net/mac802154/llsec.c | 5 +++++ 1 file changed, 5 insertions(+) --- a/net/mac802154/llsec.c +++ b/net/mac802154/llsec.c @@ -888,6 +888,11 @@ llsec_do_decrypt_auth(struct sk_buff *sk data = skb_mac_header(skb) + skb->mac_len; datalen = skb_tail_pointer(skb) - data; + if (datalen < authlen) { + kfree_sensitive(req); + return -EBADMSG; + } + sg_init_one(&sg, skb_mac_header(skb), assoclen + datalen); if (!(hdr->sec.level & IEEE802154_SCF_SECLEVEL_ENC)) {