diff options
author | David Howells <dhowells@redhat.com> | 2018-03-30 21:04:44 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-05-30 07:50:42 +0200 |
commit | 34f0516b709826c9210ad7e662a47fbef32ce3a1 (patch) | |
tree | b5c22405d4b0c127a5a36bc24840eac3520b8bb1 /net | |
parent | 9b7c95ac2e0272b34b26ecc3a6bd9163e92e33c2 (diff) |
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: 18bfeba50dfd ("rxrpc: Perform terminal call ACK/ABORT retransmission from conn processor")
Reported-by: Marc Dionne <marc.dionne@auristor.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net')
-rw-r--r-- | net/rxrpc/input.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c index 1060d14d4e6a..f3ac85a285a2 100644 --- a/net/rxrpc/input.c +++ b/net/rxrpc/input.c @@ -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; |