From 61fce63f759be681a07490fa52de76f329ac196d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 11 Apr 2014 08:48:46 -0700 Subject: [PATCH] 3.10-stable patches added patches: bridge-multicast-add-sanity-check-for-query-source-addresses.patch inet-frag-make-sure-forced-eviction-removes-all-frags.patch ip6mr-fix-mfc-notification-flags.patch ipmr-fix-mfc-notification-flags.patch ipv6-avoid-unnecessary-temporary-addresses-being-generated.patch ipv6-don-t-set-dst_nocount-for-remotely-added-routes.patch ipv6-fix-exthdrs-offload-registration.patch ipv6-ip6_append_data_mtu-do-not-handle-the-mtu-of-the-second-fragment-properly.patch ipv6-some-ipv6-statistic-counters-failed-to-disable-bh.patch isdnloop-several-buffer-overflows.patch isdnloop-validate-nul-terminated-strings-from-user.patch net-fix-for-a-race-condition-in-the-inet-frag-code.patch netlink-don-t-compare-the-nul-termination-in-nla_strcmp.patch netpoll-fix-the-skb-check-in-pkt_is_ns.patch net-sctp-fix-skb-leakage-in-cookie-echo-path-of-chunk-auth_chunk.patch net-socket-error-on-a-negative-msg_namelen.patch net-unix-non-blocking-recvmsg-should-not-return-eintr.patch rds-prevent-dereference-of-a-null-device-in-rds_iw_laddr_check.patch rtnetlink-fix-fdb-notification-flags.patch tcp-tcp_release_cb-should-release-socket-ownership.patch tg3-do-not-include-vlan-acceleration-features-in-vlan_features.patch usbnet-include-wait-queue-head-in-device-structure.patch vhost-fix-total-length-when-packets-are-too-short.patch vhost-validate-vhost_get_vq_desc-return-value.patch vlan-set-correct-source-mac-address-with-tx-vlan-offload-enabled.patch vlan-set-hard_header_len-according-to-available-acceleration.patch vxlan-fix-potential-null-dereference-in-arp_reduce.patch xen-netback-remove-pointless-clause-from-if-statement.patch --- ...ity-check-for-query-source-addresses.patch | 48 ++++++ ...re-forced-eviction-removes-all-frags.patch | 57 +++++++ .../ip6mr-fix-mfc-notification-flags.patch | 73 +++++++++ .../ipmr-fix-mfc-notification-flags.patch | 73 +++++++++ ...-temporary-addresses-being-generated.patch | 41 +++++ ...st_nocount-for-remotely-added-routes.patch | 33 ++++ ...pv6-fix-exthdrs-offload-registration.patch | 42 ++++++ ...-mtu-of-the-second-fragment-properly.patch | 96 ++++++++++++ ...tistic-counters-failed-to-disable-bh.patch | 80 ++++++++++ .../isdnloop-several-buffer-overflows.patch | 95 ++++++++++++ ...ate-nul-terminated-strings-from-user.patch | 34 +++++ ...race-condition-in-the-inet-frag-code.patch | 94 ++++++++++++ ...cookie-echo-path-of-chunk-auth_chunk.patch | 120 +++++++++++++++ ...cket-error-on-a-negative-msg_namelen.patch | 35 +++++ ...king-recvmsg-should-not-return-eintr.patch | 73 +++++++++ ...re-the-nul-termination-in-nla_strcmp.patch | 55 +++++++ ...tpoll-fix-the-skb-check-in-pkt_is_ns.patch | 31 ++++ ...-a-null-device-in-rds_iw_laddr_check.patch | 31 ++++ ...rtnetlink-fix-fdb-notification-flags.patch | 62 ++++++++ queue-3.10/series | 28 ++++ ...e_cb-should-release-socket-ownership.patch | 122 +++++++++++++++ ...celeration-features-in-vlan_features.patch | 44 ++++++ ...-wait-queue-head-in-device-structure.patch | 142 ++++++++++++++++++ ...al-length-when-packets-are-too-short.patch | 63 ++++++++ ...idate-vhost_get_vq_desc-return-value.patch | 44 ++++++ ...address-with-tx-vlan-offload-enabled.patch | 41 +++++ ...-according-to-available-acceleration.patch | 52 +++++++ ...ntial-null-dereference-in-arp_reduce.patch | 33 ++++ ...e-pointless-clause-from-if-statement.patch | 39 +++++ 29 files changed, 1781 insertions(+) create mode 100644 queue-3.10/bridge-multicast-add-sanity-check-for-query-source-addresses.patch create mode 100644 queue-3.10/inet-frag-make-sure-forced-eviction-removes-all-frags.patch create mode 100644 queue-3.10/ip6mr-fix-mfc-notification-flags.patch create mode 100644 queue-3.10/ipmr-fix-mfc-notification-flags.patch create mode 100644 queue-3.10/ipv6-avoid-unnecessary-temporary-addresses-being-generated.patch create mode 100644 queue-3.10/ipv6-don-t-set-dst_nocount-for-remotely-added-routes.patch create mode 100644 queue-3.10/ipv6-fix-exthdrs-offload-registration.patch create mode 100644 queue-3.10/ipv6-ip6_append_data_mtu-do-not-handle-the-mtu-of-the-second-fragment-properly.patch create mode 100644 queue-3.10/ipv6-some-ipv6-statistic-counters-failed-to-disable-bh.patch create mode 100644 queue-3.10/isdnloop-several-buffer-overflows.patch create mode 100644 queue-3.10/isdnloop-validate-nul-terminated-strings-from-user.patch create mode 100644 queue-3.10/net-fix-for-a-race-condition-in-the-inet-frag-code.patch create mode 100644 queue-3.10/net-sctp-fix-skb-leakage-in-cookie-echo-path-of-chunk-auth_chunk.patch create mode 100644 queue-3.10/net-socket-error-on-a-negative-msg_namelen.patch create mode 100644 queue-3.10/net-unix-non-blocking-recvmsg-should-not-return-eintr.patch create mode 100644 queue-3.10/netlink-don-t-compare-the-nul-termination-in-nla_strcmp.patch create mode 100644 queue-3.10/netpoll-fix-the-skb-check-in-pkt_is_ns.patch create mode 100644 queue-3.10/rds-prevent-dereference-of-a-null-device-in-rds_iw_laddr_check.patch create mode 100644 queue-3.10/rtnetlink-fix-fdb-notification-flags.patch create mode 100644 queue-3.10/tcp-tcp_release_cb-should-release-socket-ownership.patch create mode 100644 queue-3.10/tg3-do-not-include-vlan-acceleration-features-in-vlan_features.patch create mode 100644 queue-3.10/usbnet-include-wait-queue-head-in-device-structure.patch create mode 100644 queue-3.10/vhost-fix-total-length-when-packets-are-too-short.patch create mode 100644 queue-3.10/vhost-validate-vhost_get_vq_desc-return-value.patch create mode 100644 queue-3.10/vlan-set-correct-source-mac-address-with-tx-vlan-offload-enabled.patch create mode 100644 queue-3.10/vlan-set-hard_header_len-according-to-available-acceleration.patch create mode 100644 queue-3.10/vxlan-fix-potential-null-dereference-in-arp_reduce.patch create mode 100644 queue-3.10/xen-netback-remove-pointless-clause-from-if-statement.patch diff --git a/queue-3.10/bridge-multicast-add-sanity-check-for-query-source-addresses.patch b/queue-3.10/bridge-multicast-add-sanity-check-for-query-source-addresses.patch new file mode 100644 index 00000000000..93a9b8ca98b --- /dev/null +++ b/queue-3.10/bridge-multicast-add-sanity-check-for-query-source-addresses.patch @@ -0,0 +1,48 @@ +From foo@baz Fri Apr 11 08:46:36 PDT 2014 +From: =?UTF-8?q?Linus=20L=C3=BCssing?= +Date: Tue, 4 Mar 2014 03:57:35 +0100 +Subject: bridge: multicast: add sanity check for query source addresses +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: =?UTF-8?q?Linus=20L=C3=BCssing?= + +[ Upstream commit 6565b9eeef194afbb3beec80d6dd2447f4091f8c ] + +MLD queries are supposed to have an IPv6 link-local source address +according to RFC2710, section 4 and RFC3810, section 5.1.14. This patch +adds a sanity check to ignore such broken MLD queries. + +Without this check, such malformed MLD queries can result in a +denial of service: The queries are ignored by any MLD listener +therefore they will not respond with an MLD report. However, +without this patch these malformed MLD queries would enable the +snooping part in the bridge code, potentially shutting down the +according ports towards these hosts for multicast traffic as the +bridge did not learn about these listeners. + +Reported-by: Jan Stancek +Signed-off-by: Linus Lüssing +Reviewed-by: Hannes Frederic Sowa +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/bridge/br_multicast.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/net/bridge/br_multicast.c ++++ b/net/bridge/br_multicast.c +@@ -1176,6 +1176,12 @@ static int br_ip6_multicast_query(struct + + br_multicast_query_received(br, port, !ipv6_addr_any(&ip6h->saddr)); + ++ /* RFC2710+RFC3810 (MLDv1+MLDv2) require link-local source addresses */ ++ if (!(ipv6_addr_type(&ip6h->saddr) & IPV6_ADDR_LINKLOCAL)) { ++ err = -EINVAL; ++ goto out; ++ } ++ + if (skb->len == sizeof(*mld)) { + if (!pskb_may_pull(skb, sizeof(*mld))) { + err = -EINVAL; diff --git a/queue-3.10/inet-frag-make-sure-forced-eviction-removes-all-frags.patch b/queue-3.10/inet-frag-make-sure-forced-eviction-removes-all-frags.patch new file mode 100644 index 00000000000..111861e79ad --- /dev/null +++ b/queue-3.10/inet-frag-make-sure-forced-eviction-removes-all-frags.patch @@ -0,0 +1,57 @@ +From foo@baz Fri Apr 11 08:46:36 PDT 2014 +From: Florian Westphal +Date: Thu, 6 Mar 2014 18:06:41 +0100 +Subject: inet: frag: make sure forced eviction removes all frags + +From: Florian Westphal + +[ Upstream commit e588e2f286ed7da011ed357c24c5b9a554e26595 ] + +Quoting Alexander Aring: + While fragmentation and unloading of 6lowpan module I got this kernel Oops + after few seconds: + + BUG: unable to handle kernel paging request at f88bbc30 + [..] + Modules linked in: ipv6 [last unloaded: 6lowpan] + Call Trace: + [] ? call_timer_fn+0x54/0xb3 + [] ? process_timeout+0xa/0xa + [] run_timer_softirq+0x140/0x15f + +Problem is that incomplete frags are still around after unload; when +their frag expire timer fires, we get crash. + +When a netns is removed (also done when unloading module), inet_frag +calls the evictor with 'force' argument to purge remaining frags. + +The evictor loop terminates when accounted memory ('work') drops to 0 +or the lru-list becomes empty. However, the mem accounting is done +via percpu counters and may not be accurate, i.e. loop may terminate +prematurely. + +Alter evictor to only stop once the lru list is empty when force is +requested. + +Reported-by: Phoebe Buckheister +Reported-by: Alexander Aring +Tested-by: Alexander Aring +Signed-off-by: Florian Westphal +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/inet_fragment.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/ipv4/inet_fragment.c ++++ b/net/ipv4/inet_fragment.c +@@ -211,7 +211,7 @@ int inet_frag_evictor(struct netns_frags + } + + work = frag_mem_limit(nf) - nf->low_thresh; +- while (work > 0) { ++ while (work > 0 || force) { + spin_lock(&nf->lru_lock); + + if (list_empty(&nf->lru_list)) { diff --git a/queue-3.10/ip6mr-fix-mfc-notification-flags.patch b/queue-3.10/ip6mr-fix-mfc-notification-flags.patch new file mode 100644 index 00000000000..079e5378a54 --- /dev/null +++ b/queue-3.10/ip6mr-fix-mfc-notification-flags.patch @@ -0,0 +1,73 @@ +From foo@baz Fri Apr 11 08:46:36 PDT 2014 +From: Nicolas Dichtel +Date: Wed, 19 Mar 2014 17:47:51 +0100 +Subject: ip6mr: fix mfc notification flags + +From: Nicolas Dichtel + +[ Upstream commit f518338b16038beeb73e155e60d0f70beb9379f4 ] + +Commit 812e44dd1829 ("ip6mr: advertise new mfc entries via rtnl") reuses the +function ip6mr_fill_mroute() to notify mfc events. +But this function was used only for dump and thus was always setting the +flag NLM_F_MULTI, which is wrong in case of a single notification. + +Libraries like libnl will wait forever for NLMSG_DONE. + +CC: Thomas Graf +Signed-off-by: Nicolas Dichtel +Acked-by: Thomas Graf +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/ip6mr.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +--- a/net/ipv6/ip6mr.c ++++ b/net/ipv6/ip6mr.c +@@ -2351,13 +2351,14 @@ int ip6mr_get_route(struct net *net, + } + + static int ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb, +- u32 portid, u32 seq, struct mfc6_cache *c, int cmd) ++ u32 portid, u32 seq, struct mfc6_cache *c, int cmd, ++ int flags) + { + struct nlmsghdr *nlh; + struct rtmsg *rtm; + int err; + +- nlh = nlmsg_put(skb, portid, seq, cmd, sizeof(*rtm), NLM_F_MULTI); ++ nlh = nlmsg_put(skb, portid, seq, cmd, sizeof(*rtm), flags); + if (nlh == NULL) + return -EMSGSIZE; + +@@ -2425,7 +2426,7 @@ static void mr6_netlink_event(struct mr6 + if (skb == NULL) + goto errout; + +- err = ip6mr_fill_mroute(mrt, skb, 0, 0, mfc, cmd); ++ err = ip6mr_fill_mroute(mrt, skb, 0, 0, mfc, cmd, 0); + if (err < 0) + goto errout; + +@@ -2464,7 +2465,8 @@ static int ip6mr_rtm_dumproute(struct sk + if (ip6mr_fill_mroute(mrt, skb, + NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, +- mfc, RTM_NEWROUTE) < 0) ++ mfc, RTM_NEWROUTE, ++ NLM_F_MULTI) < 0) + goto done; + next_entry: + e++; +@@ -2478,7 +2480,8 @@ next_entry: + if (ip6mr_fill_mroute(mrt, skb, + NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, +- mfc, RTM_NEWROUTE) < 0) { ++ mfc, RTM_NEWROUTE, ++ NLM_F_MULTI) < 0) { + spin_unlock_bh(&mfc_unres_lock); + goto done; + } diff --git a/queue-3.10/ipmr-fix-mfc-notification-flags.patch b/queue-3.10/ipmr-fix-mfc-notification-flags.patch new file mode 100644 index 00000000000..d4a1342fece --- /dev/null +++ b/queue-3.10/ipmr-fix-mfc-notification-flags.patch @@ -0,0 +1,73 @@ +From foo@baz Fri Apr 11 08:46:36 PDT 2014 +From: Nicolas Dichtel +Date: Wed, 19 Mar 2014 17:47:50 +0100 +Subject: ipmr: fix mfc notification flags + +From: Nicolas Dichtel + +[ Upstream commit 65886f439ab0fdc2dff20d1fa87afb98c6717472 ] + +Commit 8cd3ac9f9b7b ("ipmr: advertise new mfc entries via rtnl") reuses the +function ipmr_fill_mroute() to notify mfc events. +But this function was used only for dump and thus was always setting the +flag NLM_F_MULTI, which is wrong in case of a single notification. + +Libraries like libnl will wait forever for NLMSG_DONE. + +CC: Thomas Graf +Signed-off-by: Nicolas Dichtel +Acked-by: Thomas Graf +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/ipmr.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +--- a/net/ipv4/ipmr.c ++++ b/net/ipv4/ipmr.c +@@ -2255,13 +2255,14 @@ int ipmr_get_route(struct net *net, stru + } + + static int ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, +- u32 portid, u32 seq, struct mfc_cache *c, int cmd) ++ u32 portid, u32 seq, struct mfc_cache *c, int cmd, ++ int flags) + { + struct nlmsghdr *nlh; + struct rtmsg *rtm; + int err; + +- nlh = nlmsg_put(skb, portid, seq, cmd, sizeof(*rtm), NLM_F_MULTI); ++ nlh = nlmsg_put(skb, portid, seq, cmd, sizeof(*rtm), flags); + if (nlh == NULL) + return -EMSGSIZE; + +@@ -2329,7 +2330,7 @@ static void mroute_netlink_event(struct + if (skb == NULL) + goto errout; + +- err = ipmr_fill_mroute(mrt, skb, 0, 0, mfc, cmd); ++ err = ipmr_fill_mroute(mrt, skb, 0, 0, mfc, cmd, 0); + if (err < 0) + goto errout; + +@@ -2368,7 +2369,8 @@ static int ipmr_rtm_dumproute(struct sk_ + if (ipmr_fill_mroute(mrt, skb, + NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, +- mfc, RTM_NEWROUTE) < 0) ++ mfc, RTM_NEWROUTE, ++ NLM_F_MULTI) < 0) + goto done; + next_entry: + e++; +@@ -2382,7 +2384,8 @@ next_entry: + if (ipmr_fill_mroute(mrt, skb, + NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, +- mfc, RTM_NEWROUTE) < 0) { ++ mfc, RTM_NEWROUTE, ++ NLM_F_MULTI) < 0) { + spin_unlock_bh(&mfc_unres_lock); + goto done; + } diff --git a/queue-3.10/ipv6-avoid-unnecessary-temporary-addresses-being-generated.patch b/queue-3.10/ipv6-avoid-unnecessary-temporary-addresses-being-generated.patch new file mode 100644 index 00000000000..c5c9f843ed5 --- /dev/null +++ b/queue-3.10/ipv6-avoid-unnecessary-temporary-addresses-being-generated.patch @@ -0,0 +1,41 @@ +From foo@baz Fri Apr 11 08:46:36 PDT 2014 +From: Heiner Kallweit +Date: Wed, 12 Mar 2014 22:13:19 +0100 +Subject: ipv6: Avoid unnecessary temporary addresses being generated + +From: Heiner Kallweit + +[ Upstream commit ecab67015ef6e3f3635551dcc9971cf363cc1cd5 ] + +tmp_prefered_lft is an offset to ifp->tstamp, not now. Therefore +age needs to be added to the condition. + +Age calculation in ipv6_create_tempaddr is different from the one +in addrconf_verify and doesn't consider ADDRCONF_TIMER_FUZZ_MINUS. +This can cause age in ipv6_create_tempaddr to be less than the one +in addrconf_verify and therefore unnecessary temporary address to +be generated. +Use age calculation as in addrconf_modify to avoid this. + +Signed-off-by: Heiner Kallweit +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/addrconf.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -1111,8 +1111,11 @@ retry: + * Lifetime is greater than REGEN_ADVANCE time units. In particular, + * an implementation must not create a temporary address with a zero + * Preferred Lifetime. ++ * Use age calculation as in addrconf_verify to avoid unnecessary ++ * temporary addresses being generated. + */ +- if (tmp_prefered_lft <= regen_advance) { ++ age = (now - tmp_tstamp + ADDRCONF_TIMER_FUZZ_MINUS) / HZ; ++ if (tmp_prefered_lft <= regen_advance + age) { + in6_ifa_put(ifp); + in6_dev_put(idev); + ret = -1; diff --git a/queue-3.10/ipv6-don-t-set-dst_nocount-for-remotely-added-routes.patch b/queue-3.10/ipv6-don-t-set-dst_nocount-for-remotely-added-routes.patch new file mode 100644 index 00000000000..dd566a1d6cc --- /dev/null +++ b/queue-3.10/ipv6-don-t-set-dst_nocount-for-remotely-added-routes.patch @@ -0,0 +1,33 @@ +From foo@baz Fri Apr 11 08:46:36 PDT 2014 +From: Sabrina Dubroca +Date: Thu, 6 Mar 2014 17:51:57 +0100 +Subject: ipv6: don't set DST_NOCOUNT for remotely added routes + +From: Sabrina Dubroca + +[ Upstream commit c88507fbad8055297c1d1e21e599f46960cbee39 ] + +DST_NOCOUNT should only be used if an authorized user adds routes +locally. In case of routes which are added on behalf of router +advertisments this flag must not get used as it allows an unlimited +number of routes getting added remotely. + +Signed-off-by: Sabrina Dubroca +Acked-by: Hannes Frederic Sowa +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/route.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -1428,7 +1428,7 @@ int ip6_route_add(struct fib6_config *cf + if (!table) + goto out; + +- rt = ip6_dst_alloc(net, NULL, DST_NOCOUNT, table); ++ rt = ip6_dst_alloc(net, NULL, (cfg->fc_flags & RTF_ADDRCONF) ? 0 : DST_NOCOUNT, table); + + if (!rt) { + err = -ENOMEM; diff --git a/queue-3.10/ipv6-fix-exthdrs-offload-registration.patch b/queue-3.10/ipv6-fix-exthdrs-offload-registration.patch new file mode 100644 index 00000000000..0eb9c7eb27f --- /dev/null +++ b/queue-3.10/ipv6-fix-exthdrs-offload-registration.patch @@ -0,0 +1,42 @@ +From foo@baz Fri Apr 11 08:46:36 PDT 2014 +From: Anton Nayshtut +Date: Wed, 5 Mar 2014 08:30:08 +0200 +Subject: ipv6: Fix exthdrs offload registration. + +From: Anton Nayshtut + +[ Upstream commit d2d273ffabd315eecefce21a4391d44b6e156b73 ] + +Without this fix, ipv6_exthdrs_offload_init doesn't register IPPROTO_DSTOPTS +offload, but returns 0 (as the IPPROTO_ROUTING registration actually succeeds). + +This then causes the ipv6_gso_segment to drop IPv6 packets with IPPROTO_DSTOPTS +header. + +The issue detected and the fix verified by running MS HCK Offload LSO test on +top of QEMU Windows guests, as this test sends IPv6 packets with +IPPROTO_DSTOPTS. + +Signed-off-by: Anton Nayshtut +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/exthdrs_offload.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/ipv6/exthdrs_offload.c ++++ b/net/ipv6/exthdrs_offload.c +@@ -25,11 +25,11 @@ int __init ipv6_exthdrs_offload_init(voi + int ret; + + ret = inet6_add_offload(&rthdr_offload, IPPROTO_ROUTING); +- if (!ret) ++ if (ret) + goto out; + + ret = inet6_add_offload(&dstopt_offload, IPPROTO_DSTOPTS); +- if (!ret) ++ if (ret) + goto out_rt; + + out: diff --git a/queue-3.10/ipv6-ip6_append_data_mtu-do-not-handle-the-mtu-of-the-second-fragment-properly.patch b/queue-3.10/ipv6-ip6_append_data_mtu-do-not-handle-the-mtu-of-the-second-fragment-properly.patch new file mode 100644 index 00000000000..fba453ae2b3 --- /dev/null +++ b/queue-3.10/ipv6-ip6_append_data_mtu-do-not-handle-the-mtu-of-the-second-fragment-properly.patch @@ -0,0 +1,96 @@ +From foo@baz Fri Apr 11 08:46:36 PDT 2014 +From: lucien +Date: Mon, 17 Mar 2014 12:51:01 +0800 +Subject: ipv6: ip6_append_data_mtu do not handle the mtu of the second fragment properly + +From: lucien + +[ Upstream commit e367c2d03dba4c9bcafad24688fadb79dd95b218 ] + +In ip6_append_data_mtu(), when the xfrm mode is not tunnel(such as +transport),the ipsec header need to be added in the first fragment, so the mtu +will decrease to reserve space for it, then the second fragment come, the mtu +should be turn back, as the commit 0c1833797a5a6ec23ea9261d979aa18078720b74 +said. however, in the commit a493e60ac4bbe2e977e7129d6d8cbb0dd236be, it use +*mtu = min(*mtu, ...) to change the mtu, which lead to the new mtu is alway +equal with the first fragment's. and cannot turn back. + +when I test through ping6 -c1 -s5000 $ip (mtu=1280): +...frag (0|1232) ESP(spi=0x00002000,seq=0xb), length 1232 +...frag (1232|1216) +...frag (2448|1216) +...frag (3664|1216) +...frag (4880|164) + +which should be: +...frag (0|1232) ESP(spi=0x00001000,seq=0x1), length 1232 +...frag (1232|1232) +...frag (2464|1232) +...frag (3696|1232) +...frag (4928|116) + +so delete the min() when change back the mtu. + +Signed-off-by: Xin Long +Fixes: 75a493e60ac4bb ("ipv6: ip6_append_data_mtu did not care about pmtudisc and frag_size") +Acked-by: Hannes Frederic Sowa +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/ip6_output.c | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -1108,21 +1108,19 @@ static void ip6_append_data_mtu(unsigned + unsigned int fragheaderlen, + struct sk_buff *skb, + struct rt6_info *rt, +- bool pmtuprobe) ++ unsigned int orig_mtu) + { + if (!(rt->dst.flags & DST_XFRM_TUNNEL)) { + if (skb == NULL) { + /* first fragment, reserve header_len */ +- *mtu = *mtu - rt->dst.header_len; ++ *mtu = orig_mtu - rt->dst.header_len; + + } else { + /* + * this fragment is not first, the headers + * space is regarded as data space. + */ +- *mtu = min(*mtu, pmtuprobe ? +- rt->dst.dev->mtu : +- dst_mtu(rt->dst.path)); ++ *mtu = orig_mtu; + } + *maxfraglen = ((*mtu - fragheaderlen) & ~7) + + fragheaderlen - sizeof(struct frag_hdr); +@@ -1139,7 +1137,7 @@ int ip6_append_data(struct sock *sk, int + struct ipv6_pinfo *np = inet6_sk(sk); + struct inet_cork *cork; + struct sk_buff *skb, *skb_prev = NULL; +- unsigned int maxfraglen, fragheaderlen, mtu; ++ unsigned int maxfraglen, fragheaderlen, mtu, orig_mtu; + int exthdrlen; + int dst_exthdrlen; + int hh_len; +@@ -1221,6 +1219,7 @@ int ip6_append_data(struct sock *sk, int + dst_exthdrlen = 0; + mtu = cork->fragsize; + } ++ orig_mtu = mtu; + + hh_len = LL_RESERVED_SPACE(rt->dst.dev); + +@@ -1300,8 +1299,7 @@ alloc_new_skb: + if (skb == NULL || skb_prev == NULL) + ip6_append_data_mtu(&mtu, &maxfraglen, + fragheaderlen, skb, rt, +- np->pmtudisc == +- IPV6_PMTUDISC_PROBE); ++ orig_mtu); + + skb_prev = skb; + diff --git a/queue-3.10/ipv6-some-ipv6-statistic-counters-failed-to-disable-bh.patch b/queue-3.10/ipv6-some-ipv6-statistic-counters-failed-to-disable-bh.patch new file mode 100644 index 00000000000..ad2d834bdd6 --- /dev/null +++ b/queue-3.10/ipv6-some-ipv6-statistic-counters-failed-to-disable-bh.patch @@ -0,0 +1,80 @@ +From foo@baz Fri Apr 11 08:46:36 PDT 2014 +From: Hannes Frederic Sowa +Date: Mon, 31 Mar 2014 20:14:10 +0200 +Subject: ipv6: some ipv6 statistic counters failed to disable bh + +From: Hannes Frederic Sowa + +[ Upstream commit 43a43b6040165f7b40b5b489fe61a4cb7f8c4980 ] + +After commit c15b1ccadb323ea ("ipv6: move DAD and addrconf_verify +processing to workqueue") some counters are now updated in process context +and thus need to disable bh before doing so, otherwise deadlocks can +happen on 32-bit archs. Fabio Estevam noticed this while while mounting +a NFS volume on an ARM board. + +As a compensation for missing this I looked after the other *_STATS_BH +and found three other calls which need updating: + +1) icmp6_send: ip6_fragment -> icmpv6_send -> icmp6_send (error handling) +2) ip6_push_pending_frames: rawv6_sendmsg -> rawv6_push_pending_frames -> ... + (only in case of icmp protocol with raw sockets in error handling) +3) ping6_v6_sendmsg (error handling) + +Fixes: c15b1ccadb323ea ("ipv6: move DAD and addrconf_verify processing to workqueue") +Reported-by: Fabio Estevam +Tested-by: Fabio Estevam +Cc: Eric Dumazet +Signed-off-by: Hannes Frederic Sowa +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/icmp.c | 2 +- + net/ipv6/ip6_output.c | 4 ++-- + net/ipv6/mcast.c | 11 ++++++----- + 3 files changed, 9 insertions(+), 8 deletions(-) + +--- a/net/ipv6/icmp.c ++++ b/net/ipv6/icmp.c +@@ -508,7 +508,7 @@ static void icmp6_send(struct sk_buff *s + np->tclass, NULL, &fl6, (struct rt6_info *)dst, + MSG_DONTWAIT, np->dontfrag); + if (err) { +- ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTERRORS); ++ ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTERRORS); + ip6_flush_pending_frames(sk); + } else { + err = icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr, +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -1554,8 +1554,8 @@ int ip6_push_pending_frames(struct sock + if (proto == IPPROTO_ICMPV6) { + struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb)); + +- ICMP6MSGOUT_INC_STATS_BH(net, idev, icmp6_hdr(skb)->icmp6_type); +- ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS); ++ ICMP6MSGOUT_INC_STATS(net, idev, icmp6_hdr(skb)->icmp6_type); ++ ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS); + } + + err = ip6_local_out(skb); +--- a/net/ipv6/mcast.c ++++ b/net/ipv6/mcast.c +@@ -1439,11 +1439,12 @@ static void mld_sendpack(struct sk_buff + dst_output); + out: + if (!err) { +- ICMP6MSGOUT_INC_STATS_BH(net, idev, ICMPV6_MLD2_REPORT); +- ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS); +- IP6_UPD_PO_STATS_BH(net, idev, IPSTATS_MIB_OUTMCAST, payload_len); +- } else +- IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_OUTDISCARDS); ++ ICMP6MSGOUT_INC_STATS(net, idev, ICMPV6_MLD2_REPORT); ++ ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS); ++ IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUTMCAST, payload_len); ++ } else { ++ IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS); ++ } + + rcu_read_unlock(); + return; diff --git a/queue-3.10/isdnloop-several-buffer-overflows.patch b/queue-3.10/isdnloop-several-buffer-overflows.patch new file mode 100644 index 00000000000..e100d8bfe5e --- /dev/null +++ b/queue-3.10/isdnloop-several-buffer-overflows.patch @@ -0,0 +1,95 @@ +From foo@baz Fri Apr 11 08:46:36 PDT 2014 +From: Dan Carpenter +Date: Tue, 8 Apr 2014 12:23:09 +0300 +Subject: isdnloop: several buffer overflows + +From: Dan Carpenter + +[ Upstream commit 7563487cbf865284dcd35e9ef5a95380da046737 ] + +There are three buffer overflows addressed in this patch. + +1) In isdnloop_fake_err() we add an 'E' to a 60 character string and +then copy it into a 60 character buffer. I have made the destination +buffer 64 characters and I'm changed the sprintf() to a snprintf(). + +2) In isdnloop_parse_cmd(), p points to a 6 characters into a 60 +character buffer so we have 54 characters. The ->eazlist[] is 11 +characters long. I have modified the code to return if the source +buffer is too long. + +3) In isdnloop_command() the cbuf[] array was 60 characters long but the +max length of the string then can be up to 79 characters. I made the +cbuf array 80 characters long and changed the sprintf() to snprintf(). +I also removed the temporary "dial" buffer and changed it to use "p" +directly. + +Unfortunately, we pass the "cbuf" string from isdnloop_command() to +isdnloop_writecmd() which truncates anything over 60 characters to make +it fit in card->omsg[]. (It can accept values up to 255 characters so +long as there is a '\n' character every 60 characters). For now I have +just fixed the memory corruption bug and left the other problems in this +driver alone. + +Signed-off-by: Dan Carpenter +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/isdn/isdnloop/isdnloop.c | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +--- a/drivers/isdn/isdnloop/isdnloop.c ++++ b/drivers/isdn/isdnloop/isdnloop.c +@@ -518,9 +518,9 @@ static isdnloop_stat isdnloop_cmd_table[ + static void + isdnloop_fake_err(isdnloop_card *card) + { +- char buf[60]; ++ char buf[64]; + +- sprintf(buf, "E%s", card->omsg); ++ snprintf(buf, sizeof(buf), "E%s", card->omsg); + isdnloop_fake(card, buf, -1); + isdnloop_fake(card, "NAK", -1); + } +@@ -903,6 +903,8 @@ isdnloop_parse_cmd(isdnloop_card *card) + case 7: + /* 0x;EAZ */ + p += 3; ++ if (strlen(p) >= sizeof(card->eazlist[0])) ++ break; + strcpy(card->eazlist[ch - 1], p); + break; + case 8: +@@ -1133,7 +1135,7 @@ isdnloop_command(isdn_ctrl *c, isdnloop_ + { + ulong a; + int i; +- char cbuf[60]; ++ char cbuf[80]; + isdn_ctrl cmd; + isdnloop_cdef cdef; + +@@ -1198,7 +1200,6 @@ isdnloop_command(isdn_ctrl *c, isdnloop_ + break; + if ((c->arg & 255) < ISDNLOOP_BCH) { + char *p; +- char dial[50]; + char dcode[4]; + + a = c->arg; +@@ -1210,10 +1211,10 @@ isdnloop_command(isdn_ctrl *c, isdnloop_ + } else + /* Normal Dial */ + strcpy(dcode, "CAL"); +- strcpy(dial, p); +- sprintf(cbuf, "%02d;D%s_R%s,%02d,%02d,%s\n", (int) (a + 1), +- dcode, dial, c->parm.setup.si1, +- c->parm.setup.si2, c->parm.setup.eazmsn); ++ snprintf(cbuf, sizeof(cbuf), ++ "%02d;D%s_R%s,%02d,%02d,%s\n", (int) (a + 1), ++ dcode, p, c->parm.setup.si1, ++ c->parm.setup.si2, c->parm.setup.eazmsn); + i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card); + } + break; diff --git a/queue-3.10/isdnloop-validate-nul-terminated-strings-from-user.patch b/queue-3.10/isdnloop-validate-nul-terminated-strings-from-user.patch new file mode 100644 index 00000000000..627823f9f6a --- /dev/null +++ b/queue-3.10/isdnloop-validate-nul-terminated-strings-from-user.patch @@ -0,0 +1,34 @@ +From foo@baz Fri Apr 11 08:46:36 PDT 2014 +From: YOSHIFUJI Hideaki +Date: Wed, 2 Apr 2014 12:48:42 +0900 +Subject: isdnloop: Validate NUL-terminated strings from user. + +From: YOSHIFUJI Hideaki + +[ Upstream commit 77bc6bed7121936bb2e019a8c336075f4c8eef62 ] + +Return -EINVAL unless all of user-given strings are correctly +NUL-terminated. + +Signed-off-by: YOSHIFUJI Hideaki +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/isdn/isdnloop/isdnloop.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/isdn/isdnloop/isdnloop.c ++++ b/drivers/isdn/isdnloop/isdnloop.c +@@ -1070,6 +1070,12 @@ isdnloop_start(isdnloop_card *card, isdn + return -EBUSY; + if (copy_from_user((char *) &sdef, (char *) sdefp, sizeof(sdef))) + return -EFAULT; ++ ++ for (i = 0; i < 3; i++) { ++ if (!memchr(sdef.num[i], 0, sizeof(sdef.num[i]))) ++ return -EINVAL; ++ } ++ + spin_lock_irqsave(&card->isdnloop_lock, flags); + switch (sdef.ptype) { + case ISDN_PTYPE_EURO: diff --git a/queue-3.10/net-fix-for-a-race-condition-in-the-inet-frag-code.patch b/queue-3.10/net-fix-for-a-race-condition-in-the-inet-frag-code.patch new file mode 100644 index 00000000000..c7a246fdc0c --- /dev/null +++ b/queue-3.10/net-fix-for-a-race-condition-in-the-inet-frag-code.patch @@ -0,0 +1,94 @@ +From foo@baz Fri Apr 11 08:46:36 PDT 2014 +From: Nikolay Aleksandrov +Date: Mon, 3 Mar 2014 23:19:18 +0100 +Subject: net: fix for a race condition in the inet frag code + +From: Nikolay Aleksandrov + +[ Upstream commit 24b9bf43e93e0edd89072da51cf1fab95fc69dec ] + +I stumbled upon this very serious bug while hunting for another one, +it's a very subtle race condition between inet_frag_evictor, +inet_frag_intern and the IPv4/6 frag_queue and expire functions +(basically the users of inet_frag_kill/inet_frag_put). + +What happens is that after a fragment has been added to the hash chain +but before it's been added to the lru_list (inet_frag_lru_add) in +inet_frag_intern, it may get deleted (either by an expired timer if +the system load is high or the timer sufficiently low, or by the +fraq_queue function for different reasons) before it's added to the +lru_list, then after it gets added it's a matter of time for the +evictor to get to a piece of memory which has been freed leading to a +number of different bugs depending on what's left there. + +I've been able to trigger this on both IPv4 and IPv6 (which is normal +as the frag code is the same), but it's been much more difficult to +trigger on IPv4 due to the protocol differences about how fragments +are treated. + +The setup I used to reproduce this is: 2 machines with 4 x 10G bonded +in a RR bond, so the same flow can be seen on multiple cards at the +same time. Then I used multiple instances of ping/ping6 to generate +fragmented packets and flood the machines with them while running +other processes to load the attacked machine. + +*It is very important to have the _same flow_ coming in on multiple CPUs +concurrently. Usually the attacked machine would die in less than 30 +minutes, if configured properly to have many evictor calls and timeouts +it could happen in 10 minutes or so. + +An important point to make is that any caller (frag_queue or timer) of +inet_frag_kill will remove both the timer refcount and the +original/guarding refcount thus removing everything that's keeping the +frag from being freed at the next inet_frag_put. All of this could +happen before the frag was ever added to the LRU list, then it gets +added and the evictor uses a freed fragment. + +An example for IPv6 would be if a fragment is being added and is at +the stage of being inserted in the hash after the hash lock is +released, but before inet_frag_lru_add executes (or is able to obtain +the lru lock) another overlapping fragment for the same flow arrives +at a different CPU which finds it in the hash, but since it's +overlapping it drops it invoking inet_frag_kill and thus removing all +guarding refcounts, and afterwards freeing it by invoking +inet_frag_put which removes the last refcount added previously by +inet_frag_find, then inet_frag_lru_add gets executed by +inet_frag_intern and we have a freed fragment in the lru_list. + +The fix is simple, just move the lru_add under the hash chain locked +region so when a removing function is called it'll have to wait for +the fragment to be added to the lru_list, and then it'll remove it (it +works because the hash chain removal is done before the lru_list one +and there's no window between the two list adds when the frag can get +dropped). With this fix applied I couldn't kill the same machine in 24 +hours with the same setup. + +Fixes: 3ef0eb0db4bf ("net: frag, move LRU list maintenance outside of +rwlock") + +CC: Florian Westphal +CC: Jesper Dangaard Brouer +CC: David S. Miller + +Signed-off-by: Nikolay Aleksandrov +Acked-by: Jesper Dangaard Brouer +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/inet_fragment.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/ipv4/inet_fragment.c ++++ b/net/ipv4/inet_fragment.c +@@ -283,9 +283,10 @@ static struct inet_frag_queue *inet_frag + + atomic_inc(&qp->refcnt); + hlist_add_head(&qp->list, &hb->chain); ++ inet_frag_lru_add(nf, qp); + spin_unlock(&hb->chain_lock); + read_unlock(&f->lock); +- inet_frag_lru_add(nf, qp); ++ + return qp; + } + diff --git a/queue-3.10/net-sctp-fix-skb-leakage-in-cookie-echo-path-of-chunk-auth_chunk.patch b/queue-3.10/net-sctp-fix-skb-leakage-in-cookie-echo-path-of-chunk-auth_chunk.patch new file mode 100644 index 00000000000..c672fdf47ef --- /dev/null +++ b/queue-3.10/net-sctp-fix-skb-leakage-in-cookie-echo-path-of-chunk-auth_chunk.patch @@ -0,0 +1,120 @@ +From foo@baz Fri Apr 11 08:46:36 PDT 2014 +From: Daniel Borkmann +Date: Tue, 4 Mar 2014 16:35:51 +0100 +Subject: net: sctp: fix skb leakage in COOKIE ECHO path of chunk->auth_chunk + +From: Daniel Borkmann + +[ Upstream commit c485658bae87faccd7aed540fd2ca3ab37992310 ] + +While working on ec0223ec48a9 ("net: sctp: fix sctp_sf_do_5_1D_ce to +verify if we/peer is AUTH capable"), we noticed that there's a skb +memory leakage in the error path. + +Running the same reproducer as in ec0223ec48a9 and by unconditionally +jumping to the error label (to simulate an error condition) in +sctp_sf_do_5_1D_ce() receive path lets kmemleak detector bark about +the unfreed chunk->auth_chunk skb clone: + +Unreferenced object 0xffff8800b8f3a000 (size 256): + comm "softirq", pid 0, jiffies 4294769856 (age 110.757s) + hex dump (first 32 bytes): + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 89 ab 75 5e d4 01 58 13 00 00 00 00 00 00 00 00 ..u^..X......... + backtrace: + [] kmemleak_alloc+0x4e/0xb0 + [] kmem_cache_alloc+0xc8/0x210 + [] skb_clone+0x49/0xb0 + [] sctp_endpoint_bh_rcv+0x1d9/0x230 [sctp] + [] sctp_inq_push+0x4c/0x70 [sctp] + [] sctp_rcv+0x82e/0x9a0 [sctp] + [] ip_local_deliver_finish+0xa8/0x210 + [] nf_reinject+0xbf/0x180 + [] nfqnl_recv_verdict+0x1d2/0x2b0 [nfnetlink_queue] + [] nfnetlink_rcv_msg+0x14b/0x250 [nfnetlink] + [] netlink_rcv_skb+0xa9/0xc0 + [] nfnetlink_rcv+0x23f/0x408 [nfnetlink] + [] netlink_unicast+0x168/0x250 + [] netlink_sendmsg+0x2e1/0x3f0 + [] sock_sendmsg+0x8b/0xc0 + [] ___sys_sendmsg+0x369/0x380 + +What happens is that commit bbd0d59809f9 clones the skb containing +the AUTH chunk in sctp_endpoint_bh_rcv() when having the edge case +that an endpoint requires COOKIE-ECHO chunks to be authenticated: + + ---------- INIT[RANDOM; CHUNKS; HMAC-ALGO] ----------> + <------- INIT-ACK[RANDOM; CHUNKS; HMAC-ALGO] --------- + ------------------ AUTH; COOKIE-ECHO ----------------> + <-------------------- COOKIE-ACK --------------------- + +When we enter sctp_sf_do_5_1D_ce() and before we actually get to +the point where we process (and subsequently free) a non-NULL +chunk->auth_chunk, we could hit the "goto nomem_init" path from +an error condition and thus leave the cloned skb around w/o +freeing it. + +The fix is to centrally free such clones in sctp_chunk_destroy() +handler that is invoked from sctp_chunk_free() after all refs have +dropped; and also move both kfree_skb(chunk->auth_chunk) there, +so that chunk->auth_chunk is either NULL (since sctp_chunkify() +allocs new chunks through kmem_cache_zalloc()) or non-NULL with +a valid skb pointer. chunk->skb and chunk->auth_chunk are the +only skbs in the sctp_chunk structure that need to be handeled. + +While at it, we should use consume_skb() for both. It is the same +as dev_kfree_skb() but more appropriately named as we are not +a device but a protocol. Also, this effectively replaces the +kfree_skb() from both invocations into consume_skb(). Functions +are the same only that kfree_skb() assumes that the frame was +being dropped after a failure (e.g. for tools like drop monitor), +usage of consume_skb() seems more appropriate in function +sctp_chunk_destroy() though. + +Fixes: bbd0d59809f9 ("[SCTP]: Implement the receive and verification of AUTH chunk") +Signed-off-by: Daniel Borkmann +Cc: Vlad Yasevich +Cc: Neil Horman +Acked-by: Vlad Yasevich +Acked-by: Neil Horman +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/sctp/sm_make_chunk.c | 4 ++-- + net/sctp/sm_statefuns.c | 5 ----- + 2 files changed, 2 insertions(+), 7 deletions(-) + +--- a/net/sctp/sm_make_chunk.c ++++ b/net/sctp/sm_make_chunk.c +@@ -1403,8 +1403,8 @@ static void sctp_chunk_destroy(struct sc + BUG_ON(!list_empty(&chunk->list)); + list_del_init(&chunk->transmitted_list); + +- /* Free the chunk skb data and the SCTP_chunk stub itself. */ +- dev_kfree_skb(chunk->skb); ++ consume_skb(chunk->skb); ++ consume_skb(chunk->auth_chunk); + + SCTP_DBG_OBJCNT_DEC(chunk); + kmem_cache_free(sctp_chunk_cachep, chunk); +--- a/net/sctp/sm_statefuns.c ++++ b/net/sctp/sm_statefuns.c +@@ -767,7 +767,6 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(st + + /* Make sure that we and the peer are AUTH capable */ + if (!net->sctp.auth_enable || !new_asoc->peer.auth_capable) { +- kfree_skb(chunk->auth_chunk); + sctp_association_free(new_asoc); + return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); + } +@@ -782,10 +781,6 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(st + auth.transport = chunk->transport; + + ret = sctp_sf_authenticate(net, ep, new_asoc, type, &auth); +- +- /* We can now safely free the auth_chunk clone */ +- kfree_skb(chunk->auth_chunk); +- + if (ret != SCTP_IERROR_NO_ERROR) { + sctp_association_free(new_asoc); + return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); diff --git a/queue-3.10/net-socket-error-on-a-negative-msg_namelen.patch b/queue-3.10/net-socket-error-on-a-negative-msg_namelen.patch new file mode 100644 index 00000000000..4fe4c12e7a3 --- /dev/null +++ b/queue-3.10/net-socket-error-on-a-negative-msg_namelen.patch @@ -0,0 +1,35 @@ +From foo@baz Fri Apr 11 08:46:36 PDT 2014 +From: Matthew Leach +Date: Tue, 11 Mar 2014 11:58:27 +0000 +Subject: net: socket: error on a negative msg_namelen + +From: Matthew Leach + +[ Upstream commit dbb490b96584d4e958533fb637f08b557f505657 ] + +When copying in a struct msghdr from the user, if the user has set the +msg_namelen parameter to a negative value it gets clamped to a valid +size due to a comparison between signed and unsigned values. + +Ensure the syscall errors when the user passes in a negative value. + +Signed-off-by: Matthew Leach +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/socket.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/net/socket.c ++++ b/net/socket.c +@@ -1964,6 +1964,10 @@ static int copy_msghdr_from_user(struct + { + if (copy_from_user(kmsg, umsg, sizeof(struct msghdr))) + return -EFAULT; ++ ++ if (kmsg->msg_namelen < 0) ++ return -EINVAL; ++ + if (kmsg->msg_namelen > sizeof(struct sockaddr_storage)) + kmsg->msg_namelen = sizeof(struct sockaddr_storage); + return 0; diff --git a/queue-3.10/net-unix-non-blocking-recvmsg-should-not-return-eintr.patch b/queue-3.10/net-unix-non-blocking-recvmsg-should-not-return-eintr.patch new file mode 100644 index 00000000000..1d7a096a4ff --- /dev/null +++ b/queue-3.10/net-unix-non-blocking-recvmsg-should-not-return-eintr.patch @@ -0,0 +1,73 @@ +From foo@baz Fri Apr 11 08:46:36 PDT 2014 +From: Eric Dumazet +Date: Tue, 25 Mar 2014 18:42:27 -0700 +Subject: net: unix: non blocking recvmsg() should not return -EINTR + +From: Eric Dumazet + +[ Upstream commit de1443916791d75fdd26becb116898277bb0273f ] + +Some applications didn't expect recvmsg() on a non blocking socket +could return -EINTR. This possibility was added as a side effect +of commit b3ca9b02b00704 ("net: fix multithreaded signal handling in +unix recv routines"). + +To hit this bug, you need to be a bit unlucky, as the u->readlock +mutex is usually held for very small periods. + +Fixes: b3ca9b02b00704 ("net: fix multithreaded signal handling in unix recv routines") +Signed-off-by: Eric Dumazet +Cc: Rainer Weikusat +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/unix/af_unix.c | 17 ++++++++++++----- + 1 file changed, 12 insertions(+), 5 deletions(-) + +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -1792,8 +1792,11 @@ static int unix_dgram_recvmsg(struct kio + goto out; + + err = mutex_lock_interruptible(&u->readlock); +- if (err) { +- err = sock_intr_errno(sock_rcvtimeo(sk, noblock)); ++ if (unlikely(err)) { ++ /* recvmsg() in non blocking mode is supposed to return -EAGAIN ++ * sk_rcvtimeo is not honored by mutex_lock_interruptible() ++ */ ++ err = noblock ? -EAGAIN : -ERESTARTSYS; + goto out; + } + +@@ -1913,6 +1916,7 @@ static int unix_stream_recvmsg(struct ki + struct unix_sock *u = unix_sk(sk); + struct sockaddr_un *sunaddr = msg->msg_name; + int copied = 0; ++ int noblock = flags & MSG_DONTWAIT; + int check_creds = 0; + int target; + int err = 0; +@@ -1928,7 +1932,7 @@ static int unix_stream_recvmsg(struct ki + goto out; + + target = sock_rcvlowat(sk, flags&MSG_WAITALL, size); +- timeo = sock_rcvtimeo(sk, flags&MSG_DONTWAIT); ++ timeo = sock_rcvtimeo(sk, noblock); + + /* Lock the socket to prevent queue disordering + * while sleeps in memcpy_tomsg +@@ -1940,8 +1944,11 @@ static int unix_stream_recvmsg(struct ki + } + + err = mutex_lock_interruptible(&u->readlock); +- if (err) { +- err = sock_intr_errno(timeo); ++ if (unlikely(err)) { ++ /* recvmsg() in non blocking mode is supposed to return -EAGAIN ++ * sk_rcvtimeo is not honored by mutex_lock_interruptible() ++ */ ++ err = noblock ? -EAGAIN : -ERESTARTSYS; + goto out; + } + diff --git a/queue-3.10/netlink-don-t-compare-the-nul-termination-in-nla_strcmp.patch b/queue-3.10/netlink-don-t-compare-the-nul-termination-in-nla_strcmp.patch new file mode 100644 index 00000000000..bd7caa7ef8a --- /dev/null +++ b/queue-3.10/netlink-don-t-compare-the-nul-termination-in-nla_strcmp.patch @@ -0,0 +1,55 @@ +From foo@baz Fri Apr 11 08:46:36 PDT 2014 +From: Pablo Neira +Date: Tue, 1 Apr 2014 19:38:44 +0200 +Subject: netlink: don't compare the nul-termination in nla_strcmp + +From: Pablo Neira + +[ Upstream commit 8b7b932434f5eee495b91a2804f5b64ebb2bc835 ] + +nla_strcmp compares the string length plus one, so it's implicitly +including the nul-termination in the comparison. + + int nla_strcmp(const struct nlattr *nla, const char *str) + { + int len = strlen(str) + 1; + ... + d = memcmp(nla_data(nla), str, len); + +However, if NLA_STRING is used, userspace can send us a string without +the nul-termination. This is a problem since the string +comparison will not match as the last byte may be not the +nul-termination. + +Fix this by skipping the comparison of the nul-termination if the +attribute data is nul-terminated. Suggested by Thomas Graf. + +Cc: Florian Westphal +Cc: Thomas Graf +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + lib/nlattr.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/lib/nlattr.c ++++ b/lib/nlattr.c +@@ -303,9 +303,15 @@ int nla_memcmp(const struct nlattr *nla, + */ + int nla_strcmp(const struct nlattr *nla, const char *str) + { +- int len = strlen(str) + 1; +- int d = nla_len(nla) - len; ++ int len = strlen(str); ++ char *buf = nla_data(nla); ++ int attrlen = nla_len(nla); ++ int d; + ++ if (attrlen > 0 && buf[attrlen - 1] == '\0') ++ attrlen--; ++ ++ d = attrlen - len; + if (d == 0) + d = memcmp(nla_data(nla), str, len); + diff --git a/queue-3.10/netpoll-fix-the-skb-check-in-pkt_is_ns.patch b/queue-3.10/netpoll-fix-the-skb-check-in-pkt_is_ns.patch new file mode 100644 index 00000000000..d3884e123b9 --- /dev/null +++ b/queue-3.10/netpoll-fix-the-skb-check-in-pkt_is_ns.patch @@ -0,0 +1,31 @@ +From foo@baz Fri Apr 11 08:46:36 PDT 2014 +From: Li RongQing +Date: Fri, 21 Mar 2014 20:53:57 +0800 +Subject: netpoll: fix the skb check in pkt_is_ns + +From: Li RongQing + +[ Not applicable upstream commit, the code here has been removed + upstream. ] + +Neighbor Solicitation is ipv6 protocol, so we should check +skb->protocol with ETH_P_IPV6 + +Signed-off-by: Li RongQing +Cc: WANG Cong +Signed-off-by: Greg Kroah-Hartman +--- + net/core/netpoll.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/core/netpoll.c ++++ b/net/core/netpoll.c +@@ -745,7 +745,7 @@ static bool pkt_is_ns(struct sk_buff *sk + struct nd_msg *msg; + struct ipv6hdr *hdr; + +- if (skb->protocol != htons(ETH_P_ARP)) ++ if (skb->protocol != htons(ETH_P_IPV6)) + return false; + if (!pskb_may_pull(skb, sizeof(struct ipv6hdr) + sizeof(struct nd_msg))) + return false; diff --git a/queue-3.10/rds-prevent-dereference-of-a-null-device-in-rds_iw_laddr_check.patch b/queue-3.10/rds-prevent-dereference-of-a-null-device-in-rds_iw_laddr_check.patch new file mode 100644 index 00000000000..0e85734edef --- /dev/null +++ b/queue-3.10/rds-prevent-dereference-of-a-null-device-in-rds_iw_laddr_check.patch @@ -0,0 +1,31 @@ +From foo@baz Fri Apr 11 08:46:36 PDT 2014 +From: Sasha Levin +Date: Sat, 29 Mar 2014 20:39:35 -0400 +Subject: rds: prevent dereference of a NULL device in rds_iw_laddr_check + +From: Sasha Levin + +[ Upstream commit bf39b4247b8799935ea91d90db250ab608a58e50 ] + +Binding might result in a NULL device which is later dereferenced +without checking. + +Signed-off-by: Sasha Levin +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/rds/iw.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/rds/iw.c ++++ b/net/rds/iw.c +@@ -239,7 +239,8 @@ static int rds_iw_laddr_check(__be32 add + ret = rdma_bind_addr(cm_id, (struct sockaddr *)&sin); + /* due to this, we will claim to support IB devices unless we + check node_type. */ +- if (ret || cm_id->device->node_type != RDMA_NODE_RNIC) ++ if (ret || !cm_id->device || ++ cm_id->device->node_type != RDMA_NODE_RNIC) + ret = -EADDRNOTAVAIL; + + rdsdebug("addr %pI4 ret %d node type %d\n", diff --git a/queue-3.10/rtnetlink-fix-fdb-notification-flags.patch b/queue-3.10/rtnetlink-fix-fdb-notification-flags.patch new file mode 100644 index 00000000000..128adf2a458 --- /dev/null +++ b/queue-3.10/rtnetlink-fix-fdb-notification-flags.patch @@ -0,0 +1,62 @@ +From foo@baz Fri Apr 11 08:46:36 PDT 2014 +From: Nicolas Dichtel +Date: Wed, 19 Mar 2014 17:47:49 +0100 +Subject: rtnetlink: fix fdb notification flags + +From: Nicolas Dichtel + +[ Upstream commit 1c104a6bebf3c16b6248408b84f91d09ac8a26b6 ] + +Commit 3ff661c38c84 ("net: rtnetlink notify events for FDB NTF_SELF adds and +deletes") reuses the function nlmsg_populate_fdb_fill() to notify fdb events. +But this function was used only for dump and thus was always setting the +flag NLM_F_MULTI, which is wrong in case of a single notification. + +Libraries like libnl will wait forever for NLMSG_DONE. + +CC: Thomas Graf +Signed-off-by: Nicolas Dichtel +Acked-by: Thomas Graf +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/rtnetlink.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/net/core/rtnetlink.c ++++ b/net/core/rtnetlink.c +@@ -1973,12 +1973,13 @@ EXPORT_SYMBOL(rtmsg_ifinfo); + static int nlmsg_populate_fdb_fill(struct sk_buff *skb, + struct net_device *dev, + u8 *addr, u32 pid, u32 seq, +- int type, unsigned int flags) ++ int type, unsigned int flags, ++ int nlflags) + { + struct nlmsghdr *nlh; + struct ndmsg *ndm; + +- nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndm), NLM_F_MULTI); ++ nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndm), nlflags); + if (!nlh) + return -EMSGSIZE; + +@@ -2016,7 +2017,7 @@ static void rtnl_fdb_notify(struct net_d + if (!skb) + goto errout; + +- err = nlmsg_populate_fdb_fill(skb, dev, addr, 0, 0, type, NTF_SELF); ++ err = nlmsg_populate_fdb_fill(skb, dev, addr, 0, 0, type, NTF_SELF, 0); + if (err < 0) { + kfree_skb(skb); + goto errout; +@@ -2249,7 +2250,8 @@ static int nlmsg_populate_fdb(struct sk_ + + err = nlmsg_populate_fdb_fill(skb, dev, ha->addr, + portid, seq, +- RTM_NEWNEIGH, NTF_SELF); ++ RTM_NEWNEIGH, NTF_SELF, ++ NLM_F_MULTI); + if (err < 0) + return err; + skip: diff --git a/queue-3.10/series b/queue-3.10/series index d634f8ebaef..d2c81ca277d 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -4,3 +4,31 @@ powernow-k6-correctly-initialize-default-parameters.patch powernow-k6-reorder-frequencies.patch kbuild-fix-make-headers_install-when-path-is-too-long.patch cpuidle-check-the-result-of-cpuidle_get_driver-against-null.patch +net-fix-for-a-race-condition-in-the-inet-frag-code.patch +net-sctp-fix-skb-leakage-in-cookie-echo-path-of-chunk-auth_chunk.patch +bridge-multicast-add-sanity-check-for-query-source-addresses.patch +inet-frag-make-sure-forced-eviction-removes-all-frags.patch +net-unix-non-blocking-recvmsg-should-not-return-eintr.patch +ipv6-fix-exthdrs-offload-registration.patch +ipv6-don-t-set-dst_nocount-for-remotely-added-routes.patch +vlan-set-correct-source-mac-address-with-tx-vlan-offload-enabled.patch +tcp-tcp_release_cb-should-release-socket-ownership.patch +net-socket-error-on-a-negative-msg_namelen.patch +ipv6-avoid-unnecessary-temporary-addresses-being-generated.patch +ipv6-ip6_append_data_mtu-do-not-handle-the-mtu-of-the-second-fragment-properly.patch +vxlan-fix-potential-null-dereference-in-arp_reduce.patch +rtnetlink-fix-fdb-notification-flags.patch +ipmr-fix-mfc-notification-flags.patch +ip6mr-fix-mfc-notification-flags.patch +netpoll-fix-the-skb-check-in-pkt_is_ns.patch +tg3-do-not-include-vlan-acceleration-features-in-vlan_features.patch +usbnet-include-wait-queue-head-in-device-structure.patch +vlan-set-hard_header_len-according-to-available-acceleration.patch +vhost-fix-total-length-when-packets-are-too-short.patch +vhost-validate-vhost_get_vq_desc-return-value.patch +xen-netback-remove-pointless-clause-from-if-statement.patch +ipv6-some-ipv6-statistic-counters-failed-to-disable-bh.patch +netlink-don-t-compare-the-nul-termination-in-nla_strcmp.patch +isdnloop-validate-nul-terminated-strings-from-user.patch +isdnloop-several-buffer-overflows.patch +rds-prevent-dereference-of-a-null-device-in-rds_iw_laddr_check.patch diff --git a/queue-3.10/tcp-tcp_release_cb-should-release-socket-ownership.patch b/queue-3.10/tcp-tcp_release_cb-should-release-socket-ownership.patch new file mode 100644 index 00000000000..f22b4d2b37a --- /dev/null +++ b/queue-3.10/tcp-tcp_release_cb-should-release-socket-ownership.patch @@ -0,0 +1,122 @@ +From foo@baz Fri Apr 11 08:46:36 PDT 2014 +From: Eric Dumazet +Date: Mon, 10 Mar 2014 09:50:11 -0700 +Subject: tcp: tcp_release_cb() should release socket ownership + +From: Eric Dumazet + +[ Upstream commit c3f9b01849ef3bc69024990092b9f42e20df7797 ] + +Lars Persson reported following deadlock : + +-000 |M:0x0:0x802B6AF8(asm) <-- arch_spin_lock +-001 |tcp_v4_rcv(skb = 0x8BD527A0) <-- sk = 0x8BE6B2A0 +-002 |ip_local_deliver_finish(skb = 0x8BD527A0) +-003 |__netif_receive_skb_core(skb = 0x8BD527A0, ?) +-004 |netif_receive_skb(skb = 0x8BD527A0) +-005 |elk_poll(napi = 0x8C770500, budget = 64) +-006 |net_rx_action(?) +-007 |__do_softirq() +-008 |do_softirq() +-009 |local_bh_enable() +-010 |tcp_rcv_established(sk = 0x8BE6B2A0, skb = 0x87D3A9E0, th = 0x814EBE14, ?) +-011 |tcp_v4_do_rcv(sk = 0x8BE6B2A0, skb = 0x87D3A9E0) +-012 |tcp_delack_timer_handler(sk = 0x8BE6B2A0) +-013 |tcp_release_cb(sk = 0x8BE6B2A0) +-014 |release_sock(sk = 0x8BE6B2A0) +-015 |tcp_sendmsg(?, sk = 0x8BE6B2A0, ?, ?) +-016 |sock_sendmsg(sock = 0x8518C4C0, msg = 0x87D8DAA8, size = 4096) +-017 |kernel_sendmsg(?, ?, ?, ?, size = 4096) +-018 |smb_send_kvec() +-019 |smb_send_rqst(server = 0x87C4D400, rqst = 0x87D8DBA0) +-020 |cifs_call_async() +-021 |cifs_async_writev(wdata = 0x87FD6580) +-022 |cifs_writepages(mapping = 0x852096E4, wbc = 0x87D8DC88) +-023 |__writeback_single_inode(inode = 0x852095D0, wbc = 0x87D8DC88) +-024 |writeback_sb_inodes(sb = 0x87D6D800, wb = 0x87E4A9C0, work = 0x87D8DD88) +-025 |__writeback_inodes_wb(wb = 0x87E4A9C0, work = 0x87D8DD88) +-026 |wb_writeback(wb = 0x87E4A9C0, work = 0x87D8DD88) +-027 |wb_do_writeback(wb = 0x87E4A9C0, force_wait = 0) +-028 |bdi_writeback_workfn(work = 0x87E4A9CC) +-029 |process_one_work(worker = 0x8B045880, work = 0x87E4A9CC) +-030 |worker_thread(__worker = 0x8B045880) +-031 |kthread(_create = 0x87CADD90) +-032 |ret_from_kernel_thread(asm) + +Bug occurs because __tcp_checksum_complete_user() enables BH, assuming +it is running from softirq context. + +Lars trace involved a NIC without RX checksum support but other points +are problematic as well, like the prequeue stuff. + +Problem is triggered by a timer, that found socket being owned by user. + +tcp_release_cb() should call tcp_write_timer_handler() or +tcp_delack_timer_handler() in the appropriate context : + +BH disabled and socket lock held, but 'owned' field cleared, +as if they were running from timer handlers. + +Fixes: 6f458dfb4092 ("tcp: improve latencies of timer triggered events") +Reported-by: Lars Persson +Tested-by: Lars Persson +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/net/sock.h | 5 +++++ + net/core/sock.c | 5 ++++- + net/ipv4/tcp_output.c | 11 +++++++++++ + 3 files changed, 20 insertions(+), 1 deletion(-) + +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -1437,6 +1437,11 @@ static inline void sk_wmem_free_skb(stru + */ + #define sock_owned_by_user(sk) ((sk)->sk_lock.owned) + ++static inline void sock_release_ownership(struct sock *sk) ++{ ++ sk->sk_lock.owned = 0; ++} ++ + /* + * Macro so as to not evaluate some arguments when + * lockdep is not enabled. +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -2309,10 +2309,13 @@ void release_sock(struct sock *sk) + if (sk->sk_backlog.tail) + __release_sock(sk); + ++ /* Warning : release_cb() might need to release sk ownership, ++ * ie call sock_release_ownership(sk) before us. ++ */ + if (sk->sk_prot->release_cb) + sk->sk_prot->release_cb(sk); + +- sk->sk_lock.owned = 0; ++ sock_release_ownership(sk); + if (waitqueue_active(&sk->sk_lock.wq)) + wake_up(&sk->sk_lock.wq); + spin_unlock_bh(&sk->sk_lock.slock); +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -755,6 +755,17 @@ void tcp_release_cb(struct sock *sk) + if (flags & (1UL << TCP_TSQ_DEFERRED)) + tcp_tsq_handler(sk); + ++ /* Here begins the tricky part : ++ * We are called from release_sock() with : ++ * 1) BH disabled ++ * 2) sk_lock.slock spinlock held ++ * 3) socket owned by us (sk->sk_lock.owned == 1) ++ * ++ * But following code is meant to be called from BH handlers, ++ * so we should keep BH disabled, but early release socket ownership ++ */ ++ sock_release_ownership(sk); ++ + if (flags & (1UL << TCP_WRITE_TIMER_DEFERRED)) { + tcp_write_timer_handler(sk); + __sock_put(sk); diff --git a/queue-3.10/tg3-do-not-include-vlan-acceleration-features-in-vlan_features.patch b/queue-3.10/tg3-do-not-include-vlan-acceleration-features-in-vlan_features.patch new file mode 100644 index 00000000000..e63f76b979b --- /dev/null +++ b/queue-3.10/tg3-do-not-include-vlan-acceleration-features-in-vlan_features.patch @@ -0,0 +1,44 @@ +From foo@baz Fri Apr 11 08:46:36 PDT 2014 +From: Vlad Yasevich +Date: Mon, 24 Mar 2014 17:52:12 -0400 +Subject: tg3: Do not include vlan acceleration features in vlan_features + +From: Vlad Yasevich + +[ Upstream commit 51dfe7b944998eaeb2b34d314f3a6b16a5fd621b ] + +Including hardware acceleration features in vlan_features breaks +stacked vlans (Q-in-Q) by marking the bottom vlan interface as +capable of acceleration. This causes one of the tags to be lost +and the packets are sent with a sing vlan header. + +CC: Nithin Nayak Sujir +CC: Michael Chan +Signed-off-by: Vlad Yasevich +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/broadcom/tg3.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/drivers/net/ethernet/broadcom/tg3.c ++++ b/drivers/net/ethernet/broadcom/tg3.c +@@ -17308,8 +17308,6 @@ static int tg3_init_one(struct pci_dev * + + tg3_init_bufmgr_config(tp); + +- features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX; +- + /* 5700 B0 chips do not support checksumming correctly due + * to hardware bugs. + */ +@@ -17341,7 +17339,8 @@ static int tg3_init_one(struct pci_dev * + features |= NETIF_F_TSO_ECN; + } + +- dev->features |= features; ++ dev->features |= features | NETIF_F_HW_VLAN_CTAG_TX | ++ NETIF_F_HW_VLAN_CTAG_RX; + dev->vlan_features |= features; + + /* diff --git a/queue-3.10/usbnet-include-wait-queue-head-in-device-structure.patch b/queue-3.10/usbnet-include-wait-queue-head-in-device-structure.patch new file mode 100644 index 00000000000..9491891ce24 --- /dev/null +++ b/queue-3.10/usbnet-include-wait-queue-head-in-device-structure.patch @@ -0,0 +1,142 @@ +From foo@baz Fri Apr 11 08:46:36 PDT 2014 +From: Oliver Neukum +Date: Wed, 26 Mar 2014 14:32:51 +0100 +Subject: usbnet: include wait queue head in device structure + +From: Oliver Neukum + +[ Upstream commit 14a0d635d18d0fb552dcc979d6d25106e6541f2e ] + +This fixes a race which happens by freeing an object on the stack. +Quoting Julius: +> The issue is +> that it calls usbnet_terminate_urbs() before that, which temporarily +> installs a waitqueue in dev->wait in order to be able to wait on the +> tasklet to run and finish up some queues. The waiting itself looks +> okay, but the access to 'dev->wait' is totally unprotected and can +> race arbitrarily. I think in this case usbnet_bh() managed to succeed +> it's dev->wait check just before usbnet_terminate_urbs() sets it back +> to NULL. The latter then finishes and the waitqueue_t structure on its +> stack gets overwritten by other functions halfway through the +> wake_up() call in usbnet_bh(). + +The fix is to just not allocate the data structure on the stack. +As dev->wait is abused as a flag it also takes a runtime PM change +to fix this bug. + +Signed-off-by: Oliver Neukum +Reported-by: Grant Grundler +Tested-by: Grant Grundler +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/usb/usbnet.c | 33 +++++++++++++++++++-------------- + include/linux/usb/usbnet.h | 2 +- + 2 files changed, 20 insertions(+), 15 deletions(-) + +--- a/drivers/net/usb/usbnet.c ++++ b/drivers/net/usb/usbnet.c +@@ -727,14 +727,12 @@ EXPORT_SYMBOL_GPL(usbnet_unlink_rx_urbs) + // precondition: never called in_interrupt + static void usbnet_terminate_urbs(struct usbnet *dev) + { +- DECLARE_WAIT_QUEUE_HEAD_ONSTACK(unlink_wakeup); + DECLARE_WAITQUEUE(wait, current); + int temp; + + /* ensure there are no more active urbs */ +- add_wait_queue(&unlink_wakeup, &wait); ++ add_wait_queue(&dev->wait, &wait); + set_current_state(TASK_UNINTERRUPTIBLE); +- dev->wait = &unlink_wakeup; + temp = unlink_urbs(dev, &dev->txq) + + unlink_urbs(dev, &dev->rxq); + +@@ -748,15 +746,14 @@ static void usbnet_terminate_urbs(struct + "waited for %d urb completions\n", temp); + } + set_current_state(TASK_RUNNING); +- dev->wait = NULL; +- remove_wait_queue(&unlink_wakeup, &wait); ++ remove_wait_queue(&dev->wait, &wait); + } + + int usbnet_stop (struct net_device *net) + { + struct usbnet *dev = netdev_priv(net); + struct driver_info *info = dev->driver_info; +- int retval; ++ int retval, pm; + + clear_bit(EVENT_DEV_OPEN, &dev->flags); + netif_stop_queue (net); +@@ -766,6 +763,8 @@ int usbnet_stop (struct net_device *net) + net->stats.rx_packets, net->stats.tx_packets, + net->stats.rx_errors, net->stats.tx_errors); + ++ /* to not race resume */ ++ pm = usb_autopm_get_interface(dev->intf); + /* allow minidriver to stop correctly (wireless devices to turn off + * radio etc) */ + if (info->stop) { +@@ -792,6 +791,9 @@ int usbnet_stop (struct net_device *net) + dev->flags = 0; + del_timer_sync (&dev->delay); + tasklet_kill (&dev->bh); ++ if (!pm) ++ usb_autopm_put_interface(dev->intf); ++ + if (info->manage_power && + !test_and_clear_bit(EVENT_NO_RUNTIME_PM, &dev->flags)) + info->manage_power(dev, 0); +@@ -1360,11 +1362,12 @@ static void usbnet_bh (unsigned long par + /* restart RX again after disabling due to high error rate */ + clear_bit(EVENT_RX_KILL, &dev->flags); + +- // waiting for all pending urbs to complete? +- if (dev->wait) { +- if ((dev->txq.qlen + dev->rxq.qlen + dev->done.qlen) == 0) { +- wake_up (dev->wait); +- } ++ /* waiting for all pending urbs to complete? ++ * only then can we forgo submitting anew ++ */ ++ if (waitqueue_active(&dev->wait)) { ++ if (dev->txq.qlen + dev->rxq.qlen + dev->done.qlen == 0) ++ wake_up_all(&dev->wait); + + // or are we maybe short a few urbs? + } else if (netif_running (dev->net) && +@@ -1502,6 +1505,7 @@ usbnet_probe (struct usb_interface *udev + dev->driver_name = name; + dev->msg_enable = netif_msg_init (msg_level, NETIF_MSG_DRV + | NETIF_MSG_PROBE | NETIF_MSG_LINK); ++ init_waitqueue_head(&dev->wait); + skb_queue_head_init (&dev->rxq); + skb_queue_head_init (&dev->txq); + skb_queue_head_init (&dev->done); +@@ -1694,9 +1698,10 @@ int usbnet_resume (struct usb_interface + spin_unlock_irq(&dev->txq.lock); + + if (test_bit(EVENT_DEV_OPEN, &dev->flags)) { +- /* handle remote wakeup ASAP */ +- if (!dev->wait && +- netif_device_present(dev->net) && ++ /* handle remote wakeup ASAP ++ * we cannot race against stop ++ */ ++ if (netif_device_present(dev->net) && + !timer_pending(&dev->delay) && + !test_bit(EVENT_RX_HALT, &dev->flags)) + rx_alloc_submit(dev, GFP_NOIO); +--- a/include/linux/usb/usbnet.h ++++ b/include/linux/usb/usbnet.h +@@ -30,7 +30,7 @@ struct usbnet { + struct driver_info *driver_info; + const char *driver_name; + void *driver_priv; +- wait_queue_head_t *wait; ++ wait_queue_head_t wait; + struct mutex phy_mutex; + unsigned char suspend_count; + unsigned char pkt_cnt, pkt_err; diff --git a/queue-3.10/vhost-fix-total-length-when-packets-are-too-short.patch b/queue-3.10/vhost-fix-total-length-when-packets-are-too-short.patch new file mode 100644 index 00000000000..967f81c85e8 --- /dev/null +++ b/queue-3.10/vhost-fix-total-length-when-packets-are-too-short.patch @@ -0,0 +1,63 @@ +From foo@baz Fri Apr 11 08:46:36 PDT 2014 +From: "Michael S. Tsirkin" +Date: Thu, 27 Mar 2014 12:00:26 +0200 +Subject: vhost: fix total length when packets are too short + +From: "Michael S. Tsirkin" + +[ Upstream commit d8316f3991d207fe32881a9ac20241be8fa2bad0 ] + +When mergeable buffers are disabled, and the +incoming packet is too large for the rx buffer, +get_rx_bufs returns success. + +This was intentional in order for make recvmsg +truncate the packet and then handle_rx would +detect err != sock_len and drop it. + +Unfortunately we pass the original sock_len to +recvmsg - which means we use parts of iov not fully +validated. + +Fix this up by detecting this overrun and doing packet drop +immediately. + +CVE-2014-0077 + +Signed-off-by: Michael S. Tsirkin +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/vhost/net.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +--- a/drivers/vhost/net.c ++++ b/drivers/vhost/net.c +@@ -540,6 +540,12 @@ static int get_rx_bufs(struct vhost_virt + *iovcount = seg; + if (unlikely(log)) + *log_num = nlogs; ++ ++ /* Detect overrun */ ++ if (unlikely(datalen > 0)) { ++ r = UIO_MAXIOV + 1; ++ goto err; ++ } + return headcount; + err: + vhost_discard_vq_desc(vq, headcount); +@@ -595,6 +601,14 @@ static void handle_rx(struct vhost_net * + /* On error, stop handling until the next kick. */ + if (unlikely(headcount < 0)) + break; ++ /* On overrun, truncate and discard */ ++ if (unlikely(headcount > UIO_MAXIOV)) { ++ msg.msg_iovlen = 1; ++ err = sock->ops->recvmsg(NULL, sock, &msg, ++ 1, MSG_DONTWAIT | MSG_TRUNC); ++ pr_debug("Discarded rx packet: len %zd\n", sock_len); ++ continue; ++ } + /* OK, now we need to know about added descriptors. */ + if (!headcount) { + if (unlikely(vhost_enable_notify(&net->dev, vq))) { diff --git a/queue-3.10/vhost-validate-vhost_get_vq_desc-return-value.patch b/queue-3.10/vhost-validate-vhost_get_vq_desc-return-value.patch new file mode 100644 index 00000000000..f501c43666f --- /dev/null +++ b/queue-3.10/vhost-validate-vhost_get_vq_desc-return-value.patch @@ -0,0 +1,44 @@ +From foo@baz Fri Apr 11 08:46:36 PDT 2014 +From: "Michael S. Tsirkin" +Date: Thu, 27 Mar 2014 12:53:37 +0200 +Subject: vhost: validate vhost_get_vq_desc return value + +From: "Michael S. Tsirkin" + +[ Upstream commit a39ee449f96a2cd44ce056d8a0a112211a9b1a1f ] + +vhost fails to validate negative error code +from vhost_get_vq_desc causing +a crash: we are using -EFAULT which is 0xfffffff2 +as vector size, which exceeds the allocated size. + +The code in question was introduced in commit +8dd014adfea6f173c1ef6378f7e5e7924866c923 + vhost-net: mergeable buffers support + +CVE-2014-0055 + +Signed-off-by: Michael S. Tsirkin +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/vhost/net.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/vhost/net.c ++++ b/drivers/vhost/net.c +@@ -513,9 +513,13 @@ static int get_rx_bufs(struct vhost_virt + r = -ENOBUFS; + goto err; + } +- d = vhost_get_vq_desc(vq->dev, vq, vq->iov + seg, ++ r = vhost_get_vq_desc(vq->dev, vq, vq->iov + seg, + ARRAY_SIZE(vq->iov) - seg, &out, + &in, log, log_num); ++ if (unlikely(r < 0)) ++ goto err; ++ ++ d = r; + if (d == vq->num) { + r = 0; + goto err; diff --git a/queue-3.10/vlan-set-correct-source-mac-address-with-tx-vlan-offload-enabled.patch b/queue-3.10/vlan-set-correct-source-mac-address-with-tx-vlan-offload-enabled.patch new file mode 100644 index 00000000000..0746f5f4ff8 --- /dev/null +++ b/queue-3.10/vlan-set-correct-source-mac-address-with-tx-vlan-offload-enabled.patch @@ -0,0 +1,41 @@ +From foo@baz Fri Apr 11 08:46:36 PDT 2014 +From: Peter Boström +Date: Mon, 10 Mar 2014 16:17:15 +0100 +Subject: vlan: Set correct source MAC address with TX VLAN offload enabled +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Peter Boström + +[ Upstream commit dd38743b4cc2f86be250eaf156cf113ba3dd531a ] + +With TX VLAN offload enabled the source MAC address for frames sent using the +VLAN interface is currently set to the address of the real interface. This is +wrong since the VLAN interface may be configured with a different address. + +The bug was introduced in commit 2205369a314e12fcec4781cc73ac9c08fc2b47de +("vlan: Fix header ops passthru when doing TX VLAN offload."). + +This patch sets the source address before calling the create function of the +real interface. + +Signed-off-by: Peter Boström +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/8021q/vlan_dev.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/8021q/vlan_dev.c ++++ b/net/8021q/vlan_dev.c +@@ -557,6 +557,9 @@ static int vlan_passthru_hard_header(str + struct vlan_dev_priv *vlan = vlan_dev_priv(dev); + struct net_device *real_dev = vlan->real_dev; + ++ if (saddr == NULL) ++ saddr = dev->dev_addr; ++ + return dev_hard_header(skb, real_dev, type, daddr, saddr, len); + } + diff --git a/queue-3.10/vlan-set-hard_header_len-according-to-available-acceleration.patch b/queue-3.10/vlan-set-hard_header_len-according-to-available-acceleration.patch new file mode 100644 index 00000000000..66a26cc0ed0 --- /dev/null +++ b/queue-3.10/vlan-set-hard_header_len-according-to-available-acceleration.patch @@ -0,0 +1,52 @@ +From foo@baz Fri Apr 11 08:46:36 PDT 2014 +From: Vlad Yasevich +Date: Wed, 26 Mar 2014 11:47:56 -0400 +Subject: vlan: Set hard_header_len according to available acceleration + +From: Vlad Yasevich + +[ Upstream commit fc0d48b8fb449ca007b2057328abf736cb516168 ] + +Currently, if the card supports CTAG acceleration we do not +account for the vlan header even if we are configuring an +8021AD vlan. This may not be best since we'll do software +tagging for 8021AD which will cause data copy on skb head expansion +Configure the length based on available hw offload capabilities and +vlan protocol. + +CC: Patrick McHardy +Signed-off-by: Vlad Yasevich +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/8021q/vlan.c | 4 +++- + net/8021q/vlan_dev.c | 3 ++- + 2 files changed, 5 insertions(+), 2 deletions(-) + +--- a/net/8021q/vlan.c ++++ b/net/8021q/vlan.c +@@ -305,9 +305,11 @@ static void vlan_sync_address(struct net + static void vlan_transfer_features(struct net_device *dev, + struct net_device *vlandev) + { ++ struct vlan_dev_priv *vlan = vlan_dev_priv(vlandev); ++ + vlandev->gso_max_size = dev->gso_max_size; + +- if (dev->features & NETIF_F_HW_VLAN_CTAG_TX) ++ if (vlan_hw_offload_capable(dev->features, vlan->vlan_proto)) + vlandev->hard_header_len = dev->hard_header_len; + else + vlandev->hard_header_len = dev->hard_header_len + VLAN_HLEN; +--- a/net/8021q/vlan_dev.c ++++ b/net/8021q/vlan_dev.c +@@ -611,7 +611,8 @@ static int vlan_dev_init(struct net_devi + #endif + + dev->needed_headroom = real_dev->needed_headroom; +- if (real_dev->features & NETIF_F_HW_VLAN_CTAG_TX) { ++ if (vlan_hw_offload_capable(real_dev->features, ++ vlan_dev_priv(dev)->vlan_proto)) { + dev->header_ops = &vlan_passthru_header_ops; + dev->hard_header_len = real_dev->hard_header_len; + } else { diff --git a/queue-3.10/vxlan-fix-potential-null-dereference-in-arp_reduce.patch b/queue-3.10/vxlan-fix-potential-null-dereference-in-arp_reduce.patch new file mode 100644 index 00000000000..82862292f50 --- /dev/null +++ b/queue-3.10/vxlan-fix-potential-null-dereference-in-arp_reduce.patch @@ -0,0 +1,33 @@ +From foo@baz Fri Apr 11 08:46:36 PDT 2014 +From: David Stevens +Date: Tue, 18 Mar 2014 12:32:29 -0400 +Subject: vxlan: fix potential NULL dereference in arp_reduce() + +From: David Stevens + +[ Upstream commit 7346135dcd3f9b57f30a5512094848c678d7143e ] + +This patch fixes a NULL pointer dereference in the event of an +skb allocation failure in arp_reduce(). + +Signed-Off-By: David L Stevens +Acked-by: Cong Wang + +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/vxlan.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/net/vxlan.c ++++ b/drivers/net/vxlan.c +@@ -845,6 +845,9 @@ static int arp_reduce(struct net_device + + neigh_release(n); + ++ if (reply == NULL) ++ goto out; ++ + skb_reset_mac_header(reply); + __skb_pull(reply, skb_network_offset(reply)); + reply->ip_summed = CHECKSUM_UNNECESSARY; diff --git a/queue-3.10/xen-netback-remove-pointless-clause-from-if-statement.patch b/queue-3.10/xen-netback-remove-pointless-clause-from-if-statement.patch new file mode 100644 index 00000000000..4fd83821328 --- /dev/null +++ b/queue-3.10/xen-netback-remove-pointless-clause-from-if-statement.patch @@ -0,0 +1,39 @@ +From foo@baz Fri Apr 11 08:46:36 PDT 2014 +From: Paul Durrant +Date: Fri, 28 Mar 2014 11:39:05 +0000 +Subject: xen-netback: remove pointless clause from if statement + +From: Paul Durrant + +[ Upstream commit 0576eddf24df716d8570ef8ca11452a9f98eaab2 ] + +This patch removes a test in start_new_rx_buffer() that checks whether +a copy operation is less than MAX_BUFFER_OFFSET in length, since +MAX_BUFFER_OFFSET is defined to be PAGE_SIZE and the only caller of +start_new_rx_buffer() already limits copy operations to PAGE_SIZE or less. + +Signed-off-by: Paul Durrant +Cc: Ian Campbell +Cc: Wei Liu +Cc: Sander Eikelenboom +Reported-By: Sander Eikelenboom +Tested-By: Sander Eikelenboom +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/xen-netback/netback.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/xen-netback/netback.c ++++ b/drivers/net/xen-netback/netback.c +@@ -347,8 +347,8 @@ static bool start_new_rx_buffer(int offs + * into multiple copies tend to give large frags their + * own buffers as before. + */ +- if ((offset + size > MAX_BUFFER_OFFSET) && +- (size <= MAX_BUFFER_OFFSET) && offset && !head) ++ BUG_ON(size > MAX_BUFFER_OFFSET); ++ if ((offset + size > MAX_BUFFER_OFFSET) && offset && !head) + return true; + + return false; -- 2.47.3