Commit 2429a197 authored by David Howells's avatar David Howells Committed by Jakub Kicinski
Browse files

rxrpc: Fix untrusted unsigned subtract



Fix the following Smatch static checker warning:

   net/rxrpc/rxgk_app.c:65 rxgk_yfs_decode_ticket()
   warn: untrusted unsigned subtract. 'ticket_len - 10 * 4'

by prechecking the length of what we're trying to extract in two places in
the token and decoding for a response packet.

Also use sizeof() on the struct we're extracting rather specifying the size
numerically to be consistent with the other related statements.

Fixes: 9d1d2b59 ("rxrpc: rxgk: Implement the yfs-rxgk security class (GSSAPI)")
Reported-by: default avatarDan Carpenter <dan.carpenter@linaro.org>
Closes: https://lists.infradead.org/pipermail/linux-afs/2025-September/010135.html


Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Link: https://patch.msgid.link/2039268.1757631977@warthog.procyon.org.uk


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 64863f4c
Loading
Loading
Loading
Loading
+14 −5
Original line number Diff line number Diff line
@@ -54,6 +54,10 @@ int rxgk_yfs_decode_ticket(struct rxrpc_connection *conn, struct sk_buff *skb,

	_enter("");

	if (ticket_len < 10 * sizeof(__be32))
		return rxrpc_abort_conn(conn, skb, RXGK_INCONSISTENCY, -EPROTO,
					rxgk_abort_resp_short_yfs_tkt);

	/* Get the session key length */
	ret = skb_copy_bits(skb, ticket_offset, tmp, sizeof(tmp));
	if (ret < 0)
@@ -195,22 +199,23 @@ int rxgk_extract_token(struct rxrpc_connection *conn, struct sk_buff *skb,
		__be32 token_len;
	} container;

	if (token_len < sizeof(container))
		goto short_packet;

	/* Decode the RXGK_TokenContainer object.  This tells us which server
	 * key we should be using.  We can then fetch the key, get the secret
	 * and set up the crypto to extract the token.
	 */
	if (skb_copy_bits(skb, token_offset, &container, sizeof(container)) < 0)
		return rxrpc_abort_conn(conn, skb, RXGK_PACKETSHORT, -EPROTO,
					rxgk_abort_resp_tok_short);
		goto short_packet;

	kvno		= ntohl(container.kvno);
	enctype		= ntohl(container.enctype);
	ticket_len	= ntohl(container.token_len);
	ticket_offset	= token_offset + sizeof(container);

	if (xdr_round_up(ticket_len) > token_len - 3 * 4)
		return rxrpc_abort_conn(conn, skb, RXGK_PACKETSHORT, -EPROTO,
					rxgk_abort_resp_tok_short);
	if (xdr_round_up(ticket_len) > token_len - sizeof(container))
		goto short_packet;

	_debug("KVNO %u", kvno);
	_debug("ENC  %u", enctype);
@@ -285,4 +290,8 @@ int rxgk_extract_token(struct rxrpc_connection *conn, struct sk_buff *skb,
	 * also come out this way if the ticket decryption fails.
	 */
	return ret;

short_packet:
	return rxrpc_abort_conn(conn, skb, RXGK_PACKETSHORT, -EPROTO,
				rxgk_abort_resp_tok_short);
}