| From foo@baz Sun May 27 17:33:38 CEST 2018 |
| From: David Howells <dhowells@redhat.com> |
| Date: Fri, 30 Mar 2018 21:04:44 +0100 |
| Subject: rxrpc: Don't treat call aborts as conn aborts |
| |
| From: David Howells <dhowells@redhat.com> |
| |
| [ 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> |
| --- |
| net/rxrpc/input.c | 15 +++++++++------ |
| 1 file changed, 9 insertions(+), 6 deletions(-) |
| |
| --- a/net/rxrpc/input.c |
| +++ b/net/rxrpc/input.c |
| @@ -1166,16 +1166,19 @@ void rxrpc_data_ready(struct sock *udp_s |
| 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; |