Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rxrpc: Fix unhandled errors in rxgk_verify_packet_integrity()

rxgk_verify_packet_integrity() may get more errors than just -EPROTO from
rxgk_verify_mic_skb(). Pretty much anything other than -ENOMEM constitutes
an unrecoverable error. In the case of -ENOMEM, we can just drop the
packet and wait for a retransmission.

Similar happens with rxgk_decrypt_skb() and its callers.

Fix rxgk_decrypt_skb() or rxgk_verify_mic_skb() to return a greater variety
of abort codes and fix their callers to abort the connection on any error
apart from -ENOMEM.

Also preclear the variables used to hold the abort code returned from
rxgk_decrypt_skb() or rxgk_verify_mic_skb() to eliminate uninitialised
variable warnings.

Fixes: 9d1d2b59341f ("rxrpc: rxgk: Implement the yfs-rxgk security class (GSSAPI)")
Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
Closes: https://lists.infradead.org/pipermail/linux-afs/2025-April/009739.html
Closes: https://lists.infradead.org/pipermail/linux-afs/2025-April/009740.html
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/2038804.1757631496@warthog.procyon.org.uk
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

David Howells and committed by
Jakub Kicinski
64863f4c 70d99623

+28 -14
+10 -8
net/rxrpc/rxgk.c
··· 475 475 struct krb5_buffer metadata; 476 476 unsigned int offset = sp->offset, len = sp->len; 477 477 size_t data_offset = 0, data_len = len; 478 - u32 ac; 478 + u32 ac = 0; 479 479 int ret = -ENOMEM; 480 480 481 481 _enter(""); ··· 499 499 ret = rxgk_verify_mic_skb(gk->krb5, gk->rx_Kc, &metadata, 500 500 skb, &offset, &len, &ac); 501 501 kfree(hdr); 502 - if (ret == -EPROTO) { 503 - rxrpc_abort_eproto(call, skb, ac, 504 - rxgk_abort_1_verify_mic_eproto); 502 + if (ret < 0) { 503 + if (ret != -ENOMEM) 504 + rxrpc_abort_eproto(call, skb, ac, 505 + rxgk_abort_1_verify_mic_eproto); 505 506 } else { 506 507 sp->offset = offset; 507 508 sp->len = len; ··· 525 524 struct rxgk_header hdr; 526 525 unsigned int offset = sp->offset, len = sp->len; 527 526 int ret; 528 - u32 ac; 527 + u32 ac = 0; 529 528 530 529 _enter(""); 531 530 532 531 ret = rxgk_decrypt_skb(gk->krb5, gk->rx_enc, skb, &offset, &len, &ac); 533 - if (ret == -EPROTO) 534 - rxrpc_abort_eproto(call, skb, ac, rxgk_abort_2_decrypt_eproto); 535 - if (ret < 0) 532 + if (ret < 0) { 533 + if (ret != -ENOMEM) 534 + rxrpc_abort_eproto(call, skb, ac, rxgk_abort_2_decrypt_eproto); 536 535 goto error; 536 + } 537 537 538 538 if (len < sizeof(hdr)) { 539 539 ret = rxrpc_abort_eproto(call, skb, RXGK_PACKETSHORT,
+6 -4
net/rxrpc/rxgk_app.c
··· 187 187 struct key *server_key; 188 188 unsigned int ticket_offset, ticket_len; 189 189 u32 kvno, enctype; 190 - int ret, ec; 190 + int ret, ec = 0; 191 191 192 192 struct { 193 193 __be32 kvno; ··· 236 236 &ticket_offset, &ticket_len, &ec); 237 237 crypto_free_aead(token_enc); 238 238 token_enc = NULL; 239 - if (ret < 0) 240 - return rxrpc_abort_conn(conn, skb, ec, ret, 241 - rxgk_abort_resp_tok_dec); 239 + if (ret < 0) { 240 + if (ret != -ENOMEM) 241 + return rxrpc_abort_conn(conn, skb, ec, ret, 242 + rxgk_abort_resp_tok_dec); 243 + } 242 244 243 245 ret = conn->security->default_decode_ticket(conn, skb, ticket_offset, 244 246 ticket_len, _key);
+12 -2
net/rxrpc/rxgk_common.h
··· 88 88 *_offset += offset; 89 89 *_len = len; 90 90 break; 91 + case -EBADMSG: /* Checksum mismatch. */ 91 92 case -EPROTO: 92 - case -EBADMSG: 93 93 *_error_code = RXGK_SEALEDINCON; 94 94 break; 95 + case -EMSGSIZE: 96 + *_error_code = RXGK_PACKETSHORT; 97 + break; 98 + case -ENOPKG: /* Would prefer RXGK_BADETYPE, but not available for YFS. */ 95 99 default: 100 + *_error_code = RXGK_INCONSISTENCY; 96 101 break; 97 102 } 98 103 ··· 132 127 *_offset += offset; 133 128 *_len = len; 134 129 break; 130 + case -EBADMSG: /* Checksum mismatch */ 135 131 case -EPROTO: 136 - case -EBADMSG: 137 132 *_error_code = RXGK_SEALEDINCON; 138 133 break; 134 + case -EMSGSIZE: 135 + *_error_code = RXGK_PACKETSHORT; 136 + break; 137 + case -ENOPKG: /* Would prefer RXGK_BADETYPE, but not available for YFS. */ 139 138 default: 139 + *_error_code = RXGK_INCONSISTENCY; 140 140 break; 141 141 } 142 142