Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 34f0516b authored by David Howells's avatar David Howells Committed by Greg Kroah-Hartman
Browse files

rxrpc: Don't treat call aborts as conn aborts



[ Upstream commit 57b0c9d49b94bbeb53649b7fbd264603c1ebd585 ]

If a call-level abort is received for the previous call to complete on a
connection channel, then that abort is queued for the connection processor
to handle.  Unfortunately, the connection processor then assumes without
checking that the abort is connection-level (ie. callNumber is 0) and
distributes it over all active calls on that connection, thereby
incorrectly aborting them.

Fix this by discarding aborts aimed at a completed call.

Further, discard all packets aimed at a call that's complete if there's
currently an active call on a channel, since the DATA packets associated
with the new call automatically terminate the old call.

Fixes: 18bfeba5 ("rxrpc: Perform terminal call ACK/ABORT retransmission from conn processor")
Reported-by: default avatarMarc Dionne <marc.dionne@auristor.com>
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
Signed-off-by: default avatarSasha Levin <alexander.levin@microsoft.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 9b7c95ac
Loading
Loading
Loading
Loading
+9 −6
Original line number Diff line number Diff line
@@ -1166,16 +1166,19 @@ void rxrpc_data_ready(struct sock *udp_sk)
			goto discard_unlock;

		if (sp->hdr.callNumber == chan->last_call) {
			/* For the previous service call, if completed successfully, we
			 * discard all further packets.
			if (chan->call ||
			    sp->hdr.type == RXRPC_PACKET_TYPE_ABORT)
				goto discard_unlock;

			/* For the previous service call, if completed
			 * successfully, we discard all further packets.
			 */
			if (rxrpc_conn_is_service(conn) &&
			    (chan->last_type == RXRPC_PACKET_TYPE_ACK ||
			     sp->hdr.type == RXRPC_PACKET_TYPE_ABORT))
			    chan->last_type == RXRPC_PACKET_TYPE_ACK)
				goto discard_unlock;

			/* But otherwise we need to retransmit the final packet from
			 * data cached in the connection record.
			/* But otherwise we need to retransmit the final packet
			 * from data cached in the connection record.
			 */
			rxrpc_post_packet_to_conn(conn, skb);
			goto out_unlock;