mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/3] AF_RXRPC fixes [ver #3]
@ 2014-03-06 23:18 David Howells
  2014-03-06 23:18 ` [PATCH 1/3] af_rxrpc: Remove incorrect checksum calculation from rxrpc_recvmsg() " David Howells
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: David Howells @ 2014-03-06 23:18 UTC (permalink / raw)
  To: netdev; +Cc: dhowells, tim, linux-afs, linux-kernel


Hi Dave,

Here are some AF_RXRPC fixes:

 (1) Fix to remove incorrect checksum calculation made during recvmsg().  It's
     unnecessary to try to do this there since we check the checksum before
     reading the RxRPC header from the packet.

 (2) Fix to prevent the sending of an ABORT packet in response to another
     ABORT packet and inducing a storm.

 (3) Fix UDP MTU calculation from parsing ICMP_FRAG_NEEDED packets where we
     don't handle the ICMP packet not specifying an MTU size.

---
The above changes since commit c88507fbad8055297c1d1e21e599f46960cbee39:

  ipv6: don't set DST_NOCOUNT for remotely added routes (2014-03-06 17:29:27 -0500)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git tags/rxrpc-fixes-20140306

for you to fetch changes up to ddc348e1c88d705b70f8aba0c42876100277c829:

  af_rxrpc: Fix UDP MTU calculation from ICMP_FRAG_NEEDED (2014-03-06 23:01:50 +0000)

David
---
David Howells (1):
      af_rxrpc: Fix UDP MTU calculation from ICMP_FRAG_NEEDED

Tim Smith (2):
      af_rxrpc: Remove incorrect checksum calculation from rxrpc_recvmsg()
      af_rxrpc: Prevent RxRPC peers from ABORT-storming one another


 net/rxrpc/ar-error.c   |    1 +
 net/rxrpc/ar-input.c   |   12 ++++++++----
 net/rxrpc/ar-recvmsg.c |   25 +------------------------
 3 files changed, 10 insertions(+), 28 deletions(-)


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/3] af_rxrpc: Remove incorrect checksum calculation from rxrpc_recvmsg() [ver #3]
  2014-03-06 23:18 [PATCH 0/3] AF_RXRPC fixes [ver #3] David Howells
@ 2014-03-06 23:18 ` David Howells
  2014-03-06 23:18 ` [PATCH 2/3] af_rxrpc: Prevent RxRPC peers from ABORT-storming one another " David Howells
  2014-03-06 23:18 ` [PATCH 3/3] af_rxrpc: Fix UDP MTU calculation from ICMP_FRAG_NEEDED " David Howells
  2 siblings, 0 replies; 4+ messages in thread
From: David Howells @ 2014-03-06 23:18 UTC (permalink / raw)
  To: netdev; +Cc: dhowells, tim, linux-afs, linux-kernel

From: Tim Smith <tim@electronghost.co.uk>

The UDP checksum was already verified in rxrpc_data_ready() - which calls
skb_checksum_complete() - as the RxRPC packet header contains no checksum of
its own.  Subsequent calls to skb_copy_and_csum_datagram_iovec() are thus
redundant and are, in any case, being passed only a subset of the UDP payload -
so the checksum will always fail if that path is taken.

So there is no need to check skb->ip_summed in rxrpc_recvmsg(), and no need for
the csum_copy_error: exit path.

Signed-off-by: Tim Smith <tim@electronghost.co.uk>
Signed-off-by: David Howells <dhowells@redhat.com>
---

 net/rxrpc/ar-recvmsg.c |   25 +------------------------
 1 file changed, 1 insertion(+), 24 deletions(-)

diff --git a/net/rxrpc/ar-recvmsg.c b/net/rxrpc/ar-recvmsg.c
index 34b5490dde65..e9aaa65c0778 100644
--- a/net/rxrpc/ar-recvmsg.c
+++ b/net/rxrpc/ar-recvmsg.c
@@ -180,16 +180,7 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock,
 		if (copy > len - copied)
 			copy = len - copied;
 
-		if (skb->ip_summed == CHECKSUM_UNNECESSARY ||
-		    skb->ip_summed == CHECKSUM_PARTIAL) {
-			ret = skb_copy_datagram_iovec(skb, offset,
-						      msg->msg_iov, copy);
-		} else {
-			ret = skb_copy_and_csum_datagram_iovec(skb, offset,
-							       msg->msg_iov);
-			if (ret == -EINVAL)
-				goto csum_copy_error;
-		}
+		ret = skb_copy_datagram_iovec(skb, offset, msg->msg_iov, copy);
 
 		if (ret < 0)
 			goto copy_error;
@@ -348,20 +339,6 @@ copy_error:
 	_leave(" = %d", ret);
 	return ret;
 
-csum_copy_error:
-	_debug("csum error");
-	release_sock(&rx->sk);
-	if (continue_call)
-		rxrpc_put_call(continue_call);
-	rxrpc_kill_skb(skb);
-	if (!(flags & MSG_PEEK)) {
-		if (skb_dequeue(&rx->sk.sk_receive_queue) != skb)
-			BUG();
-	}
-	skb_kill_datagram(&rx->sk, skb, flags);
-	rxrpc_put_call(call);
-	return -EAGAIN;
-
 wait_interrupted:
 	ret = sock_intr_errno(timeo);
 wait_error:


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 2/3] af_rxrpc: Prevent RxRPC peers from ABORT-storming one another [ver #3]
  2014-03-06 23:18 [PATCH 0/3] AF_RXRPC fixes [ver #3] David Howells
  2014-03-06 23:18 ` [PATCH 1/3] af_rxrpc: Remove incorrect checksum calculation from rxrpc_recvmsg() " David Howells
@ 2014-03-06 23:18 ` David Howells
  2014-03-06 23:18 ` [PATCH 3/3] af_rxrpc: Fix UDP MTU calculation from ICMP_FRAG_NEEDED " David Howells
  2 siblings, 0 replies; 4+ messages in thread
From: David Howells @ 2014-03-06 23:18 UTC (permalink / raw)
  To: netdev; +Cc: dhowells, tim, linux-afs, linux-kernel

From: Tim Smith <tim@electronghost.co.uk>

When an ABORT is sent, aborting a connection, the sender quite reasonably
forgets about the connection.  If another frame is received, another ABORT
will be sent.  When the receiver gets it, it no longer applies to an extant
connection, so an ABORT is sent, and so on...

Prevent this by never sending a rejection for an ABORT packet.

Signed-off-by: Tim Smith <tim@electronghost.co.uk>
Signed-off-by: David Howells <dhowells@redhat.com>
---

 net/rxrpc/ar-input.c |   12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/net/rxrpc/ar-input.c b/net/rxrpc/ar-input.c
index 529572f18d1f..eb7e16276cc1 100644
--- a/net/rxrpc/ar-input.c
+++ b/net/rxrpc/ar-input.c
@@ -606,8 +606,10 @@ dead_call:
 	}
 
 	_debug("dead call");
-	skb->priority = RX_CALL_DEAD;
-	rxrpc_reject_packet(conn->trans->local, skb);
+	if (sp->hdr.type != RXRPC_PACKET_TYPE_ABORT) {
+		skb->priority = RX_CALL_DEAD;
+		rxrpc_reject_packet(conn->trans->local, skb);
+	}
 	goto done;
 
 	/* resend last packet of a completed call
@@ -790,8 +792,10 @@ cant_route_call:
 		skb->priority = RX_CALL_DEAD;
 	}
 
-	_debug("reject");
-	rxrpc_reject_packet(local, skb);
+	if (sp->hdr.type != RXRPC_PACKET_TYPE_ABORT) {
+		_debug("reject type %d",sp->hdr.type);
+		rxrpc_reject_packet(local, skb);
+	}
 	rxrpc_put_local(local);
 	_leave(" [no call]");
 	return;


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 3/3] af_rxrpc: Fix UDP MTU calculation from ICMP_FRAG_NEEDED [ver #3]
  2014-03-06 23:18 [PATCH 0/3] AF_RXRPC fixes [ver #3] David Howells
  2014-03-06 23:18 ` [PATCH 1/3] af_rxrpc: Remove incorrect checksum calculation from rxrpc_recvmsg() " David Howells
  2014-03-06 23:18 ` [PATCH 2/3] af_rxrpc: Prevent RxRPC peers from ABORT-storming one another " David Howells
@ 2014-03-06 23:18 ` David Howells
  2 siblings, 0 replies; 4+ messages in thread
From: David Howells @ 2014-03-06 23:18 UTC (permalink / raw)
  To: netdev; +Cc: dhowells, tim, linux-afs, linux-kernel

AF_RXRPC sends UDP packets with the "Don't Fragment" bit set in an attempt to
determine the maximum packet size between the local socket and the peer by
invoking the generation of ICMP_FRAG_NEEDED packets.

Once a packet is sent with the "Don't Fragment" bit set, it is then
inconvenient to break it up as that requires recalculating all the rxrpc serial
and sequence numbers and reencrypting all the fragments, so we switch off the
"Don't Fragment" service temporarily and send the bounced packet again.  Future
packets then use the new MTU.

That's all fine.  The problem lies in rxrpc_UDP_error_report() where the code
that deals with ICMP_FRAG_NEEDED packets lives.  Packets of this type have a
field (ee_info) to indicate the maximum packet size at the reporting node - but
sometimes ee_info isn't filled in and is just left as 0 and the code must allow
for this.

When ee_info is 0, the code should take the MTU size we're currently using and
reduce it for the next packet we want to send.  However, it takes ee_info
(which is known to be 0) and tries to reduce that instead.

This was discovered by Coverity.

Reported-by: Dave Jones <davej@redhat.com>
Signed-off-by: David Howells <dhowells@redhat.com>
---

 net/rxrpc/ar-error.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/net/rxrpc/ar-error.c b/net/rxrpc/ar-error.c
index a9206087b4d7..db57458c824c 100644
--- a/net/rxrpc/ar-error.c
+++ b/net/rxrpc/ar-error.c
@@ -83,6 +83,7 @@ void rxrpc_UDP_error_report(struct sock *sk)
 
 		if (mtu == 0) {
 			/* they didn't give us a size, estimate one */
+			mtu = peer->if_mtu;
 			if (mtu > 1500) {
 				mtu >>= 1;
 				if (mtu < 1500)


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2014-03-06 23:19 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-06 23:18 [PATCH 0/3] AF_RXRPC fixes [ver #3] David Howells
2014-03-06 23:18 ` [PATCH 1/3] af_rxrpc: Remove incorrect checksum calculation from rxrpc_recvmsg() " David Howells
2014-03-06 23:18 ` [PATCH 2/3] af_rxrpc: Prevent RxRPC peers from ABORT-storming one another " David Howells
2014-03-06 23:18 ` [PATCH 3/3] af_rxrpc: Fix UDP MTU calculation from ICMP_FRAG_NEEDED " David Howells

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®