From f095fec9a8e21c24ebdc61341bed46d469bd1384 Mon Sep 17 00:00:00 2001 From: Andreas Wellving Date: Wed, 10 Jul 2019 11:20:38 +0200 Subject: tcp: CVE-2019-11478 tcp: tcp_fragment() should apply sane memory limits tcp: refine memory limit test in tcp_fragment() References: https://nvd.nist.gov/vuln/detail/CVE-2019-11478 https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=linux-4.9.y&id=e358f4af19db46ca25cc9a8a78412b09ba98859d https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=linux-4.9.y&id=caa51edc7e9606418611e68de624efbd0042adf5 Change-Id: Ie16affeda488857ce013ce3be578c05619aee446 Signed-off-by: Andreas Wellving --- patches/cve/4.9.x.scc | 2 + ...-refine-memory-limit-test-in-tcp_fragment.patch | 45 +++++++++++ ..._fragment-should-apply-sane-memory-limits.patch | 86 ++++++++++++++++++++++ 3 files changed, 133 insertions(+) create mode 100644 patches/cve/CVE-2019-11478-tcp-refine-memory-limit-test-in-tcp_fragment.patch create mode 100644 patches/cve/CVE-2019-11478-tcp-tcp_fragment-should-apply-sane-memory-limits.patch diff --git a/patches/cve/4.9.x.scc b/patches/cve/4.9.x.scc index e3a9067..ad03493 100644 --- a/patches/cve/4.9.x.scc +++ b/patches/cve/4.9.x.scc @@ -46,3 +46,5 @@ patch CVE-2018-20836-scsi-libsas-fix-a-race-condition-when-smp-task-timeo.patch #CVEs fixed in 4.9.182: patch CVE-2019-11477-tcp-limit-payload-size-of-sacked-skbs.patch +patch CVE-2019-11478-tcp-tcp_fragment-should-apply-sane-memory-limits.patch +patch CVE-2019-11478-tcp-refine-memory-limit-test-in-tcp_fragment.patch diff --git a/patches/cve/CVE-2019-11478-tcp-refine-memory-limit-test-in-tcp_fragment.patch b/patches/cve/CVE-2019-11478-tcp-refine-memory-limit-test-in-tcp_fragment.patch new file mode 100644 index 0000000..57bca2c --- /dev/null +++ b/patches/cve/CVE-2019-11478-tcp-refine-memory-limit-test-in-tcp_fragment.patch @@ -0,0 +1,45 @@ +From caa51edc7e9606418611e68de624efbd0042adf5 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Fri, 21 Jun 2019 06:09:55 -0700 +Subject: [PATCH] tcp: refine memory limit test in tcp_fragment() + +commit b6653b3629e5b88202be3c9abc44713973f5c4b4 upstream. + +tcp_fragment() might be called for skbs in the write queue. + +Memory limits might have been exceeded because tcp_sendmsg() only +checks limits at full skb (64KB) boundaries. + +Therefore, we need to make sure tcp_fragment() wont punish applications +that might have setup very low SO_SNDBUF values. + +CVE: CVE-2019-11478 +Upstream-Status: Backport [https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=linux-4.9.y&id=caa51edc7e9606418611e68de624efbd0042adf5] + +Fixes: f070ef2ac667 ("tcp: tcp_fragment() should apply sane memory limits") +Signed-off-by: Eric Dumazet +Reported-by: Christoph Paasch +Tested-by: Christoph Paasch +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Andreas Wellving +--- + net/ipv4/tcp_output.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c +index d8c6b833f0ce..0c195b0f4216 100644 +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -1185,7 +1185,7 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, + if (nsize < 0) + nsize = 0; + +- if (unlikely((sk->sk_wmem_queued >> 1) > sk->sk_sndbuf)) { ++ if (unlikely((sk->sk_wmem_queued >> 1) > sk->sk_sndbuf + 0x20000)) { + NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPWQUEUETOOBIG); + return -ENOMEM; + } +-- +2.20.1 + diff --git a/patches/cve/CVE-2019-11478-tcp-tcp_fragment-should-apply-sane-memory-limits.patch b/patches/cve/CVE-2019-11478-tcp-tcp_fragment-should-apply-sane-memory-limits.patch new file mode 100644 index 0000000..7d0c4f4 --- /dev/null +++ b/patches/cve/CVE-2019-11478-tcp-tcp_fragment-should-apply-sane-memory-limits.patch @@ -0,0 +1,86 @@ +From e358f4af19db46ca25cc9a8a78412b09ba98859d Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Sat, 15 Jun 2019 17:40:56 -0700 +Subject: [PATCH] tcp: tcp_fragment() should apply sane memory limits + +commit f070ef2ac66716357066b683fb0baf55f8191a2e upstream. + +Jonathan Looney reported that a malicious peer can force a sender +to fragment its retransmit queue into tiny skbs, inflating memory +usage and/or overflow 32bit counters. + +TCP allows an application to queue up to sk_sndbuf bytes, +so we need to give some allowance for non malicious splitting +of retransmit queue. + +A new SNMP counter is added to monitor how many times TCP +did not allow to split an skb if the allowance was exceeded. + +Note that this counter might increase in the case applications +use SO_SNDBUF socket option to lower sk_sndbuf. + +CVE-2019-11478 : tcp_fragment, prevent fragmenting a packet when the + socket is already using more than half the allowed space + +CVE: CVE-2019-11478 +Upstream-Status: Backport [https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=linux-4.9.y&id=e358f4af19db46ca25cc9a8a78412b09ba98859d] + +Signed-off-by: Eric Dumazet +Reported-by: Jonathan Looney +Acked-by: Neal Cardwell +Acked-by: Yuchung Cheng +Reviewed-by: Tyler Hicks +Cc: Bruce Curtis +Cc: Jonathan Lemon +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Andreas Wellving +--- + include/uapi/linux/snmp.h | 1 + + net/ipv4/proc.c | 1 + + net/ipv4/tcp_output.c | 5 +++++ + 3 files changed, 7 insertions(+) + +diff --git a/include/uapi/linux/snmp.h b/include/uapi/linux/snmp.h +index 3442a26d36d9..56e3460d1f9f 100644 +--- a/include/uapi/linux/snmp.h ++++ b/include/uapi/linux/snmp.h +@@ -282,6 +282,7 @@ enum + LINUX_MIB_TCPKEEPALIVE, /* TCPKeepAlive */ + LINUX_MIB_TCPMTUPFAIL, /* TCPMTUPFail */ + LINUX_MIB_TCPMTUPSUCCESS, /* TCPMTUPSuccess */ ++ LINUX_MIB_TCPWQUEUETOOBIG, /* TCPWqueueTooBig */ + __LINUX_MIB_MAX + }; + +diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c +index ec48d8eafc7e..8b221398534b 100644 +--- a/net/ipv4/proc.c ++++ b/net/ipv4/proc.c +@@ -306,6 +306,7 @@ static const struct snmp_mib snmp4_net_list[] = { + SNMP_MIB_ITEM("TCPKeepAlive", LINUX_MIB_TCPKEEPALIVE), + SNMP_MIB_ITEM("TCPMTUPFail", LINUX_MIB_TCPMTUPFAIL), + SNMP_MIB_ITEM("TCPMTUPSuccess", LINUX_MIB_TCPMTUPSUCCESS), ++ SNMP_MIB_ITEM("TCPWqueueTooBig", LINUX_MIB_TCPWQUEUETOOBIG), + SNMP_MIB_SENTINEL + }; + +diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c +index 2f166662682e..123b2d8fde46 100644 +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -1185,6 +1185,11 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, + if (nsize < 0) + nsize = 0; + ++ if (unlikely((sk->sk_wmem_queued >> 1) > sk->sk_sndbuf)) { ++ NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPWQUEUETOOBIG); ++ return -ENOMEM; ++ } ++ + if (skb_unclone(skb, gfp)) + return -ENOMEM; + +-- +2.20.1 + -- cgit v1.2.3-54-g00ecf