* [PATCH net 0/2] udp: add missing check on edumx rx path
@ 2018-09-13 14:27 Paolo Abeni
2018-09-13 14:27 ` [PATCH net 1/2] udp4: fix IP_CMSG_CHECKSUM for connected sockets Paolo Abeni
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Paolo Abeni @ 2018-09-13 14:27 UTC (permalink / raw)
To: netdev; +Cc: David S. Miller, Tom Herbert
The early demux RX path for the UDP protocol is currently missing
some checks. Both ipv4 and ipv6 implementations lack checksum conversion
and the ipv6 implementation additionally lack the zero checksum
validation.
The first patch takes care of UDPv4 and the second one of UDPv6
Paolo Abeni (2):
udp4: fix IP_CMSG_CHECKSUM for connected sockets
udp6: add missing checks on edumux packet processing
net/ipv4/udp.c | 49 +++++++++++++++++++------------------
net/ipv6/udp.c | 65 ++++++++++++++++++++++++++++----------------------
2 files changed, 63 insertions(+), 51 deletions(-)
--
2.17.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH net 1/2] udp4: fix IP_CMSG_CHECKSUM for connected sockets
2018-09-13 14:27 [PATCH net 0/2] udp: add missing check on edumx rx path Paolo Abeni
@ 2018-09-13 14:27 ` Paolo Abeni
2018-09-13 14:27 ` [PATCH net 2/2] udp6: add missing checks on edumux packet processing Paolo Abeni
2018-09-16 22:28 ` [PATCH net 0/2] udp: add missing check on edumx rx path David Miller
2 siblings, 0 replies; 4+ messages in thread
From: Paolo Abeni @ 2018-09-13 14:27 UTC (permalink / raw)
To: netdev; +Cc: David S. Miller, Tom Herbert
commit 2abb7cdc0dc8 ("udp: Add support for doing checksum
unnecessary conversion") left out the early demux path for
connected sockets. As a result IP_CMSG_CHECKSUM gives wrong
values for such socket when GRO is not enabled/available.
This change addresses the issue by moving the csum conversion to a
common helper and using such helper in both the default and the
early demux rx path.
Fixes: 2abb7cdc0dc8 ("udp: Add support for doing checksum unnecessary conversion")
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
net/ipv4/udp.c | 49 ++++++++++++++++++++++++++-----------------------
1 file changed, 26 insertions(+), 23 deletions(-)
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index f4e35b2ff8b8..7d69dd6fa7e8 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -2124,6 +2124,28 @@ static inline int udp4_csum_init(struct sk_buff *skb, struct udphdr *uh,
inet_compute_pseudo);
}
+/* wrapper for udp_queue_rcv_skb tacking care of csum conversion and
+ * return code conversion for ip layer consumption
+ */
+static int udp_unicast_rcv_skb(struct sock *sk, struct sk_buff *skb,
+ struct udphdr *uh)
+{
+ int ret;
+
+ if (inet_get_convert_csum(sk) && uh->check && !IS_UDPLITE(sk))
+ skb_checksum_try_convert(skb, IPPROTO_UDP, uh->check,
+ inet_compute_pseudo);
+
+ ret = udp_queue_rcv_skb(sk, skb);
+
+ /* a return value > 0 means to resubmit the input, but
+ * it wants the return to be -protocol, or 0
+ */
+ if (ret > 0)
+ return -ret;
+ return 0;
+}
+
/*
* All we need to do is get the socket, and then do a checksum.
*/
@@ -2170,14 +2192,9 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
if (unlikely(sk->sk_rx_dst != dst))
udp_sk_rx_dst_set(sk, dst);
- ret = udp_queue_rcv_skb(sk, skb);
+ ret = udp_unicast_rcv_skb(sk, skb, uh);
sock_put(sk);
- /* a return value > 0 means to resubmit the input, but
- * it wants the return to be -protocol, or 0
- */
- if (ret > 0)
- return -ret;
- return 0;
+ return ret;
}
if (rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST))
@@ -2185,22 +2202,8 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
saddr, daddr, udptable, proto);
sk = __udp4_lib_lookup_skb(skb, uh->source, uh->dest, udptable);
- if (sk) {
- int ret;
-
- if (inet_get_convert_csum(sk) && uh->check && !IS_UDPLITE(sk))
- skb_checksum_try_convert(skb, IPPROTO_UDP, uh->check,
- inet_compute_pseudo);
-
- ret = udp_queue_rcv_skb(sk, skb);
-
- /* a return value > 0 means to resubmit the input, but
- * it wants the return to be -protocol, or 0
- */
- if (ret > 0)
- return -ret;
- return 0;
- }
+ if (sk)
+ return udp_unicast_rcv_skb(sk, skb, uh);
if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
goto drop;
--
2.17.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH net 2/2] udp6: add missing checks on edumux packet processing
2018-09-13 14:27 [PATCH net 0/2] udp: add missing check on edumx rx path Paolo Abeni
2018-09-13 14:27 ` [PATCH net 1/2] udp4: fix IP_CMSG_CHECKSUM for connected sockets Paolo Abeni
@ 2018-09-13 14:27 ` Paolo Abeni
2018-09-16 22:28 ` [PATCH net 0/2] udp: add missing check on edumx rx path David Miller
2 siblings, 0 replies; 4+ messages in thread
From: Paolo Abeni @ 2018-09-13 14:27 UTC (permalink / raw)
To: netdev; +Cc: David S. Miller, Tom Herbert
Currently the UDPv6 early demux rx code path lacks some mandatory
checks, already implemented into the normal RX code path - namely
the checksum conversion and no_check6_rx check.
Similar to the previous commit, we move the common processing to
an UDPv6 specific helper and call it from both edemux code path
and normal code path. In respect to the UDPv4, we need to add an
explicit check for non zero csum according to no_check6_rx value.
Reported-by: Jianlin Shi <jishi@redhat.com>
Suggested-by: Xin Long <lucien.xin@gmail.com>
Fixes: c9f2c1ae123a ("udp6: fix socket leak on early demux")
Fixes: 2abb7cdc0dc8 ("udp: Add support for doing checksum unnecessary conversion")
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
net/ipv6/udp.c | 65 ++++++++++++++++++++++++++++----------------------
1 file changed, 37 insertions(+), 28 deletions(-)
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 83f4c77c79d8..28c4aa5078fc 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -752,6 +752,28 @@ static void udp6_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst)
}
}
+/* wrapper for udp_queue_rcv_skb tacking care of csum conversion and
+ * return code conversion for ip layer consumption
+ */
+static int udp6_unicast_rcv_skb(struct sock *sk, struct sk_buff *skb,
+ struct udphdr *uh)
+{
+ int ret;
+
+ if (inet_get_convert_csum(sk) && uh->check && !IS_UDPLITE(sk))
+ skb_checksum_try_convert(skb, IPPROTO_UDP, uh->check,
+ ip6_compute_pseudo);
+
+ ret = udpv6_queue_rcv_skb(sk, skb);
+
+ /* a return value > 0 means to resubmit the input, but
+ * it wants the return to be -protocol, or 0
+ */
+ if (ret > 0)
+ return -ret;
+ return 0;
+}
+
int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
int proto)
{
@@ -803,13 +825,14 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
if (unlikely(sk->sk_rx_dst != dst))
udp6_sk_rx_dst_set(sk, dst);
- ret = udpv6_queue_rcv_skb(sk, skb);
- sock_put(sk);
+ if (!uh->check && !udp_sk(sk)->no_check6_rx) {
+ sock_put(sk);
+ goto report_csum_error;
+ }
- /* a return value > 0 means to resubmit the input */
- if (ret > 0)
- return ret;
- return 0;
+ ret = udp6_unicast_rcv_skb(sk, skb, uh);
+ sock_put(sk);
+ return ret;
}
/*
@@ -822,30 +845,13 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
/* Unicast */
sk = __udp6_lib_lookup_skb(skb, uh->source, uh->dest, udptable);
if (sk) {
- int ret;
-
- if (!uh->check && !udp_sk(sk)->no_check6_rx) {
- udp6_csum_zero_error(skb);
- goto csum_error;
- }
-
- if (inet_get_convert_csum(sk) && uh->check && !IS_UDPLITE(sk))
- skb_checksum_try_convert(skb, IPPROTO_UDP, uh->check,
- ip6_compute_pseudo);
-
- ret = udpv6_queue_rcv_skb(sk, skb);
-
- /* a return value > 0 means to resubmit the input */
- if (ret > 0)
- return ret;
-
- return 0;
+ if (!uh->check && !udp_sk(sk)->no_check6_rx)
+ goto report_csum_error;
+ return udp6_unicast_rcv_skb(sk, skb, uh);
}
- if (!uh->check) {
- udp6_csum_zero_error(skb);
- goto csum_error;
- }
+ if (!uh->check)
+ goto report_csum_error;
if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
goto discard;
@@ -866,6 +872,9 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
ulen, skb->len,
daddr, ntohs(uh->dest));
goto discard;
+
+report_csum_error:
+ udp6_csum_zero_error(skb);
csum_error:
__UDP6_INC_STATS(net, UDP_MIB_CSUMERRORS, proto == IPPROTO_UDPLITE);
discard:
--
2.17.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH net 0/2] udp: add missing check on edumx rx path
2018-09-13 14:27 [PATCH net 0/2] udp: add missing check on edumx rx path Paolo Abeni
2018-09-13 14:27 ` [PATCH net 1/2] udp4: fix IP_CMSG_CHECKSUM for connected sockets Paolo Abeni
2018-09-13 14:27 ` [PATCH net 2/2] udp6: add missing checks on edumux packet processing Paolo Abeni
@ 2018-09-16 22:28 ` David Miller
2 siblings, 0 replies; 4+ messages in thread
From: David Miller @ 2018-09-16 22:28 UTC (permalink / raw)
To: pabeni; +Cc: netdev, tom
From: Paolo Abeni <pabeni@redhat.com>
Date: Thu, 13 Sep 2018 16:27:19 +0200
> The early demux RX path for the UDP protocol is currently missing
> some checks. Both ipv4 and ipv6 implementations lack checksum conversion
> and the ipv6 implementation additionally lack the zero checksum
> validation.
>
> The first patch takes care of UDPv4 and the second one of UDPv6
Series applied and queued up for -stable.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2018-09-17 3:53 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-09-13 14:27 [PATCH net 0/2] udp: add missing check on edumx rx path Paolo Abeni
2018-09-13 14:27 ` [PATCH net 1/2] udp4: fix IP_CMSG_CHECKSUM for connected sockets Paolo Abeni
2018-09-13 14:27 ` [PATCH net 2/2] udp6: add missing checks on edumux packet processing Paolo Abeni
2018-09-16 22:28 ` [PATCH net 0/2] udp: add missing check on edumx rx path David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).