From: Greg Kroah-Hartman Date: Mon, 7 Oct 2013 02:04:27 +0000 (-0700) Subject: 3.10-stable patches X-Git-Tag: v3.0.100~22 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5520028ec804f5c9c6c7835a41767cb20643c073;p=thirdparty%2Fkernel%2Fstable-queue.git 3.10-stable patches added patches: bonding-fix-broken-promiscuity-reference-counting-issue.patch bridge-clamp-forward_delay-when-enabling-stp.patch bridge-fix-null-pointer-deref-of-br_port_get_rcu.patch bridge-use-br_port_get_rtnl-within-rtnl-lock.patch caif-add-missing-braces-to-multiline-if-in-cfctrl_linkup_request.patch dm9601-fix-iff_allmulti-handling.patch ip6tnl-allow-to-use-rtnl-ops-on-fb-tunnel.patch ip6_tunnels-raddr-and-laddr-are-inverted-in-nl-msg.patch ip-generate-unique-ip-identificator-if-local-fragmentation-is-allowed.patch ip_tunnel-fix-a-memory-corruption-in-ip_tunnel_xmit.patch ip-use-ip_hdr-in-__ip_make_skb-to-retrieve-ip-header.patch ipv4-igmp-use-in_dev_put-in-timer-handlers-instead-of-__in_dev_put.patch ipv6-exthdrs-accept-tlv-which-includes-only-padding.patch ipv6-gre-correct-calculation-of-max_headroom.patch ipv6-mcast-use-in6_dev_put-in-timer-handlers-instead-of-__in6_dev_put.patch ipv6-nat-do-not-drop-dnated-6to4-6rd-packets.patch ipv6-udp-packets-following-an-ufo-enqueued-packet-need-also-be-handled-by-ufo.patch ll_temac-reset-dma-descriptors-indexes-on-ndo_open.patch net-dccp-do-not-report-icmp-redirects-to-user-space.patch net-fib-fib6_add-fix-potential-null-pointer-dereference.patch net-fix-multiqueue-selection.patch net-flow_dissector-fix-thoff-for-ipproto_ah.patch net-net_secret-should-not-depend-on-tcp.patch netpoll-fix-null-pointer-dereference-in-netpoll_cleanup.patch netpoll-should-handle-eth_p_arp-other-than-eth_p_ip-in-netpoll_neigh_reply.patch net_sched-htb-fix-a-typo-in-htb_change_class.patch net-sctp-fix-bug-in-sctp_poll-for-sock_select_err_queue.patch net-sctp-fix-ipv6-ipsec-encryption-bug-in-sctp_v6_xmit.patch net-sctp-fix-smatch-warning-in-sctp_send_asconf_del_ip.patch net-sctp-rfc4443-do-not-report-icmp-redirects-to-user-space.patch r8169-enforce-rx_multi_en-for-the-8168f.patch resubmit-bridge-fix-message_age_timer-calculation.patch sit-allow-to-use-rtnl-ops-on-fb-tunnel.patch tcp-add-missing-braces-to-do_tcp_setsockopt.patch tuntap-correctly-handle-error-in-tun_set_iff.patch via-rhine-fix-vlan-priority-field-pcp-ieee-802.1p.patch xen-netback-count-number-required-slots-for-an-skb-more-carefully.patch --- diff --git a/queue-3.10/bonding-fix-broken-promiscuity-reference-counting-issue.patch b/queue-3.10/bonding-fix-broken-promiscuity-reference-counting-issue.patch new file mode 100644 index 00000000000..6546473a83d --- /dev/null +++ b/queue-3.10/bonding-fix-broken-promiscuity-reference-counting-issue.patch @@ -0,0 +1,77 @@ +From ccba889ea82e28473e76d70dfb123dd100929282 Mon Sep 17 00:00:00 2001 +From: Neil Horman +Date: Fri, 27 Sep 2013 12:22:15 -0400 +Subject: bonding: Fix broken promiscuity reference counting issue + +From: Neil Horman + +[ Upstream commit 5a0068deb611109c5ba77358be533f763f395ee4 ] + +Recently grabbed this report: +https://bugzilla.redhat.com/show_bug.cgi?id=1005567 + +Of an issue in which the bonding driver, with an attached vlan encountered the +following errors when bond0 was taken down and back up: + +dummy1: promiscuity touches roof, set promiscuity failed. promiscuity feature of +device might be broken. + +The error occurs because, during __bond_release_one, if we release our last +slave, we take on a random mac address and issue a NETDEV_CHANGEADDR +notification. With an attached vlan, the vlan may see that the vlan and bond +mac address were in sync, but no longer are. This triggers a call to dev_uc_add +and dev_set_rx_mode, which enables IFF_PROMISC on the bond device. Then, when +we complete __bond_release_one, we use the current state of the bond flags to +determine if we should decrement the promiscuity of the releasing slave. But +since the bond changed promiscuity state during the release operation, we +incorrectly decrement the slave promisc count when it wasn't in promiscuous mode +to begin with, causing the above error + +Fix is pretty simple, just cache the bonding flags at the start of the function +and use those when determining the need to set promiscuity. + +This is also needed for the ALLMULTI flag + +Reported-by: Mark Wu +CC: Jay Vosburgh +CC: Andy Gospodarek +CC: Mark Wu +CC: "David S. Miller" +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/bonding/bond_main.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -1991,6 +1991,7 @@ static int __bond_release_one(struct net + struct bonding *bond = netdev_priv(bond_dev); + struct slave *slave, *oldcurrent; + struct sockaddr addr; ++ int old_flags = bond_dev->flags; + netdev_features_t old_features = bond_dev->features; + + /* slave is not a slave or master is not master of this slave */ +@@ -2123,12 +2124,18 @@ static int __bond_release_one(struct net + * already taken care of above when we detached the slave + */ + if (!USES_PRIMARY(bond->params.mode)) { +- /* unset promiscuity level from slave */ +- if (bond_dev->flags & IFF_PROMISC) ++ /* unset promiscuity level from slave ++ * NOTE: The NETDEV_CHANGEADDR call above may change the value ++ * of the IFF_PROMISC flag in the bond_dev, but we need the ++ * value of that flag before that change, as that was the value ++ * when this slave was attached, so we cache at the start of the ++ * function and use it here. Same goes for ALLMULTI below ++ */ ++ if (old_flags & IFF_PROMISC) + dev_set_promiscuity(slave_dev, -1); + + /* unset allmulti level from slave */ +- if (bond_dev->flags & IFF_ALLMULTI) ++ if (old_flags & IFF_ALLMULTI) + dev_set_allmulti(slave_dev, -1); + + /* flush master's mc_list from slave */ diff --git a/queue-3.10/bridge-clamp-forward_delay-when-enabling-stp.patch b/queue-3.10/bridge-clamp-forward_delay-when-enabling-stp.patch new file mode 100644 index 00000000000..c17fc1ec5df --- /dev/null +++ b/queue-3.10/bridge-clamp-forward_delay-when-enabling-stp.patch @@ -0,0 +1,106 @@ +From 3a1928f60af201163037ab9b022e4aae2c6bc83b Mon Sep 17 00:00:00 2001 +From: Herbert Xu +Date: Thu, 12 Sep 2013 17:12:05 +1000 +Subject: bridge: Clamp forward_delay when enabling STP + +From: Herbert Xu + +[ Upstream commit be4f154d5ef0ca147ab6bcd38857a774133f5450 ] + +At some point limits were added to forward_delay. However, the +limits are only enforced when STP is enabled. This created a +scenario where you could have a value outside the allowed range +while STP is disabled, which then stuck around even after STP +is enabled. + +This patch fixes this by clamping the value when we enable STP. + +I had to move the locking around a bit to ensure that there is +no window where someone could insert a value outside the range +while we're in the middle of enabling STP. + +Signed-off-by: Herbert Xu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/bridge/br_private.h | 1 + + net/bridge/br_stp.c | 21 +++++++++++++++------ + net/bridge/br_stp_if.c | 12 ++++++++++-- + 3 files changed, 26 insertions(+), 8 deletions(-) + +--- a/net/bridge/br_private.h ++++ b/net/bridge/br_private.h +@@ -714,6 +714,7 @@ extern struct net_bridge_port *br_get_po + extern void br_init_port(struct net_bridge_port *p); + extern void br_become_designated_port(struct net_bridge_port *p); + ++extern void __br_set_forward_delay(struct net_bridge *br, unsigned long t); + extern int br_set_forward_delay(struct net_bridge *br, unsigned long x); + extern int br_set_hello_time(struct net_bridge *br, unsigned long x); + extern int br_set_max_age(struct net_bridge *br, unsigned long x); +--- a/net/bridge/br_stp.c ++++ b/net/bridge/br_stp.c +@@ -544,18 +544,27 @@ int br_set_max_age(struct net_bridge *br + + } + ++void __br_set_forward_delay(struct net_bridge *br, unsigned long t) ++{ ++ br->bridge_forward_delay = t; ++ if (br_is_root_bridge(br)) ++ br->forward_delay = br->bridge_forward_delay; ++} ++ + int br_set_forward_delay(struct net_bridge *br, unsigned long val) + { + unsigned long t = clock_t_to_jiffies(val); ++ int err = -ERANGE; + ++ spin_lock_bh(&br->lock); + if (br->stp_enabled != BR_NO_STP && + (t < BR_MIN_FORWARD_DELAY || t > BR_MAX_FORWARD_DELAY)) +- return -ERANGE; ++ goto unlock; + +- spin_lock_bh(&br->lock); +- br->bridge_forward_delay = t; +- if (br_is_root_bridge(br)) +- br->forward_delay = br->bridge_forward_delay; ++ __br_set_forward_delay(br, t); ++ err = 0; ++ ++unlock: + spin_unlock_bh(&br->lock); +- return 0; ++ return err; + } +--- a/net/bridge/br_stp_if.c ++++ b/net/bridge/br_stp_if.c +@@ -129,6 +129,14 @@ static void br_stp_start(struct net_brid + char *envp[] = { NULL }; + + r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC); ++ ++ spin_lock_bh(&br->lock); ++ ++ if (br->bridge_forward_delay < BR_MIN_FORWARD_DELAY) ++ __br_set_forward_delay(br, BR_MIN_FORWARD_DELAY); ++ else if (br->bridge_forward_delay < BR_MAX_FORWARD_DELAY) ++ __br_set_forward_delay(br, BR_MAX_FORWARD_DELAY); ++ + if (r == 0) { + br->stp_enabled = BR_USER_STP; + br_debug(br, "userspace STP started\n"); +@@ -137,10 +145,10 @@ static void br_stp_start(struct net_brid + br_debug(br, "using kernel STP\n"); + + /* To start timers on any ports left in blocking */ +- spin_lock_bh(&br->lock); + br_port_state_selection(br); +- spin_unlock_bh(&br->lock); + } ++ ++ spin_unlock_bh(&br->lock); + } + + static void br_stp_stop(struct net_bridge *br) diff --git a/queue-3.10/bridge-fix-null-pointer-deref-of-br_port_get_rcu.patch b/queue-3.10/bridge-fix-null-pointer-deref-of-br_port_get_rcu.patch new file mode 100644 index 00000000000..b87612f5540 --- /dev/null +++ b/queue-3.10/bridge-fix-null-pointer-deref-of-br_port_get_rcu.patch @@ -0,0 +1,47 @@ +From 86496b0a3f001d1a5fd3dd30dcee81c6b06a23eb Mon Sep 17 00:00:00 2001 +From: Hong Zhiguo +Date: Sat, 14 Sep 2013 22:42:28 +0800 +Subject: bridge: fix NULL pointer deref of br_port_get_rcu + +From: Hong Zhiguo + +[ Upstream commit 716ec052d2280d511e10e90ad54a86f5b5d4dcc2 ] + +The NULL deref happens when br_handle_frame is called between these +2 lines of del_nbp: + dev->priv_flags &= ~IFF_BRIDGE_PORT; + /* --> br_handle_frame is called at this time */ + netdev_rx_handler_unregister(dev); + +In br_handle_frame the return of br_port_get_rcu(dev) is dereferenced +without check but br_port_get_rcu(dev) returns NULL if: + !(dev->priv_flags & IFF_BRIDGE_PORT) + +Eric Dumazet pointed out the testing of IFF_BRIDGE_PORT is not necessary +here since we're in rcu_read_lock and we have synchronize_net() in +netdev_rx_handler_unregister. So remove the testing of IFF_BRIDGE_PORT +and by the previous patch, make sure br_port_get_rcu is called in +bridging code. + +Signed-off-by: Hong Zhiguo +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/bridge/br_private.h | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +--- a/net/bridge/br_private.h ++++ b/net/bridge/br_private.h +@@ -183,10 +183,7 @@ struct net_bridge_port + + static inline struct net_bridge_port *br_port_get_rcu(const struct net_device *dev) + { +- struct net_bridge_port *port = +- rcu_dereference_rtnl(dev->rx_handler_data); +- +- return br_port_exists(dev) ? port : NULL; ++ return rcu_dereference(dev->rx_handler_data); + } + + static inline struct net_bridge_port *br_port_get_rtnl(const struct net_device *dev) diff --git a/queue-3.10/bridge-use-br_port_get_rtnl-within-rtnl-lock.patch b/queue-3.10/bridge-use-br_port_get_rtnl-within-rtnl-lock.patch new file mode 100644 index 00000000000..d027fa06a5d --- /dev/null +++ b/queue-3.10/bridge-use-br_port_get_rtnl-within-rtnl-lock.patch @@ -0,0 +1,52 @@ +From 25c2d9bb8b2f8a083c2c2bc197ad3df301f9b674 Mon Sep 17 00:00:00 2001 +From: Hong Zhiguo +Date: Sat, 14 Sep 2013 22:42:27 +0800 +Subject: bridge: use br_port_get_rtnl within rtnl lock + +From: Hong Zhiguo + +[ Upstream commit 1fb1754a8c70d69ab480763c423e0a74369c4a67 ] + +current br_port_get_rcu is problematic in bridging path +(NULL deref). Change these calls in netlink path first. + +Signed-off-by: Hong Zhiguo +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/bridge/br_netlink.c | 4 ++-- + net/bridge/br_private.h | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +--- a/net/bridge/br_netlink.c ++++ b/net/bridge/br_netlink.c +@@ -203,7 +203,7 @@ int br_getlink(struct sk_buff *skb, u32 + struct net_device *dev, u32 filter_mask) + { + int err = 0; +- struct net_bridge_port *port = br_port_get_rcu(dev); ++ struct net_bridge_port *port = br_port_get_rtnl(dev); + + /* not a bridge port and */ + if (!port && !(filter_mask & RTEXT_FILTER_BRVLAN)) +@@ -443,7 +443,7 @@ static size_t br_get_link_af_size(const + struct net_port_vlans *pv; + + if (br_port_exists(dev)) +- pv = nbp_get_vlan_info(br_port_get_rcu(dev)); ++ pv = nbp_get_vlan_info(br_port_get_rtnl(dev)); + else if (dev->priv_flags & IFF_EBRIDGE) + pv = br_get_vlan_info((struct net_bridge *)netdev_priv(dev)); + else +--- a/net/bridge/br_private.h ++++ b/net/bridge/br_private.h +@@ -189,7 +189,7 @@ static inline struct net_bridge_port *br + return br_port_exists(dev) ? port : NULL; + } + +-static inline struct net_bridge_port *br_port_get_rtnl(struct net_device *dev) ++static inline struct net_bridge_port *br_port_get_rtnl(const struct net_device *dev) + { + return br_port_exists(dev) ? + rtnl_dereference(dev->rx_handler_data) : NULL; diff --git a/queue-3.10/caif-add-missing-braces-to-multiline-if-in-cfctrl_linkup_request.patch b/queue-3.10/caif-add-missing-braces-to-multiline-if-in-cfctrl_linkup_request.patch new file mode 100644 index 00000000000..d51b355b0eb --- /dev/null +++ b/queue-3.10/caif-add-missing-braces-to-multiline-if-in-cfctrl_linkup_request.patch @@ -0,0 +1,35 @@ +From dd2b73f2e768a8367f75609f28832eaee2e6bba8 Mon Sep 17 00:00:00 2001 +From: Dave Jones +Date: Thu, 5 Sep 2013 00:11:19 -0400 +Subject: caif: Add missing braces to multiline if in cfctrl_linkup_request + +From: Dave Jones + +[ Upstream commit 0c1db731bfcf3a9fd6c58132134f8b0f423552f0 ] + +The indentation here implies this was meant to be a multi-line if. + +Introduced several years back in commit c85c2951d4da1236e32f1858db418221e624aba5 +("caif: Handle dev_queue_xmit errors.") + +Signed-off-by: Dave Jones +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/caif/cfctrl.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/caif/cfctrl.c ++++ b/net/caif/cfctrl.c +@@ -293,9 +293,10 @@ int cfctrl_linkup_request(struct cflayer + + count = cfctrl_cancel_req(&cfctrl->serv.layer, + user_layer); +- if (count != 1) ++ if (count != 1) { + pr_err("Could not remove request (%d)", count); + return -ENODEV; ++ } + } + return 0; + } diff --git a/queue-3.10/dm9601-fix-iff_allmulti-handling.patch b/queue-3.10/dm9601-fix-iff_allmulti-handling.patch new file mode 100644 index 00000000000..ebb488a4380 --- /dev/null +++ b/queue-3.10/dm9601-fix-iff_allmulti-handling.patch @@ -0,0 +1,31 @@ +From f34adcc74a664e2c41a9f6bc2436a0cd37af78bd Mon Sep 17 00:00:00 2001 +From: Peter Korsgaard +Date: Mon, 30 Sep 2013 23:28:20 +0200 +Subject: dm9601: fix IFF_ALLMULTI handling + +From: Peter Korsgaard + +[ Upstream commit bf0ea6380724beb64f27a722dfc4b0edabff816e ] + +Pass-all-multicast is controlled by bit 3 in RX control, not bit 2 +(pass undersized frames). + +Reported-by: Joseph Chang +Signed-off-by: Peter Korsgaard +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/usb/dm9601.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/usb/dm9601.c ++++ b/drivers/net/usb/dm9601.c +@@ -303,7 +303,7 @@ static void dm9601_set_multicast(struct + rx_ctl |= 0x02; + } else if (net->flags & IFF_ALLMULTI || + netdev_mc_count(net) > DM_MAX_MCAST) { +- rx_ctl |= 0x04; ++ rx_ctl |= 0x08; + } else if (!netdev_mc_empty(net)) { + struct netdev_hw_addr *ha; + diff --git a/queue-3.10/ip-generate-unique-ip-identificator-if-local-fragmentation-is-allowed.patch b/queue-3.10/ip-generate-unique-ip-identificator-if-local-fragmentation-is-allowed.patch new file mode 100644 index 00000000000..89bf3d6d3c1 --- /dev/null +++ b/queue-3.10/ip-generate-unique-ip-identificator-if-local-fragmentation-is-allowed.patch @@ -0,0 +1,195 @@ +From 47a45c517a0cbd65efac3c995fc3af10fc445a3c Mon Sep 17 00:00:00 2001 +From: Ansis Atteka +Date: Wed, 18 Sep 2013 15:29:53 -0700 +Subject: ip: generate unique IP identificator if local fragmentation is allowed + +From: Ansis Atteka + +[ Upstream commit 703133de331a7a7df47f31fb9de51dc6f68a9de8 ] + +If local fragmentation is allowed, then ip_select_ident() and +ip_select_ident_more() need to generate unique IDs to ensure +correct defragmentation on the peer. + +For example, if IPsec (tunnel mode) has to encrypt large skbs +that have local_df bit set, then all IP fragments that belonged +to different ESP datagrams would have used the same identificator. +If one of these IP fragments would get lost or reordered, then +peer could possibly stitch together wrong IP fragments that did +not belong to the same datagram. This would lead to a packet loss +or data corruption. + +Signed-off-by: Ansis Atteka +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ppp/pptp.c | 2 +- + include/net/ip.h | 12 ++++++++---- + net/ipv4/igmp.c | 4 ++-- + net/ipv4/inetpeer.c | 4 ++-- + net/ipv4/ip_output.c | 6 +++--- + net/ipv4/ipmr.c | 2 +- + net/ipv4/raw.c | 2 +- + net/ipv4/xfrm4_mode_tunnel.c | 2 +- + net/ipv6/sit.c | 2 +- + net/netfilter/ipvs/ip_vs_xmit.c | 2 +- + 10 files changed, 21 insertions(+), 17 deletions(-) + +--- a/drivers/net/ppp/pptp.c ++++ b/drivers/net/ppp/pptp.c +@@ -281,7 +281,7 @@ static int pptp_xmit(struct ppp_channel + nf_reset(skb); + + skb->ip_summed = CHECKSUM_NONE; +- ip_select_ident(iph, &rt->dst, NULL); ++ ip_select_ident(skb, &rt->dst, NULL); + ip_send_check(iph); + + ip_local_out(skb); +--- a/include/net/ip.h ++++ b/include/net/ip.h +@@ -254,9 +254,11 @@ int ip_dont_fragment(struct sock *sk, st + + extern void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more); + +-static inline void ip_select_ident(struct iphdr *iph, struct dst_entry *dst, struct sock *sk) ++static inline void ip_select_ident(struct sk_buff *skb, struct dst_entry *dst, struct sock *sk) + { +- if (iph->frag_off & htons(IP_DF)) { ++ struct iphdr *iph = ip_hdr(skb); ++ ++ if ((iph->frag_off & htons(IP_DF)) && !skb->local_df) { + /* This is only to work around buggy Windows95/2000 + * VJ compression implementations. If the ID field + * does not change, they drop every other packet in +@@ -268,9 +270,11 @@ static inline void ip_select_ident(struc + __ip_select_ident(iph, dst, 0); + } + +-static inline void ip_select_ident_more(struct iphdr *iph, struct dst_entry *dst, struct sock *sk, int more) ++static inline void ip_select_ident_more(struct sk_buff *skb, struct dst_entry *dst, struct sock *sk, int more) + { +- if (iph->frag_off & htons(IP_DF)) { ++ struct iphdr *iph = ip_hdr(skb); ++ ++ if ((iph->frag_off & htons(IP_DF)) && !skb->local_df) { + if (sk && inet_sk(sk)->inet_daddr) { + iph->id = htons(inet_sk(sk)->inet_id); + inet_sk(sk)->inet_id += 1 + more; +--- a/net/ipv4/igmp.c ++++ b/net/ipv4/igmp.c +@@ -343,7 +343,7 @@ static struct sk_buff *igmpv3_newpack(st + pip->saddr = fl4.saddr; + pip->protocol = IPPROTO_IGMP; + pip->tot_len = 0; /* filled in later */ +- ip_select_ident(pip, &rt->dst, NULL); ++ ip_select_ident(skb, &rt->dst, NULL); + ((u8 *)&pip[1])[0] = IPOPT_RA; + ((u8 *)&pip[1])[1] = 4; + ((u8 *)&pip[1])[2] = 0; +@@ -687,7 +687,7 @@ static int igmp_send_report(struct in_de + iph->daddr = dst; + iph->saddr = fl4.saddr; + iph->protocol = IPPROTO_IGMP; +- ip_select_ident(iph, &rt->dst, NULL); ++ ip_select_ident(skb, &rt->dst, NULL); + ((u8 *)&iph[1])[0] = IPOPT_RA; + ((u8 *)&iph[1])[1] = 4; + ((u8 *)&iph[1])[2] = 0; +--- a/net/ipv4/inetpeer.c ++++ b/net/ipv4/inetpeer.c +@@ -32,8 +32,8 @@ + * At the moment of writing this notes identifier of IP packets is generated + * to be unpredictable using this code only for packets subjected + * (actually or potentially) to defragmentation. I.e. DF packets less than +- * PMTU in size uses a constant ID and do not use this code (see +- * ip_select_ident() in include/net/ip.h). ++ * PMTU in size when local fragmentation is disabled use a constant ID and do ++ * not use this code (see ip_select_ident() in include/net/ip.h). + * + * Route cache entries hold references to our nodes. + * New cache entries get references via lookup by destination IP address in +--- a/net/ipv4/ip_output.c ++++ b/net/ipv4/ip_output.c +@@ -148,7 +148,7 @@ int ip_build_and_send_pkt(struct sk_buff + iph->daddr = (opt && opt->opt.srr ? opt->opt.faddr : daddr); + iph->saddr = saddr; + iph->protocol = sk->sk_protocol; +- ip_select_ident(iph, &rt->dst, sk); ++ ip_select_ident(skb, &rt->dst, sk); + + if (opt && opt->opt.optlen) { + iph->ihl += opt->opt.optlen>>2; +@@ -394,7 +394,7 @@ packet_routed: + ip_options_build(skb, &inet_opt->opt, inet->inet_daddr, rt, 0); + } + +- ip_select_ident_more(iph, &rt->dst, sk, ++ ip_select_ident_more(skb, &rt->dst, sk, + (skb_shinfo(skb)->gso_segs ?: 1) - 1); + + skb->priority = sk->sk_priority; +@@ -1332,7 +1332,7 @@ struct sk_buff *__ip_make_skb(struct soc + iph->ttl = ttl; + iph->protocol = sk->sk_protocol; + ip_copy_addrs(iph, fl4); +- ip_select_ident(iph, &rt->dst, sk); ++ ip_select_ident(skb, &rt->dst, sk); + + if (opt) { + iph->ihl += opt->optlen>>2; +--- a/net/ipv4/ipmr.c ++++ b/net/ipv4/ipmr.c +@@ -1658,7 +1658,7 @@ static void ip_encap(struct sk_buff *skb + iph->protocol = IPPROTO_IPIP; + iph->ihl = 5; + iph->tot_len = htons(skb->len); +- ip_select_ident(iph, skb_dst(skb), NULL); ++ ip_select_ident(skb, skb_dst(skb), NULL); + ip_send_check(iph); + + memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); +--- a/net/ipv4/raw.c ++++ b/net/ipv4/raw.c +@@ -387,7 +387,7 @@ static int raw_send_hdrinc(struct sock * + iph->check = 0; + iph->tot_len = htons(length); + if (!iph->id) +- ip_select_ident(iph, &rt->dst, NULL); ++ ip_select_ident(skb, &rt->dst, NULL); + + iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); + } +--- a/net/ipv4/xfrm4_mode_tunnel.c ++++ b/net/ipv4/xfrm4_mode_tunnel.c +@@ -117,7 +117,7 @@ static int xfrm4_mode_tunnel_output(stru + + top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ? + 0 : (XFRM_MODE_SKB_CB(skb)->frag_off & htons(IP_DF)); +- ip_select_ident(top_iph, dst->child, NULL); ++ ip_select_ident(skb, dst->child, NULL); + + top_iph->ttl = ip4_dst_hoplimit(dst->child); + +--- a/net/ipv6/sit.c ++++ b/net/ipv6/sit.c +@@ -865,7 +865,7 @@ static netdev_tx_t ipip6_tunnel_xmit(str + iph->ttl = iph6->hop_limit; + + skb->ip_summed = CHECKSUM_NONE; +- ip_select_ident(iph, skb_dst(skb), NULL); ++ ip_select_ident(skb, skb_dst(skb), NULL); + iptunnel_xmit(skb, dev); + return NETDEV_TX_OK; + +--- a/net/netfilter/ipvs/ip_vs_xmit.c ++++ b/net/netfilter/ipvs/ip_vs_xmit.c +@@ -883,7 +883,7 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, s + iph->daddr = cp->daddr.ip; + iph->saddr = saddr; + iph->ttl = old_iph->ttl; +- ip_select_ident(iph, &rt->dst, NULL); ++ ip_select_ident(skb, &rt->dst, NULL); + + /* Another hack: avoid icmp_send in ip_fragment */ + skb->local_df = 1; diff --git a/queue-3.10/ip-use-ip_hdr-in-__ip_make_skb-to-retrieve-ip-header.patch b/queue-3.10/ip-use-ip_hdr-in-__ip_make_skb-to-retrieve-ip-header.patch new file mode 100644 index 00000000000..e935aec0c2d --- /dev/null +++ b/queue-3.10/ip-use-ip_hdr-in-__ip_make_skb-to-retrieve-ip-header.patch @@ -0,0 +1,30 @@ +From 082a8ea9f1c1a2f0f2c9631ce19ae6453a3aad6a Mon Sep 17 00:00:00 2001 +From: Ansis Atteka +Date: Wed, 18 Sep 2013 15:29:52 -0700 +Subject: ip: use ip_hdr() in __ip_make_skb() to retrieve IP header + +From: Ansis Atteka + +[ Upstream commit 749154aa56b57652a282cbde57a57abc278d1205 ] + +skb->data already points to IP header, but for the sake of +consistency we can also use ip_hdr() to retrieve it. + +Signed-off-by: Ansis Atteka +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/ip_output.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/ipv4/ip_output.c ++++ b/net/ipv4/ip_output.c +@@ -1324,7 +1324,7 @@ struct sk_buff *__ip_make_skb(struct soc + else + ttl = ip_select_ttl(inet, &rt->dst); + +- iph = (struct iphdr *)skb->data; ++ iph = ip_hdr(skb); + iph->version = 4; + iph->ihl = 5; + iph->tos = inet->tos; diff --git a/queue-3.10/ip6_tunnels-raddr-and-laddr-are-inverted-in-nl-msg.patch b/queue-3.10/ip6_tunnels-raddr-and-laddr-are-inverted-in-nl-msg.patch new file mode 100644 index 00000000000..96580b170a2 --- /dev/null +++ b/queue-3.10/ip6_tunnels-raddr-and-laddr-are-inverted-in-nl-msg.patch @@ -0,0 +1,35 @@ +From 13e99342571d74a61b70c91f17f8ecba56f4df0a Mon Sep 17 00:00:00 2001 +From: Ding Zhi +Date: Mon, 16 Sep 2013 11:31:15 +0200 +Subject: ip6_tunnels: raddr and laddr are inverted in nl msg + +From: Ding Zhi + +[ Upstream commit 0d2ede929f61783aebfb9228e4d32a0546ee4d23 ] + +IFLA_IPTUN_LOCAL and IFLA_IPTUN_REMOTE were inverted. + +Introduced by c075b13098b3 (ip6tnl: advertise tunnel param via rtnl). + +Signed-off-by: Ding Zhi +Signed-off-by: Nicolas Dichtel +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/ip6_tunnel.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/ipv6/ip6_tunnel.c ++++ b/net/ipv6/ip6_tunnel.c +@@ -1646,9 +1646,9 @@ static int ip6_tnl_fill_info(struct sk_b + + if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) || + nla_put(skb, IFLA_IPTUN_LOCAL, sizeof(struct in6_addr), +- &parm->raddr) || +- nla_put(skb, IFLA_IPTUN_REMOTE, sizeof(struct in6_addr), + &parm->laddr) || ++ nla_put(skb, IFLA_IPTUN_REMOTE, sizeof(struct in6_addr), ++ &parm->raddr) || + nla_put_u8(skb, IFLA_IPTUN_TTL, parm->hop_limit) || + nla_put_u8(skb, IFLA_IPTUN_ENCAP_LIMIT, parm->encap_limit) || + nla_put_be32(skb, IFLA_IPTUN_FLOWINFO, parm->flowinfo) || diff --git a/queue-3.10/ip6tnl-allow-to-use-rtnl-ops-on-fb-tunnel.patch b/queue-3.10/ip6tnl-allow-to-use-rtnl-ops-on-fb-tunnel.patch new file mode 100644 index 00000000000..31031a55eab --- /dev/null +++ b/queue-3.10/ip6tnl-allow-to-use-rtnl-ops-on-fb-tunnel.patch @@ -0,0 +1,34 @@ +From d042f1b21be858cb72bb47ac01be6e23092b6ef8 Mon Sep 17 00:00:00 2001 +From: Nicolas Dichtel +Date: Tue, 1 Oct 2013 18:05:00 +0200 +Subject: ip6tnl: allow to use rtnl ops on fb tunnel + +From: Nicolas Dichtel + +[ Upstream commit bb8140947a247b9aa15652cc24dc555ebb0b64b0 ] + +rtnl ops where introduced by c075b13098b3 ("ip6tnl: advertise tunnel param via +rtnl"), but I forget to assign rtnl ops to fb tunnels. + +Now that it is done, we must remove the explicit call to +unregister_netdevice_queue(), because the fallback tunnel is added to the queue +in ip6_tnl_destroy_tunnels() when checking rtnl_link_ops of all netdevices (this +is valid since commit 0bd8762824e7 ("ip6tnl: add x-netns support")). + +Signed-off-by: Nicolas Dichtel +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/ip6_tunnel.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/ipv6/ip6_tunnel.c ++++ b/net/ipv6/ip6_tunnel.c +@@ -1732,6 +1732,7 @@ static int __net_init ip6_tnl_init_net(s + if (!ip6n->fb_tnl_dev) + goto err_alloc_dev; + dev_net_set(ip6n->fb_tnl_dev, net); ++ ip6n->fb_tnl_dev->rtnl_link_ops = &ip6_link_ops; + + err = ip6_fb_tnl_dev_init(ip6n->fb_tnl_dev); + if (err < 0) diff --git a/queue-3.10/ip_tunnel-fix-a-memory-corruption-in-ip_tunnel_xmit.patch b/queue-3.10/ip_tunnel-fix-a-memory-corruption-in-ip_tunnel_xmit.patch new file mode 100644 index 00000000000..4b0ed37f51c --- /dev/null +++ b/queue-3.10/ip_tunnel-fix-a-memory-corruption-in-ip_tunnel_xmit.patch @@ -0,0 +1,46 @@ +From cfaf7c0454cc5b29ccb80c2f545d1a35f1d9c934 Mon Sep 17 00:00:00 2001 +From: Steffen Klassert +Date: Tue, 1 Oct 2013 11:33:59 +0200 +Subject: ip_tunnel: Fix a memory corruption in ip_tunnel_xmit + +From: Steffen Klassert + +[ Upstream commit 3e08f4a72f689c6296d336c2aab4bddd60c93ae2 ] + +We might extend the used aera of a skb beyond the total +headroom when we install the ipip header. Fix this by +calling skb_cow_head() unconditionally. + +Bug was introduced with commit c544193214 +("GRE: Refactor GRE tunneling code.") + +Cc: Pravin Shelar +Signed-off-by: Steffen Klassert +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/ip_tunnel.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/net/ipv4/ip_tunnel.c ++++ b/net/ipv4/ip_tunnel.c +@@ -659,13 +659,13 @@ void ip_tunnel_xmit(struct sk_buff *skb, + + max_headroom = LL_RESERVED_SPACE(tdev) + sizeof(struct iphdr) + + rt->dst.header_len; +- if (max_headroom > dev->needed_headroom) { ++ if (max_headroom > dev->needed_headroom) + dev->needed_headroom = max_headroom; +- if (skb_cow_head(skb, dev->needed_headroom)) { +- dev->stats.tx_dropped++; +- dev_kfree_skb(skb); +- return; +- } ++ ++ if (skb_cow_head(skb, dev->needed_headroom)) { ++ dev->stats.tx_dropped++; ++ dev_kfree_skb(skb); ++ return; + } + + skb_dst_drop(skb); diff --git a/queue-3.10/ipv4-igmp-use-in_dev_put-in-timer-handlers-instead-of-__in_dev_put.patch b/queue-3.10/ipv4-igmp-use-in_dev_put-in-timer-handlers-instead-of-__in_dev_put.patch new file mode 100644 index 00000000000..10a0492d924 --- /dev/null +++ b/queue-3.10/ipv4-igmp-use-in_dev_put-in-timer-handlers-instead-of-__in_dev_put.patch @@ -0,0 +1,47 @@ +From 197107cb5b021956a722a0af43afadba2934e49e Mon Sep 17 00:00:00 2001 +From: Salam Noureddine +Date: Sun, 29 Sep 2013 13:39:42 -0700 +Subject: ipv4 igmp: use in_dev_put in timer handlers instead of __in_dev_put + +From: Salam Noureddine + +[ Upstream commit e2401654dd0f5f3fb7a8d80dad9554d73d7ca394 ] + +It is possible for the timer handlers to run after the call to +ip_mc_down so use in_dev_put instead of __in_dev_put in the handler +function in order to do proper cleanup when the refcnt reaches 0. +Otherwise, the refcnt can reach zero without the in_device being +destroyed and we end up leaking a reference to the net_device and +see messages like the following, + +unregister_netdevice: waiting for eth0 to become free. Usage count = 1 + +Tested on linux-3.4.43. + +Signed-off-by: Salam Noureddine +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/igmp.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/ipv4/igmp.c ++++ b/net/ipv4/igmp.c +@@ -709,7 +709,7 @@ static void igmp_gq_timer_expire(unsigne + + in_dev->mr_gq_running = 0; + igmpv3_send_report(in_dev, NULL); +- __in_dev_put(in_dev); ++ in_dev_put(in_dev); + } + + static void igmp_ifc_timer_expire(unsigned long data) +@@ -721,7 +721,7 @@ static void igmp_ifc_timer_expire(unsign + in_dev->mr_ifc_count--; + igmp_ifc_start_timer(in_dev, IGMP_Unsolicited_Report_Interval); + } +- __in_dev_put(in_dev); ++ in_dev_put(in_dev); + } + + static void igmp_ifc_event(struct in_device *in_dev) diff --git a/queue-3.10/ipv6-exthdrs-accept-tlv-which-includes-only-padding.patch b/queue-3.10/ipv6-exthdrs-accept-tlv-which-includes-only-padding.patch new file mode 100644 index 00000000000..664db73592f --- /dev/null +++ b/queue-3.10/ipv6-exthdrs-accept-tlv-which-includes-only-padding.patch @@ -0,0 +1,39 @@ +From d3f0327fae034e8c530f46692b455d9b02bd423e Mon Sep 17 00:00:00 2001 +From: Jiri Pirko +Date: Fri, 6 Sep 2013 16:02:25 +0200 +Subject: ipv6/exthdrs: accept tlv which includes only padding + +From: Jiri Pirko + +[ Upstream commit 8112b1fe071be01a28a774ed55909e6f4b29712d ] + +In rfc4942 and rfc2460 I cannot find anything which would implicate to +drop packets which have only padding in tlv. + +Current behaviour breaks TAHI Test v6LC.1.2.6. + +Problem was intruduced in: +9b905fe6843 "ipv6/exthdrs: strict Pad1 and PadN check" + +Signed-off-by: Jiri Pirko +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/exthdrs.c | 6 ------ + 1 file changed, 6 deletions(-) + +--- a/net/ipv6/exthdrs.c ++++ b/net/ipv6/exthdrs.c +@@ -162,12 +162,6 @@ static bool ip6_parse_tlv(const struct t + off += optlen; + len -= optlen; + } +- /* This case will not be caught by above check since its padding +- * length is smaller than 7: +- * 1 byte NH + 1 byte Length + 6 bytes Padding +- */ +- if ((padlen == 6) && ((off - skb_network_header_len(skb)) == 8)) +- goto bad; + + if (len == 0) + return true; diff --git a/queue-3.10/ipv6-gre-correct-calculation-of-max_headroom.patch b/queue-3.10/ipv6-gre-correct-calculation-of-max_headroom.patch new file mode 100644 index 00000000000..5838ee360b9 --- /dev/null +++ b/queue-3.10/ipv6-gre-correct-calculation-of-max_headroom.patch @@ -0,0 +1,50 @@ +From 8aa06a725fc62fa533b99f85dcbc78a4b66457ee Mon Sep 17 00:00:00 2001 +From: Hannes Frederic Sowa +Date: Sun, 29 Sep 2013 05:40:50 +0200 +Subject: ipv6: gre: correct calculation of max_headroom + +From: Hannes Frederic Sowa + +[ Upstream commit 3da812d860755925da890e8c713f2d2e2d7b1bae ] + +gre_hlen already accounts for sizeof(struct ipv6_hdr) + gre header, +so initialize max_headroom to zero. Otherwise the + + if (encap_limit >= 0) { + max_headroom += 8; + mtu -= 8; + } + +increments an uninitialized variable before max_headroom was reset. + +Found with coverity: 728539 + +Cc: Dmitry Kozlov +Signed-off-by: Hannes Frederic Sowa +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/ip6_gre.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/ipv6/ip6_gre.c ++++ b/net/ipv6/ip6_gre.c +@@ -620,7 +620,7 @@ static netdev_tx_t ip6gre_xmit2(struct s + struct ip6_tnl *tunnel = netdev_priv(dev); + struct net_device *tdev; /* Device to other host */ + struct ipv6hdr *ipv6h; /* Our new IP header */ +- unsigned int max_headroom; /* The extra header space needed */ ++ unsigned int max_headroom = 0; /* The extra header space needed */ + int gre_hlen; + struct ipv6_tel_txoption opt; + int mtu; +@@ -693,7 +693,7 @@ static netdev_tx_t ip6gre_xmit2(struct s + tunnel->err_count = 0; + } + +- max_headroom = LL_RESERVED_SPACE(tdev) + gre_hlen + dst->header_len; ++ max_headroom += LL_RESERVED_SPACE(tdev) + gre_hlen + dst->header_len; + + if (skb_headroom(skb) < max_headroom || skb_shared(skb) || + (skb_cloned(skb) && !skb_clone_writable(skb, 0))) { diff --git a/queue-3.10/ipv6-mcast-use-in6_dev_put-in-timer-handlers-instead-of-__in6_dev_put.patch b/queue-3.10/ipv6-mcast-use-in6_dev_put-in-timer-handlers-instead-of-__in6_dev_put.patch new file mode 100644 index 00000000000..ccfa3316f82 --- /dev/null +++ b/queue-3.10/ipv6-mcast-use-in6_dev_put-in-timer-handlers-instead-of-__in6_dev_put.patch @@ -0,0 +1,47 @@ +From 1b27441c294e5895617285930489628bc701b6d3 Mon Sep 17 00:00:00 2001 +From: Salam Noureddine +Date: Sun, 29 Sep 2013 13:41:34 -0700 +Subject: ipv6 mcast: use in6_dev_put in timer handlers instead of __in6_dev_put + +From: Salam Noureddine + +[ Upstream commit 9260d3e1013701aa814d10c8fc6a9f92bd17d643 ] + +It is possible for the timer handlers to run after the call to +ipv6_mc_down so use in6_dev_put instead of __in6_dev_put in the +handler function in order to do proper cleanup when the refcnt +reaches 0. Otherwise, the refcnt can reach zero without the +inet6_dev being destroyed and we end up leaking a reference to +the net_device and see messages like the following, + +unregister_netdevice: waiting for eth0 to become free. Usage count = 1 + +Tested on linux-3.4.43. + +Signed-off-by: Salam Noureddine +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/mcast.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/ipv6/mcast.c ++++ b/net/ipv6/mcast.c +@@ -2158,7 +2158,7 @@ static void mld_gq_timer_expire(unsigned + + idev->mc_gq_running = 0; + mld_send_report(idev, NULL); +- __in6_dev_put(idev); ++ in6_dev_put(idev); + } + + static void mld_ifc_timer_expire(unsigned long data) +@@ -2171,7 +2171,7 @@ static void mld_ifc_timer_expire(unsigne + if (idev->mc_ifc_count) + mld_ifc_start_timer(idev, idev->mc_maxdelay); + } +- __in6_dev_put(idev); ++ in6_dev_put(idev); + } + + static void mld_ifc_event(struct inet6_dev *idev) diff --git a/queue-3.10/ipv6-nat-do-not-drop-dnated-6to4-6rd-packets.patch b/queue-3.10/ipv6-nat-do-not-drop-dnated-6to4-6rd-packets.patch new file mode 100644 index 00000000000..ae123796f13 --- /dev/null +++ b/queue-3.10/ipv6-nat-do-not-drop-dnated-6to4-6rd-packets.patch @@ -0,0 +1,190 @@ +From 8c05e1e80bef9aebb3b7db71e7c04abe85d67cee Mon Sep 17 00:00:00 2001 +From: "Catalin\\\\\\\\(ux\\\\\\\\) M. BOIE" +Date: Mon, 23 Sep 2013 23:04:19 +0300 +Subject: IPv6 NAT: Do not drop DNATed 6to4/6rd packets + +From: "Catalin\\\\\\\\(ux\\\\\\\\) M. BOIE" + +[ Upstream commit 7df37ff33dc122f7bd0614d707939fe84322d264 ] + +When a router is doing DNAT for 6to4/6rd packets the latest +anti-spoofing commit 218774dc ("ipv6: add anti-spoofing checks for +6to4 and 6rd") will drop them because the IPv6 address embedded does +not match the IPv4 destination. This patch will allow them to pass by +testing if we have an address that matches on 6to4/6rd interface. I +have been hit by this problem using Fedora and IPV6TO4_IPV4ADDR. +Also, log the dropped packets (with rate limit). + +Signed-off-by: Catalin(ux) M. BOIE +Acked-by: Hannes Frederic Sowa +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/net/addrconf.h | 4 ++ + net/ipv6/addrconf.c | 27 +++++++++++++++ + net/ipv6/sit.c | 84 ++++++++++++++++++++++++++++++++++++++++--------- + 3 files changed, 100 insertions(+), 15 deletions(-) + +--- a/include/net/addrconf.h ++++ b/include/net/addrconf.h +@@ -73,6 +73,10 @@ extern int ipv6_chk_home_addr(struct n + const struct in6_addr *addr); + #endif + ++bool ipv6_chk_custom_prefix(const struct in6_addr *addr, ++ const unsigned int prefix_len, ++ struct net_device *dev); ++ + extern int ipv6_chk_prefix(const struct in6_addr *addr, + struct net_device *dev); + +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -1533,6 +1533,33 @@ static bool ipv6_chk_same_addr(struct ne + return false; + } + ++/* Compares an address/prefix_len with addresses on device @dev. ++ * If one is found it returns true. ++ */ ++bool ipv6_chk_custom_prefix(const struct in6_addr *addr, ++ const unsigned int prefix_len, struct net_device *dev) ++{ ++ struct inet6_dev *idev; ++ struct inet6_ifaddr *ifa; ++ bool ret = false; ++ ++ rcu_read_lock(); ++ idev = __in6_dev_get(dev); ++ if (idev) { ++ read_lock_bh(&idev->lock); ++ list_for_each_entry(ifa, &idev->addr_list, if_list) { ++ ret = ipv6_prefix_equal(addr, &ifa->addr, prefix_len); ++ if (ret) ++ break; ++ } ++ read_unlock_bh(&idev->lock); ++ } ++ rcu_read_unlock(); ++ ++ return ret; ++} ++EXPORT_SYMBOL(ipv6_chk_custom_prefix); ++ + int ipv6_chk_prefix(const struct in6_addr *addr, struct net_device *dev) + { + struct inet6_dev *idev; +--- a/net/ipv6/sit.c ++++ b/net/ipv6/sit.c +@@ -566,6 +566,70 @@ static inline bool is_spoofed_6rd(struct + return false; + } + ++/* Checks if an address matches an address on the tunnel interface. ++ * Used to detect the NAT of proto 41 packets and let them pass spoofing test. ++ * Long story: ++ * This function is called after we considered the packet as spoofed ++ * in is_spoofed_6rd. ++ * We may have a router that is doing NAT for proto 41 packets ++ * for an internal station. Destination a.a.a.a/PREFIX:bbbb:bbbb ++ * will be translated to n.n.n.n/PREFIX:bbbb:bbbb. And is_spoofed_6rd ++ * function will return true, dropping the packet. ++ * But, we can still check if is spoofed against the IP ++ * addresses associated with the interface. ++ */ ++static bool only_dnatted(const struct ip_tunnel *tunnel, ++ const struct in6_addr *v6dst) ++{ ++ int prefix_len; ++ ++#ifdef CONFIG_IPV6_SIT_6RD ++ prefix_len = tunnel->ip6rd.prefixlen + 32 ++ - tunnel->ip6rd.relay_prefixlen; ++#else ++ prefix_len = 48; ++#endif ++ return ipv6_chk_custom_prefix(v6dst, prefix_len, tunnel->dev); ++} ++ ++/* Returns true if a packet is spoofed */ ++static bool packet_is_spoofed(struct sk_buff *skb, ++ const struct iphdr *iph, ++ struct ip_tunnel *tunnel) ++{ ++ const struct ipv6hdr *ipv6h; ++ ++ if (tunnel->dev->priv_flags & IFF_ISATAP) { ++ if (!isatap_chksrc(skb, iph, tunnel)) ++ return true; ++ ++ return false; ++ } ++ ++ if (tunnel->dev->flags & IFF_POINTOPOINT) ++ return false; ++ ++ ipv6h = ipv6_hdr(skb); ++ ++ if (unlikely(is_spoofed_6rd(tunnel, iph->saddr, &ipv6h->saddr))) { ++ net_warn_ratelimited("Src spoofed %pI4/%pI6c -> %pI4/%pI6c\n", ++ &iph->saddr, &ipv6h->saddr, ++ &iph->daddr, &ipv6h->daddr); ++ return true; ++ } ++ ++ if (likely(!is_spoofed_6rd(tunnel, iph->daddr, &ipv6h->daddr))) ++ return false; ++ ++ if (only_dnatted(tunnel, &ipv6h->daddr)) ++ return false; ++ ++ net_warn_ratelimited("Dst spoofed %pI4/%pI6c -> %pI4/%pI6c\n", ++ &iph->saddr, &ipv6h->saddr, ++ &iph->daddr, &ipv6h->daddr); ++ return true; ++} ++ + static int ipip6_rcv(struct sk_buff *skb) + { + const struct iphdr *iph = ip_hdr(skb); +@@ -584,19 +648,9 @@ static int ipip6_rcv(struct sk_buff *skb + skb->protocol = htons(ETH_P_IPV6); + skb->pkt_type = PACKET_HOST; + +- if (tunnel->dev->priv_flags & IFF_ISATAP) { +- if (!isatap_chksrc(skb, iph, tunnel)) { +- tunnel->dev->stats.rx_errors++; +- goto out; +- } +- } else if (!(tunnel->dev->flags&IFF_POINTOPOINT)) { +- if (is_spoofed_6rd(tunnel, iph->saddr, +- &ipv6_hdr(skb)->saddr) || +- is_spoofed_6rd(tunnel, iph->daddr, +- &ipv6_hdr(skb)->daddr)) { +- tunnel->dev->stats.rx_errors++; +- goto out; +- } ++ if (packet_is_spoofed(skb, iph, tunnel)) { ++ tunnel->dev->stats.rx_errors++; ++ goto out; + } + + __skb_tunnel_rx(skb, tunnel->dev); +@@ -713,7 +767,7 @@ static netdev_tx_t ipip6_tunnel_xmit(str + neigh = dst_neigh_lookup(skb_dst(skb), &iph6->daddr); + + if (neigh == NULL) { +- net_dbg_ratelimited("sit: nexthop == NULL\n"); ++ net_dbg_ratelimited("nexthop == NULL\n"); + goto tx_error; + } + +@@ -742,7 +796,7 @@ static netdev_tx_t ipip6_tunnel_xmit(str + neigh = dst_neigh_lookup(skb_dst(skb), &iph6->daddr); + + if (neigh == NULL) { +- net_dbg_ratelimited("sit: nexthop == NULL\n"); ++ net_dbg_ratelimited("nexthop == NULL\n"); + goto tx_error; + } + diff --git a/queue-3.10/ipv6-udp-packets-following-an-ufo-enqueued-packet-need-also-be-handled-by-ufo.patch b/queue-3.10/ipv6-udp-packets-following-an-ufo-enqueued-packet-need-also-be-handled-by-ufo.patch new file mode 100644 index 00000000000..1bf6b5916ec --- /dev/null +++ b/queue-3.10/ipv6-udp-packets-following-an-ufo-enqueued-packet-need-also-be-handled-by-ufo.patch @@ -0,0 +1,122 @@ +From f8ed28cb5503ae2f8dd14f12d7e84063414b81bc Mon Sep 17 00:00:00 2001 +From: Hannes Frederic Sowa +Date: Sat, 21 Sep 2013 06:27:00 +0200 +Subject: ipv6: udp packets following an UFO enqueued packet need also be handled by UFO + +From: Hannes Frederic Sowa + +[ Upstream commit 2811ebac2521ceac84f2bdae402455baa6a7fb47 ] + +In the following scenario the socket is corked: +If the first UDP packet is larger then the mtu we try to append it to the +write queue via ip6_ufo_append_data. A following packet, which is smaller +than the mtu would be appended to the already queued up gso-skb via +plain ip6_append_data. This causes random memory corruptions. + +In ip6_ufo_append_data we also have to be careful to not queue up the +same skb multiple times. So setup the gso frame only when no first skb +is available. + +This also fixes a shortcoming where we add the current packet's length to +cork->length but return early because of a packet > mtu with dontfrag set +(instead of sutracting it again). + +Found with trinity. + +Cc: YOSHIFUJI Hideaki +Signed-off-by: Hannes Frederic Sowa +Reported-by: Dmitry Vyukov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/ip6_output.c | 53 ++++++++++++++++++++------------------------------ + 1 file changed, 22 insertions(+), 31 deletions(-) + +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -1039,6 +1039,8 @@ static inline int ip6_ufo_append_data(st + * udp datagram + */ + if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) { ++ struct frag_hdr fhdr; ++ + skb = sock_alloc_send_skb(sk, + hh_len + fragheaderlen + transhdrlen + 20, + (flags & MSG_DONTWAIT), &err); +@@ -1059,12 +1061,6 @@ static inline int ip6_ufo_append_data(st + + skb->ip_summed = CHECKSUM_PARTIAL; + skb->csum = 0; +- } +- +- err = skb_append_datato_frags(sk,skb, getfrag, from, +- (length - transhdrlen)); +- if (!err) { +- struct frag_hdr fhdr; + + /* Specify the length of each IPv6 datagram fragment. + * It has to be a multiple of 8. +@@ -1075,15 +1071,10 @@ static inline int ip6_ufo_append_data(st + ipv6_select_ident(&fhdr, rt); + skb_shinfo(skb)->ip6_frag_id = fhdr.identification; + __skb_queue_tail(&sk->sk_write_queue, skb); +- +- return 0; + } +- /* There is not enough support do UPD LSO, +- * so follow normal path +- */ +- kfree_skb(skb); + +- return err; ++ return skb_append_datato_frags(sk, skb, getfrag, from, ++ (length - transhdrlen)); + } + + static inline struct ipv6_opt_hdr *ip6_opt_dup(struct ipv6_opt_hdr *src, +@@ -1250,27 +1241,27 @@ int ip6_append_data(struct sock *sk, int + * --yoshfuji + */ + +- cork->length += length; +- if (length > mtu) { +- int proto = sk->sk_protocol; +- if (dontfrag && (proto == IPPROTO_UDP || proto == IPPROTO_RAW)){ +- ipv6_local_rxpmtu(sk, fl6, mtu-exthdrlen); +- return -EMSGSIZE; +- } +- +- if (proto == IPPROTO_UDP && +- (rt->dst.dev->features & NETIF_F_UFO)) { ++ if ((length > mtu) && dontfrag && (sk->sk_protocol == IPPROTO_UDP || ++ sk->sk_protocol == IPPROTO_RAW)) { ++ ipv6_local_rxpmtu(sk, fl6, mtu-exthdrlen); ++ return -EMSGSIZE; ++ } + +- err = ip6_ufo_append_data(sk, getfrag, from, length, +- hh_len, fragheaderlen, +- transhdrlen, mtu, flags, rt); +- if (err) +- goto error; +- return 0; +- } ++ skb = skb_peek_tail(&sk->sk_write_queue); ++ cork->length += length; ++ if (((length > mtu) || ++ (skb && skb_is_gso(skb))) && ++ (sk->sk_protocol == IPPROTO_UDP) && ++ (rt->dst.dev->features & NETIF_F_UFO)) { ++ err = ip6_ufo_append_data(sk, getfrag, from, length, ++ hh_len, fragheaderlen, ++ transhdrlen, mtu, flags, rt); ++ if (err) ++ goto error; ++ return 0; + } + +- if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) ++ if (!skb) + goto alloc_new_skb; + + while (length > 0) { diff --git a/queue-3.10/ll_temac-reset-dma-descriptors-indexes-on-ndo_open.patch b/queue-3.10/ll_temac-reset-dma-descriptors-indexes-on-ndo_open.patch new file mode 100644 index 00000000000..0ed532ffba4 --- /dev/null +++ b/queue-3.10/ll_temac-reset-dma-descriptors-indexes-on-ndo_open.patch @@ -0,0 +1,42 @@ +From da2c6cc3c1f3d2f6cab18352d00ab4a42c1ebee0 Mon Sep 17 00:00:00 2001 +From: Ricardo Ribalda +Date: Tue, 1 Oct 2013 08:17:10 +0200 +Subject: ll_temac: Reset dma descriptors indexes on ndo_open + +From: Ricardo Ribalda + +[ Upstream commit 7167cf0e8cd10287b7912b9ffcccd9616f382922 ] + +The dma descriptors indexes are only initialized on the probe function. + +If a packet is on the buffer when temac_stop is called, the dma +descriptors indexes can be left on a incorrect state where no other +package can be sent. + +So an interface could be left in an usable state after ifdow/ifup. + +This patch makes sure that the descriptors indexes are in a proper +status when the device is open. + +Signed-off-by: Ricardo Ribalda Delgado +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/xilinx/ll_temac_main.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/net/ethernet/xilinx/ll_temac_main.c ++++ b/drivers/net/ethernet/xilinx/ll_temac_main.c +@@ -297,6 +297,12 @@ static int temac_dma_bd_init(struct net_ + lp->rx_bd_p + (sizeof(*lp->rx_bd_v) * (RX_BD_NUM - 1))); + lp->dma_out(lp, TX_CURDESC_PTR, lp->tx_bd_p); + ++ /* Init descriptor indexes */ ++ lp->tx_bd_ci = 0; ++ lp->tx_bd_next = 0; ++ lp->tx_bd_tail = 0; ++ lp->rx_bd_ci = 0; ++ + return 0; + + out: diff --git a/queue-3.10/net-dccp-do-not-report-icmp-redirects-to-user-space.patch b/queue-3.10/net-dccp-do-not-report-icmp-redirects-to-user-space.patch new file mode 100644 index 00000000000..bb6d4eb03fc --- /dev/null +++ b/queue-3.10/net-dccp-do-not-report-icmp-redirects-to-user-space.patch @@ -0,0 +1,31 @@ +From a8f5959cfce4d7e8fc5b8715f5f82829879d0335 Mon Sep 17 00:00:00 2001 +From: Duan Jiong +Date: Wed, 18 Sep 2013 20:03:27 +0800 +Subject: net:dccp: do not report ICMP redirects to user space + +From: Duan Jiong + +[ Upstream commit bd784a140712fd06674f2240eecfc4ccae421129 ] + +DCCP shouldn't be setting sk_err on redirects as it +isn't an error condition. it should be doing exactly +what tcp is doing and leaving the error handler without +touching the socket. + +Signed-off-by: Duan Jiong +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/dccp/ipv6.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/dccp/ipv6.c ++++ b/net/dccp/ipv6.c +@@ -135,6 +135,7 @@ static void dccp_v6_err(struct sk_buff * + + if (dst) + dst->ops->redirect(dst, sk, skb); ++ goto out; + } + + if (type == ICMPV6_PKT_TOOBIG) { diff --git a/queue-3.10/net-fib-fib6_add-fix-potential-null-pointer-dereference.patch b/queue-3.10/net-fib-fib6_add-fix-potential-null-pointer-dereference.patch new file mode 100644 index 00000000000..3e6e65f6703 --- /dev/null +++ b/queue-3.10/net-fib-fib6_add-fix-potential-null-pointer-dereference.patch @@ -0,0 +1,56 @@ +From af64a37e20ffe1306299bcd2a513dbf467b6cf93 Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +Date: Sat, 7 Sep 2013 15:13:20 +0200 +Subject: net: fib: fib6_add: fix potential NULL pointer dereference + +From: Daniel Borkmann + +[ Upstream commit ae7b4e1f213aa659aedf9c6ecad0bf5f0476e1e2 ] + +When the kernel is compiled with CONFIG_IPV6_SUBTREES, and we return +with an error in fn = fib6_add_1(), then error codes are encoded into +the return pointer e.g. ERR_PTR(-ENOENT). In such an error case, we +write the error code into err and jump to out, hence enter the if(err) +condition. Now, if CONFIG_IPV6_SUBTREES is enabled, we check for: + + if (pn != fn && pn->leaf == rt) + ... + if (pn != fn && !pn->leaf && !(pn->fn_flags & RTN_RTINFO)) + ... + +Since pn is NULL and fn is f.e. ERR_PTR(-ENOENT), then pn != fn +evaluates to true and causes a NULL-pointer dereference on further +checks on pn. Fix it, by setting both NULL in error case, so that +pn != fn already evaluates to false and no further dereference +takes place. + +This was first correctly implemented in 4a287eba2 ("IPv6 routing, +NLM_F_* flag support: REPLACE and EXCL flags support, warn about +missing CREATE flag"), but the bug got later on introduced by +188c517a0 ("ipv6: return errno pointers consistently for fib6_add_1()"). + +Signed-off-by: Daniel Borkmann +Cc: Lin Ming +Cc: Matti Vaittinen +Cc: Hannes Frederic Sowa +Acked-by: Hannes Frederic Sowa +Acked-by: Matti Vaittinen +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/ip6_fib.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/ipv6/ip6_fib.c ++++ b/net/ipv6/ip6_fib.c +@@ -825,9 +825,9 @@ int fib6_add(struct fib6_node *root, str + fn = fib6_add_1(root, &rt->rt6i_dst.addr, sizeof(struct in6_addr), + rt->rt6i_dst.plen, offsetof(struct rt6_info, rt6i_dst), + allow_create, replace_required); +- + if (IS_ERR(fn)) { + err = PTR_ERR(fn); ++ fn = NULL; + goto out; + } + diff --git a/queue-3.10/net-fix-multiqueue-selection.patch b/queue-3.10/net-fix-multiqueue-selection.patch new file mode 100644 index 00000000000..1d27e779de9 --- /dev/null +++ b/queue-3.10/net-fix-multiqueue-selection.patch @@ -0,0 +1,49 @@ +From c7c1522f4a1afc5f7f8292b785cdb8855824ea12 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Sat, 7 Sep 2013 12:02:57 -0700 +Subject: net: fix multiqueue selection + +From: Eric Dumazet + +[ Upstream commit 50d1784ee4683f073c0362ee360bfae7a3333d6c ] + +commit 416186fbf8c5b4e4465 ("net: Split core bits of netdev_pick_tx +into __netdev_pick_tx") added a bug that disables caching of queue +index in the socket. + +This is the source of packet reorders for TCP flows, and +again this is happening more often when using FQ pacing. + +Old code was doing + +if (queue_index != old_index) + sk_tx_queue_set(sk, queue_index); + +Alexander renamed the variables but forgot to change sk_tx_queue_set() +2nd parameter. + +if (queue_index != new_index) + sk_tx_queue_set(sk, queue_index); + +This means we store -1 over and over in sk->sk_tx_queue_mapping + +Signed-off-by: Eric Dumazet +Cc: Alexander Duyck +Acked-by: Alexander Duyck +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/flow_dissector.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/core/flow_dissector.c ++++ b/net/core/flow_dissector.c +@@ -347,7 +347,7 @@ u16 __netdev_pick_tx(struct net_device * + + if (queue_index != new_index && sk && + rcu_access_pointer(sk->sk_dst_cache)) +- sk_tx_queue_set(sk, queue_index); ++ sk_tx_queue_set(sk, new_index); + + queue_index = new_index; + } diff --git a/queue-3.10/net-flow_dissector-fix-thoff-for-ipproto_ah.patch b/queue-3.10/net-flow_dissector-fix-thoff-for-ipproto_ah.patch new file mode 100644 index 00000000000..ff340902fbd --- /dev/null +++ b/queue-3.10/net-flow_dissector-fix-thoff-for-ipproto_ah.patch @@ -0,0 +1,41 @@ +From bd43a3e079544ea599cf3ec0e3d66605b7384366 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Thu, 26 Sep 2013 08:44:06 -0700 +Subject: net: flow_dissector: fix thoff for IPPROTO_AH + +From: Eric Dumazet + +[ Upstream commit b86783587b3d1d552326d955acee37eac48800f1 ] + +In commit 8ed781668dd49 ("flow_keys: include thoff into flow_keys for +later usage"), we missed that existing code was using nhoff as a +temporary variable that could not always contain transport header +offset. + +This is not a problem for TCP/UDP because port offset (@poff) +is 0 for these protocols. + +Signed-off-by: Eric Dumazet +Cc: Daniel Borkmann +Cc: Nikolay Aleksandrov +Acked-by: Nikolay Aleksandrov +Acked-by: Daniel Borkmann +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/flow_dissector.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/core/flow_dissector.c ++++ b/net/core/flow_dissector.c +@@ -149,8 +149,8 @@ ipv6: + if (poff >= 0) { + __be32 *ports, _ports; + +- nhoff += poff; +- ports = skb_header_pointer(skb, nhoff, sizeof(_ports), &_ports); ++ ports = skb_header_pointer(skb, nhoff + poff, ++ sizeof(_ports), &_ports); + if (ports) + flow->ports = *ports; + } diff --git a/queue-3.10/net-net_secret-should-not-depend-on-tcp.patch b/queue-3.10/net-net_secret-should-not-depend-on-tcp.patch new file mode 100644 index 00000000000..254e09f8707 --- /dev/null +++ b/queue-3.10/net-net_secret-should-not-depend-on-tcp.patch @@ -0,0 +1,145 @@ +From 79d3483370058bf89affe5b3cd9ea98ae05d3b48 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Tue, 24 Sep 2013 06:19:57 -0700 +Subject: net: net_secret should not depend on TCP + +From: Eric Dumazet + +[ Upstream commit 9a3bab6b05383f1e4c3716b3615500c51285959e ] + +A host might need net_secret[] and never open a single socket. + +Problem added in commit aebda156a570782 +("net: defer net_secret[] initialization") + +Based on prior patch from Hannes Frederic Sowa. + +Reported-by: Hannes Frederic Sowa +Signed-off-by: Eric Dumazet +Acked-by: Hannes Frederic Sowa +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/net/secure_seq.h | 1 - + net/core/secure_seq.c | 27 ++++++++++++++++++++++++--- + net/ipv4/af_inet.c | 4 +--- + 3 files changed, 25 insertions(+), 7 deletions(-) + +--- a/include/net/secure_seq.h ++++ b/include/net/secure_seq.h +@@ -3,7 +3,6 @@ + + #include + +-extern void net_secret_init(void); + extern __u32 secure_ip_id(__be32 daddr); + extern __u32 secure_ipv6_id(const __be32 daddr[4]); + extern u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport); +--- a/net/core/secure_seq.c ++++ b/net/core/secure_seq.c +@@ -10,11 +10,24 @@ + + #include + +-static u32 net_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned; ++#define NET_SECRET_SIZE (MD5_MESSAGE_BYTES / 4) + +-void net_secret_init(void) ++static u32 net_secret[NET_SECRET_SIZE] ____cacheline_aligned; ++ ++static void net_secret_init(void) + { +- get_random_bytes(net_secret, sizeof(net_secret)); ++ u32 tmp; ++ int i; ++ ++ if (likely(net_secret[0])) ++ return; ++ ++ for (i = NET_SECRET_SIZE; i > 0;) { ++ do { ++ get_random_bytes(&tmp, sizeof(tmp)); ++ } while (!tmp); ++ cmpxchg(&net_secret[--i], 0, tmp); ++ } + } + + #ifdef CONFIG_INET +@@ -42,6 +55,7 @@ __u32 secure_tcpv6_sequence_number(const + u32 hash[MD5_DIGEST_WORDS]; + u32 i; + ++ net_secret_init(); + memcpy(hash, saddr, 16); + for (i = 0; i < 4; i++) + secret[i] = net_secret[i] + (__force u32)daddr[i]; +@@ -63,6 +77,7 @@ u32 secure_ipv6_port_ephemeral(const __b + u32 hash[MD5_DIGEST_WORDS]; + u32 i; + ++ net_secret_init(); + memcpy(hash, saddr, 16); + for (i = 0; i < 4; i++) + secret[i] = net_secret[i] + (__force u32) daddr[i]; +@@ -82,6 +97,7 @@ __u32 secure_ip_id(__be32 daddr) + { + u32 hash[MD5_DIGEST_WORDS]; + ++ net_secret_init(); + hash[0] = (__force __u32) daddr; + hash[1] = net_secret[13]; + hash[2] = net_secret[14]; +@@ -96,6 +112,7 @@ __u32 secure_ipv6_id(const __be32 daddr[ + { + __u32 hash[4]; + ++ net_secret_init(); + memcpy(hash, daddr, 16); + md5_transform(hash, net_secret); + +@@ -107,6 +124,7 @@ __u32 secure_tcp_sequence_number(__be32 + { + u32 hash[MD5_DIGEST_WORDS]; + ++ net_secret_init(); + hash[0] = (__force u32)saddr; + hash[1] = (__force u32)daddr; + hash[2] = ((__force u16)sport << 16) + (__force u16)dport; +@@ -121,6 +139,7 @@ u32 secure_ipv4_port_ephemeral(__be32 sa + { + u32 hash[MD5_DIGEST_WORDS]; + ++ net_secret_init(); + hash[0] = (__force u32)saddr; + hash[1] = (__force u32)daddr; + hash[2] = (__force u32)dport ^ net_secret[14]; +@@ -140,6 +159,7 @@ u64 secure_dccp_sequence_number(__be32 s + u32 hash[MD5_DIGEST_WORDS]; + u64 seq; + ++ net_secret_init(); + hash[0] = (__force u32)saddr; + hash[1] = (__force u32)daddr; + hash[2] = ((__force u16)sport << 16) + (__force u16)dport; +@@ -164,6 +184,7 @@ u64 secure_dccpv6_sequence_number(__be32 + u64 seq; + u32 i; + ++ net_secret_init(); + memcpy(hash, saddr, 16); + for (i = 0; i < 4; i++) + secret[i] = net_secret[i] + daddr[i]; +--- a/net/ipv4/af_inet.c ++++ b/net/ipv4/af_inet.c +@@ -263,10 +263,8 @@ void build_ehash_secret(void) + get_random_bytes(&rnd, sizeof(rnd)); + } while (rnd == 0); + +- if (cmpxchg(&inet_ehash_secret, 0, rnd) == 0) { ++ if (cmpxchg(&inet_ehash_secret, 0, rnd) == 0) + get_random_bytes(&ipv6_hash_secret, sizeof(ipv6_hash_secret)); +- net_secret_init(); +- } + } + EXPORT_SYMBOL(build_ehash_secret); + diff --git a/queue-3.10/net-sctp-fix-bug-in-sctp_poll-for-sock_select_err_queue.patch b/queue-3.10/net-sctp-fix-bug-in-sctp_poll-for-sock_select_err_queue.patch new file mode 100644 index 00000000000..fbb42afb765 --- /dev/null +++ b/queue-3.10/net-sctp-fix-bug-in-sctp_poll-for-sock_select_err_queue.patch @@ -0,0 +1,45 @@ +From bf20b5d336d0dd1f66b455ed210c5f29abd6e7fb Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +Date: Sat, 7 Sep 2013 16:44:59 +0200 +Subject: net: sctp: fix bug in sctp_poll for SOCK_SELECT_ERR_QUEUE + +From: Daniel Borkmann + +[ Upstream commit a0fb05d1aef0f5df936f80b726d1b3bfd4275f95 ] + +If we do not add braces around ... + + mask |= POLLERR | + sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? POLLPRI : 0; + +... then this condition always evaluates to true as POLLERR is +defined as 8 and binary or'd with whatever result comes out of +sock_flag(). Hence instead of (X | Y) ? A : B, transform it into +X | (Y ? A : B). Unfortunatelty, commit 8facd5fb73 ("net: fix +smatch warnings inside datagram_poll") forgot about SCTP. :-( + +Introduced by 7d4c04fc170 ("net: add option to enable error queue +packets waking select"). + +Signed-off-by: Daniel Borkmann +Cc: Jacob Keller +Acked-by: Neil Horman +Acked-by: Vlad Yasevich +Acked-by: Jacob Keller +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/sctp/socket.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -6193,7 +6193,7 @@ unsigned int sctp_poll(struct file *file + /* Is there any exceptional events? */ + if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) + mask |= POLLERR | +- sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? POLLPRI : 0; ++ (sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? POLLPRI : 0); + if (sk->sk_shutdown & RCV_SHUTDOWN) + mask |= POLLRDHUP | POLLIN | POLLRDNORM; + if (sk->sk_shutdown == SHUTDOWN_MASK) diff --git a/queue-3.10/net-sctp-fix-ipv6-ipsec-encryption-bug-in-sctp_v6_xmit.patch b/queue-3.10/net-sctp-fix-ipv6-ipsec-encryption-bug-in-sctp_v6_xmit.patch new file mode 100644 index 00000000000..fb6b158eb55 --- /dev/null +++ b/queue-3.10/net-sctp-fix-ipv6-ipsec-encryption-bug-in-sctp_v6_xmit.patch @@ -0,0 +1,191 @@ +From d7dcbed786ea5efc5ead39e6017ad35f155aab46 Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +Date: Wed, 11 Sep 2013 16:58:36 +0200 +Subject: net: sctp: fix ipv6 ipsec encryption bug in sctp_v6_xmit + +From: Daniel Borkmann + +[ Upstream commit 95ee62083cb6453e056562d91f597552021e6ae7 ] + +Alan Chester reported an issue with IPv6 on SCTP that IPsec traffic is not +being encrypted, whereas on IPv4 it is. Setting up an AH + ESP transport +does not seem to have the desired effect: + +SCTP + IPv4: + + 22:14:20.809645 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto AH (51), length 116) + 192.168.0.2 > 192.168.0.5: AH(spi=0x00000042,sumlen=16,seq=0x1): ESP(spi=0x00000044,seq=0x1), length 72 + 22:14:20.813270 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto AH (51), length 340) + 192.168.0.5 > 192.168.0.2: AH(spi=0x00000043,sumlen=16,seq=0x1): + +SCTP + IPv6: + + 22:31:19.215029 IP6 (class 0x02, hlim 64, next-header SCTP (132) payload length: 364) + fe80::222:15ff:fe87:7fc.3333 > fe80::92e6:baff:fe0d:5a54.36767: sctp + 1) [INIT ACK] [init tag: 747759530] [rwnd: 62464] [OS: 10] [MIS: 10] + +Moreover, Alan says: + + This problem was seen with both Racoon and Racoon2. Other people have seen + this with OpenSwan. When IPsec is configured to encrypt all upper layer + protocols the SCTP connection does not initialize. After using Wireshark to + follow packets, this is because the SCTP packet leaves Box A unencrypted and + Box B believes all upper layer protocols are to be encrypted so it drops + this packet, causing the SCTP connection to fail to initialize. When IPsec + is configured to encrypt just SCTP, the SCTP packets are observed unencrypted. + +In fact, using `socat sctp6-listen:3333 -` on one end and transferring "plaintext" +string on the other end, results in cleartext on the wire where SCTP eventually +does not report any errors, thus in the latter case that Alan reports, the +non-paranoid user might think he's communicating over an encrypted transport on +SCTP although he's not (tcpdump ... -X): + + ... + 0x0030: 5d70 8e1a 0003 001a 177d eb6c 0000 0000 ]p.......}.l.... + 0x0040: 0000 0000 706c 6169 6e74 6578 740a 0000 ....plaintext... + +Only in /proc/net/xfrm_stat we can see XfrmInTmplMismatch increasing on the +receiver side. Initial follow-up analysis from Alan's bug report was done by +Alexey Dobriyan. Also thanks to Vlad Yasevich for feedback on this. + +SCTP has its own implementation of sctp_v6_xmit() not calling inet6_csk_xmit(). +This has the implication that it probably never really got updated along with +changes in inet6_csk_xmit() and therefore does not seem to invoke xfrm handlers. + +SCTP's IPv4 xmit however, properly calls ip_queue_xmit() to do the work. Since +a call to inet6_csk_xmit() would solve this problem, but result in unecessary +route lookups, let us just use the cached flowi6 instead that we got through +sctp_v6_get_dst(). Since all SCTP packets are being sent through sctp_packet_transmit(), +we do the route lookup / flow caching in sctp_transport_route(), hold it in +tp->dst and skb_dst_set() right after that. If we would alter fl6->daddr in +sctp_v6_xmit() to np->opt->srcrt, we possibly could run into the same effect +of not having xfrm layer pick it up, hence, use fl6_update_dst() in sctp_v6_get_dst() +instead to get the correct source routed dst entry, which we assign to the skb. + +Also source address routing example from 625034113 ("sctp: fix sctp to work with +ipv6 source address routing") still works with this patch! Nevertheless, in RFC5095 +it is actually 'recommended' to not use that anyway due to traffic amplification [1]. +So it seems we're not supposed to do that anyway in sctp_v6_xmit(). Moreover, if +we overwrite the flow destination here, the lower IPv6 layer will be unable to +put the correct destination address into IP header, as routing header is added in +ipv6_push_nfrag_opts() but then probably with wrong final destination. Things aside, +result of this patch is that we do not have any XfrmInTmplMismatch increase plus on +the wire with this patch it now looks like: + +SCTP + IPv6: + + 08:17:47.074080 IP6 2620:52:0:102f:7a2b:cbff:fe27:1b0a > 2620:52:0:102f:213:72ff:fe32:7eba: + AH(spi=0x00005fb4,seq=0x1): ESP(spi=0x00005fb5,seq=0x1), length 72 + 08:17:47.074264 IP6 2620:52:0:102f:213:72ff:fe32:7eba > 2620:52:0:102f:7a2b:cbff:fe27:1b0a: + AH(spi=0x00003d54,seq=0x1): ESP(spi=0x00003d55,seq=0x1), length 296 + +This fixes Kernel Bugzilla 24412. This security issue seems to be present since +2.6.18 kernels. Lets just hope some big passive adversary in the wild didn't have +its fun with that. lksctp-tools IPv6 regression test suite passes as well with +this patch. + + [1] http://www.secdev.org/conf/IPv6_RH_security-csw07.pdf + +Reported-by: Alan Chester +Reported-by: Alexey Dobriyan +Signed-off-by: Daniel Borkmann +Cc: Steffen Klassert +Cc: Hannes Frederic Sowa +Acked-by: Vlad Yasevich +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/sctp/ipv6.c | 42 +++++++++++++----------------------------- + 1 file changed, 13 insertions(+), 29 deletions(-) + +--- a/net/sctp/ipv6.c ++++ b/net/sctp/ipv6.c +@@ -210,45 +210,24 @@ out: + in6_dev_put(idev); + } + +-/* Based on tcp_v6_xmit() in tcp_ipv6.c. */ + static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport) + { + struct sock *sk = skb->sk; + struct ipv6_pinfo *np = inet6_sk(sk); +- struct flowi6 fl6; +- +- memset(&fl6, 0, sizeof(fl6)); +- +- fl6.flowi6_proto = sk->sk_protocol; +- +- /* Fill in the dest address from the route entry passed with the skb +- * and the source address from the transport. +- */ +- fl6.daddr = transport->ipaddr.v6.sin6_addr; +- fl6.saddr = transport->saddr.v6.sin6_addr; +- +- fl6.flowlabel = np->flow_label; +- IP6_ECN_flow_xmit(sk, fl6.flowlabel); +- if (ipv6_addr_type(&fl6.saddr) & IPV6_ADDR_LINKLOCAL) +- fl6.flowi6_oif = transport->saddr.v6.sin6_scope_id; +- else +- fl6.flowi6_oif = sk->sk_bound_dev_if; +- +- if (np->opt && np->opt->srcrt) { +- struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt; +- fl6.daddr = *rt0->addr; +- } ++ struct flowi6 *fl6 = &transport->fl.u.ip6; + + SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, src:%pI6 dst:%pI6\n", + __func__, skb, skb->len, +- &fl6.saddr, &fl6.daddr); ++ &fl6->saddr, &fl6->daddr); + +- SCTP_INC_STATS(sock_net(sk), SCTP_MIB_OUTSCTPPACKS); ++ IP6_ECN_flow_xmit(sk, fl6->flowlabel); + + if (!(transport->param_flags & SPP_PMTUD_ENABLE)) + skb->local_df = 1; + +- return ip6_xmit(sk, skb, &fl6, np->opt, np->tclass); ++ SCTP_INC_STATS(sock_net(sk), SCTP_MIB_OUTSCTPPACKS); ++ ++ return ip6_xmit(sk, skb, fl6, np->opt, np->tclass); + } + + /* Returns the dst cache entry for the given source and destination ip +@@ -261,10 +240,12 @@ static void sctp_v6_get_dst(struct sctp_ + struct dst_entry *dst = NULL; + struct flowi6 *fl6 = &fl->u.ip6; + struct sctp_bind_addr *bp; ++ struct ipv6_pinfo *np = inet6_sk(sk); + struct sctp_sockaddr_entry *laddr; + union sctp_addr *baddr = NULL; + union sctp_addr *daddr = &t->ipaddr; + union sctp_addr dst_saddr; ++ struct in6_addr *final_p, final; + __u8 matchlen = 0; + __u8 bmatchlen; + sctp_scope_t scope; +@@ -287,7 +268,8 @@ static void sctp_v6_get_dst(struct sctp_ + SCTP_DEBUG_PRINTK("SRC=%pI6 - ", &fl6->saddr); + } + +- dst = ip6_dst_lookup_flow(sk, fl6, NULL, false); ++ final_p = fl6_update_dst(fl6, np->opt, &final); ++ dst = ip6_dst_lookup_flow(sk, fl6, final_p, false); + if (!asoc || saddr) + goto out; + +@@ -339,10 +321,12 @@ static void sctp_v6_get_dst(struct sctp_ + } + } + rcu_read_unlock(); ++ + if (baddr) { + fl6->saddr = baddr->v6.sin6_addr; + fl6->fl6_sport = baddr->v6.sin6_port; +- dst = ip6_dst_lookup_flow(sk, fl6, NULL, false); ++ final_p = fl6_update_dst(fl6, np->opt, &final); ++ dst = ip6_dst_lookup_flow(sk, fl6, final_p, false); + } + + out: diff --git a/queue-3.10/net-sctp-fix-smatch-warning-in-sctp_send_asconf_del_ip.patch b/queue-3.10/net-sctp-fix-smatch-warning-in-sctp_send_asconf_del_ip.patch new file mode 100644 index 00000000000..9c4dff1f01b --- /dev/null +++ b/queue-3.10/net-sctp-fix-smatch-warning-in-sctp_send_asconf_del_ip.patch @@ -0,0 +1,60 @@ +From 3d71b99f9d1c2e70e24c299fa9fecf5416aa57f7 Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +Date: Sat, 7 Sep 2013 20:51:21 +0200 +Subject: net: sctp: fix smatch warning in sctp_send_asconf_del_ip + +From: Daniel Borkmann + +[ Upstream commit 88362ad8f9a6cea787420b57cc27ccacef000dbe ] + +This was originally reported in [1] and posted by Neil Horman [2], he said: + + Fix up a missed null pointer check in the asconf code. If we don't find + a local address, but we pass in an address length of more than 1, we may + dereference a NULL laddr pointer. Currently this can't happen, as the only + users of the function pass in the value 1 as the addrcnt parameter, but + its not hot path, and it doesn't hurt to check for NULL should that ever + be the case. + +The callpath from sctp_asconf_mgmt() looks okay. But this could be triggered +from sctp_setsockopt_bindx() call with SCTP_BINDX_REM_ADDR and addrcnt > 1 +while passing all possible addresses from the bind list to SCTP_BINDX_REM_ADDR +so that we do *not* find a single address in the association's bind address +list that is not in the packed array of addresses. If this happens when we +have an established association with ASCONF-capable peers, then we could get +a NULL pointer dereference as we only check for laddr == NULL && addrcnt == 1 +and call later sctp_make_asconf_update_ip() with NULL laddr. + +BUT: this actually won't happen as sctp_bindx_rem() will catch such a case +and return with an error earlier. As this is incredably unintuitive and error +prone, add a check to catch at least future bugs here. As Neil says, its not +hot path. Introduced by 8a07eb0a5 ("sctp: Add ASCONF operation on the +single-homed host"). + + [1] http://www.spinics.net/lists/linux-sctp/msg02132.html + [2] http://www.spinics.net/lists/linux-sctp/msg02133.html + +Reported-by: Dan Carpenter +Signed-off-by: Neil Horman +Signed-off-by: Daniel Borkmann +Cc: Michio Honda +Acked-By: Neil Horman +Acked-by: Vlad Yasevich +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/sctp/socket.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -820,6 +820,9 @@ static int sctp_send_asconf_del_ip(struc + goto skip_mkasconf; + } + ++ if (laddr == NULL) ++ return -EINVAL; ++ + /* We do not need RCU protection throughout this loop + * because this is done under a socket lock from the + * setsockopt call. diff --git a/queue-3.10/net-sctp-rfc4443-do-not-report-icmp-redirects-to-user-space.patch b/queue-3.10/net-sctp-rfc4443-do-not-report-icmp-redirects-to-user-space.patch new file mode 100644 index 00000000000..b0a9b9db48a --- /dev/null +++ b/queue-3.10/net-sctp-rfc4443-do-not-report-icmp-redirects-to-user-space.patch @@ -0,0 +1,59 @@ +From 5d6c495c759ab1560df30393ceb701dc11a46cb8 Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +Date: Mon, 16 Sep 2013 12:36:02 +0200 +Subject: net: sctp: rfc4443: do not report ICMP redirects to user space + +From: Daniel Borkmann + +[ Upstream commit 3f96a532113131d5a65ac9e00fc83cfa31b0295f ] + +Adapt the same behaviour for SCTP as present in TCP for ICMP redirect +messages. For IPv6, RFC4443, section 2.4. says: + + ... + (e) An ICMPv6 error message MUST NOT be originated as a result of + receiving the following: + ... + (e.2) An ICMPv6 redirect message [IPv6-DISC]. + ... + +Therefore, do not report an error to user space, just invoke dst's redirect +callback and leave, same for IPv4 as done in TCP as well. The implication +w/o having this patch could be that the reception of such packets would +generate a poll notification and in worst case it could even tear down the +whole connection. Therefore, stop updating sk_err on redirects. + +Reported-by: Duan Jiong +Reported-by: Hannes Frederic Sowa +Suggested-by: Vlad Yasevich +Signed-off-by: Daniel Borkmann +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/sctp/input.c | 3 +-- + net/sctp/ipv6.c | 2 +- + 2 files changed, 2 insertions(+), 3 deletions(-) + +--- a/net/sctp/input.c ++++ b/net/sctp/input.c +@@ -648,8 +648,7 @@ void sctp_v4_err(struct sk_buff *skb, __ + break; + case ICMP_REDIRECT: + sctp_icmp_redirect(sk, transport, skb); +- err = 0; +- break; ++ /* Fall through to out_unlock. */ + default: + goto out_unlock; + } +--- a/net/sctp/ipv6.c ++++ b/net/sctp/ipv6.c +@@ -189,7 +189,7 @@ SCTP_STATIC void sctp_v6_err(struct sk_b + break; + case NDISC_REDIRECT: + sctp_icmp_redirect(sk, transport, skb); +- break; ++ goto out_unlock; + default: + break; + } diff --git a/queue-3.10/net_sched-htb-fix-a-typo-in-htb_change_class.patch b/queue-3.10/net_sched-htb-fix-a-typo-in-htb_change_class.patch new file mode 100644 index 00000000000..d86aed42bb8 --- /dev/null +++ b/queue-3.10/net_sched-htb-fix-a-typo-in-htb_change_class.patch @@ -0,0 +1,36 @@ +From c4ad7cbee4c5bb1b3e36b22949a23dd83e0516c8 Mon Sep 17 00:00:00 2001 +From: Vimalkumar +Date: Tue, 10 Sep 2013 17:36:37 -0700 +Subject: net_sched: htb: fix a typo in htb_change_class() + +From: Vimalkumar + +[ Upstream commit f3ad857e3da1abaea780dc892b592cd86c541c52 ] + +Fix a typo added in commit 56b765b79 ("htb: improved accuracy at high +rates") + +cbuffer should not be a copy of buffer. + +Signed-off-by: Vimalkumar +Signed-off-by: Eric Dumazet +Cc: Jesper Dangaard Brouer +Cc: Jiri Pirko +Reviewed-by: Jiri Pirko +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/sched/sch_htb.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/sched/sch_htb.c ++++ b/net/sched/sch_htb.c +@@ -1476,7 +1476,7 @@ static int htb_change_class(struct Qdisc + psched_ratecfg_precompute(&cl->ceil, &hopt->ceil); + + cl->buffer = PSCHED_TICKS2NS(hopt->buffer); +- cl->cbuffer = PSCHED_TICKS2NS(hopt->buffer); ++ cl->cbuffer = PSCHED_TICKS2NS(hopt->cbuffer); + + sch_tree_unlock(sch); + diff --git a/queue-3.10/netpoll-fix-null-pointer-dereference-in-netpoll_cleanup.patch b/queue-3.10/netpoll-fix-null-pointer-dereference-in-netpoll_cleanup.patch new file mode 100644 index 00000000000..a17b63b8d99 --- /dev/null +++ b/queue-3.10/netpoll-fix-null-pointer-dereference-in-netpoll_cleanup.patch @@ -0,0 +1,53 @@ +From a3348d27f3cbae159b5995c19aa7d15db4982d06 Mon Sep 17 00:00:00 2001 +From: Nikolay Aleksandrov +Date: Thu, 19 Sep 2013 15:02:35 +0200 +Subject: netpoll: fix NULL pointer dereference in netpoll_cleanup + +From: Nikolay Aleksandrov + +[ Upstream commit d0fe8c888b1fd1a2f84b9962cabcb98a70988aec ] + +I've been hitting a NULL ptr deref while using netconsole because the +np->dev check and the pointer manipulation in netpoll_cleanup are done +without rtnl and the following sequence happens when having a netconsole +over a vlan and we remove the vlan while disabling the netconsole: + CPU 1 CPU2 + removes vlan and calls the notifier +enters store_enabled(), calls +netdev_cleanup which checks np->dev +and then waits for rtnl + executes the netconsole netdev + release notifier making np->dev + == NULL and releases rtnl +continues to dereference a member of +np->dev which at this point is == NULL + +Signed-off-by: Nikolay Aleksandrov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/netpoll.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +--- a/net/core/netpoll.c ++++ b/net/core/netpoll.c +@@ -1289,15 +1289,14 @@ EXPORT_SYMBOL_GPL(__netpoll_free_async); + + void netpoll_cleanup(struct netpoll *np) + { +- if (!np->dev) +- return; +- + rtnl_lock(); ++ if (!np->dev) ++ goto out; + __netpoll_cleanup(np); +- rtnl_unlock(); +- + dev_put(np->dev); + np->dev = NULL; ++out: ++ rtnl_unlock(); + } + EXPORT_SYMBOL(netpoll_cleanup); + diff --git a/queue-3.10/netpoll-should-handle-eth_p_arp-other-than-eth_p_ip-in-netpoll_neigh_reply.patch b/queue-3.10/netpoll-should-handle-eth_p_arp-other-than-eth_p_ip-in-netpoll_neigh_reply.patch new file mode 100644 index 00000000000..26d3cae081b --- /dev/null +++ b/queue-3.10/netpoll-should-handle-eth_p_arp-other-than-eth_p_ip-in-netpoll_neigh_reply.patch @@ -0,0 +1,32 @@ +From dc4b6f759a581e7eee285c62508859abea77c42f Mon Sep 17 00:00:00 2001 +From: Sonic Zhang +Date: Wed, 11 Sep 2013 11:31:53 +0800 +Subject: netpoll: Should handle ETH_P_ARP other than ETH_P_IP in netpoll_neigh_reply + +From: Sonic Zhang + +[ Upstream commit b0dd663b60944a3ce86430fa35549fb37968bda0 ] + +The received ARP request type in the Ethernet packet head is ETH_P_ARP other than ETH_P_IP. + +[ Bug introduced by commit b7394d2429c198b1da3d46ac39192e891029ec0f + ("netpoll: prepare for ipv6") ] + +Signed-off-by: Sonic Zhang +Signed-off-by: David S. Miller +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 +@@ -550,7 +550,7 @@ static void netpoll_neigh_reply(struct s + return; + + proto = ntohs(eth_hdr(skb)->h_proto); +- if (proto == ETH_P_IP) { ++ if (proto == ETH_P_ARP) { + struct arphdr *arp; + unsigned char *arp_ptr; + /* No arp on this interface */ diff --git a/queue-3.10/r8169-enforce-rx_multi_en-for-the-8168f.patch b/queue-3.10/r8169-enforce-rx_multi_en-for-the-8168f.patch new file mode 100644 index 00000000000..ed4cd3dd30a --- /dev/null +++ b/queue-3.10/r8169-enforce-rx_multi_en-for-the-8168f.patch @@ -0,0 +1,35 @@ +From d4231c00ad355016267ddbf42ad50b4dd9aca037 Mon Sep 17 00:00:00 2001 +From: Francois Romieu +Date: Sun, 8 Sep 2013 01:15:35 +0200 +Subject: r8169: enforce RX_MULTI_EN for the 8168f. + +From: Francois Romieu + +[ Upstream commit 3ced8c955e74d319f3e3997f7169c79d524dfd06 ] + +Same narrative as eb2dc35d99028b698cdedba4f5522bc43e576bd2 ("r8169: RxConfig +hack for the 8168evl.") regarding AMD IOMMU errors. + +RTL_GIGA_MAC_VER_36 - 8168f as well - has not been reported to behave the +same. + +Tested-by: David R +Tested-by: Frédéric Leroy +Cc: Hayes Wang +Signed-off-by: Francois Romieu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/realtek/r8169.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/ethernet/realtek/r8169.c ++++ b/drivers/net/ethernet/realtek/r8169.c +@@ -4218,6 +4218,7 @@ static void rtl_init_rxcfg(struct rtl816 + case RTL_GIGA_MAC_VER_23: + case RTL_GIGA_MAC_VER_24: + case RTL_GIGA_MAC_VER_34: ++ case RTL_GIGA_MAC_VER_35: + RTL_W32(RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST); + break; + case RTL_GIGA_MAC_VER_40: diff --git a/queue-3.10/resubmit-bridge-fix-message_age_timer-calculation.patch b/queue-3.10/resubmit-bridge-fix-message_age_timer-calculation.patch new file mode 100644 index 00000000000..21012f2f8d0 --- /dev/null +++ b/queue-3.10/resubmit-bridge-fix-message_age_timer-calculation.patch @@ -0,0 +1,37 @@ +From fd5188f3905894b2e9ba20e1c654ec53442a514e Mon Sep 17 00:00:00 2001 +From: Chris Healy +Date: Wed, 11 Sep 2013 21:37:47 -0700 +Subject: resubmit bridge: fix message_age_timer calculation + +From: Chris Healy + +[ Upstream commit 9a0620133ccce9dd35c00a96405c8d80938c2cc0 ] + +This changes the message_age_timer calculation to use the BPDU's max age as +opposed to the local bridge's max age. This is in accordance with section +8.6.2.3.2 Step 2 of the 802.1D-1998 sprecification. + +With the current implementation, when running with very large bridge +diameters, convergance will not always occur even if a root bridge is +configured to have a longer max age. + +Tested successfully on bridge diameters of ~200. + +Signed-off-by: Chris Healy +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/bridge/br_stp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/bridge/br_stp.c ++++ b/net/bridge/br_stp.c +@@ -209,7 +209,7 @@ static void br_record_config_information + p->designated_age = jiffies - bpdu->message_age; + + mod_timer(&p->message_age_timer, jiffies +- + (p->br->max_age - bpdu->message_age)); ++ + (bpdu->max_age - bpdu->message_age)); + } + + /* called under bridge lock */ diff --git a/queue-3.10/series b/queue-3.10/series index 86c57023304..740f80e1651 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -3,3 +3,40 @@ cpqarray-fix-info-leak-in-ida_locked_ioctl.patch cciss-fix-info-leak-in-cciss_ioctl32_passthru.patch hid-fix-data-access-in-implement.patch hid-fix-unused-rsize-usage.patch +caif-add-missing-braces-to-multiline-if-in-cfctrl_linkup_request.patch +tcp-add-missing-braces-to-do_tcp_setsockopt.patch +ipv6-exthdrs-accept-tlv-which-includes-only-padding.patch +net-fib-fib6_add-fix-potential-null-pointer-dereference.patch +net-sctp-fix-bug-in-sctp_poll-for-sock_select_err_queue.patch +net-sctp-fix-smatch-warning-in-sctp_send_asconf_del_ip.patch +net-fix-multiqueue-selection.patch +net-flow_dissector-fix-thoff-for-ipproto_ah.patch +net_sched-htb-fix-a-typo-in-htb_change_class.patch +r8169-enforce-rx_multi_en-for-the-8168f.patch +netpoll-should-handle-eth_p_arp-other-than-eth_p_ip-in-netpoll_neigh_reply.patch +netpoll-fix-null-pointer-dereference-in-netpoll_cleanup.patch +tuntap-correctly-handle-error-in-tun_set_iff.patch +net-sctp-fix-ipv6-ipsec-encryption-bug-in-sctp_v6_xmit.patch +xen-netback-count-number-required-slots-for-an-skb-more-carefully.patch +resubmit-bridge-fix-message_age_timer-calculation.patch +bridge-clamp-forward_delay-when-enabling-stp.patch +bridge-use-br_port_get_rtnl-within-rtnl-lock.patch +bridge-fix-null-pointer-deref-of-br_port_get_rcu.patch +ip6_tunnels-raddr-and-laddr-are-inverted-in-nl-msg.patch +net-sctp-rfc4443-do-not-report-icmp-redirects-to-user-space.patch +net-dccp-do-not-report-icmp-redirects-to-user-space.patch +ip-use-ip_hdr-in-__ip_make_skb-to-retrieve-ip-header.patch +ip-generate-unique-ip-identificator-if-local-fragmentation-is-allowed.patch +ipv6-udp-packets-following-an-ufo-enqueued-packet-need-also-be-handled-by-ufo.patch +via-rhine-fix-vlan-priority-field-pcp-ieee-802.1p.patch +ipv6-nat-do-not-drop-dnated-6to4-6rd-packets.patch +net-net_secret-should-not-depend-on-tcp.patch +dm9601-fix-iff_allmulti-handling.patch +bonding-fix-broken-promiscuity-reference-counting-issue.patch +ipv6-gre-correct-calculation-of-max_headroom.patch +ipv4-igmp-use-in_dev_put-in-timer-handlers-instead-of-__in_dev_put.patch +ipv6-mcast-use-in6_dev_put-in-timer-handlers-instead-of-__in6_dev_put.patch +ll_temac-reset-dma-descriptors-indexes-on-ndo_open.patch +ip_tunnel-fix-a-memory-corruption-in-ip_tunnel_xmit.patch +sit-allow-to-use-rtnl-ops-on-fb-tunnel.patch +ip6tnl-allow-to-use-rtnl-ops-on-fb-tunnel.patch diff --git a/queue-3.10/sit-allow-to-use-rtnl-ops-on-fb-tunnel.patch b/queue-3.10/sit-allow-to-use-rtnl-ops-on-fb-tunnel.patch new file mode 100644 index 00000000000..4cd439c6996 --- /dev/null +++ b/queue-3.10/sit-allow-to-use-rtnl-ops-on-fb-tunnel.patch @@ -0,0 +1,34 @@ +From ac9c685da8618739023802e55982e79082e759de Mon Sep 17 00:00:00 2001 +From: Nicolas Dichtel +Date: Tue, 1 Oct 2013 18:04:59 +0200 +Subject: sit: allow to use rtnl ops on fb tunnel + +From: Nicolas Dichtel + +[ Upstream commit 205983c43700ac3a81e7625273a3fa83cd2759b5 ] + +rtnl ops where introduced by ba3e3f50a0e5 ("sit: advertise tunnel param via +rtnl"), but I forget to assign rtnl ops to fb tunnels. + +Now that it is done, we must remove the explicit call to +unregister_netdevice_queue(), because the fallback tunnel is added to the queue +in sit_destroy_tunnels() when checking rtnl_link_ops of all netdevices (this +is valid since commit 5e6700b3bf98 ("sit: add support of x-netns")). + +Signed-off-by: Nicolas Dichtel +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/sit.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/ipv6/sit.c ++++ b/net/ipv6/sit.c +@@ -1561,6 +1561,7 @@ static int __net_init sit_init_net(struc + goto err_alloc_dev; + } + dev_net_set(sitn->fb_tunnel_dev, net); ++ sitn->fb_tunnel_dev->rtnl_link_ops = &sit_link_ops; + + err = ipip6_fb_tunnel_init(sitn->fb_tunnel_dev); + if (err) diff --git a/queue-3.10/tcp-add-missing-braces-to-do_tcp_setsockopt.patch b/queue-3.10/tcp-add-missing-braces-to-do_tcp_setsockopt.patch new file mode 100644 index 00000000000..09d0e3cef5f --- /dev/null +++ b/queue-3.10/tcp-add-missing-braces-to-do_tcp_setsockopt.patch @@ -0,0 +1,32 @@ +From a24082ad423574b271fefac759257d426ffd032a Mon Sep 17 00:00:00 2001 +From: Dave Jones +Date: Thu, 5 Sep 2013 13:43:34 -0400 +Subject: tcp: Add missing braces to do_tcp_setsockopt + +From: Dave Jones + +[ Upstream commit e2e5c4c07caf810d7849658dca42f598b3938e21 ] + +Signed-off-by: Dave Jones +Acked-by: Neal Cardwell +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -2447,10 +2447,11 @@ static int do_tcp_setsockopt(struct sock + case TCP_THIN_DUPACK: + if (val < 0 || val > 1) + err = -EINVAL; +- else ++ else { + tp->thin_dupack = val; + if (tp->thin_dupack) + tcp_disable_early_retrans(tp); ++ } + break; + + case TCP_REPAIR: diff --git a/queue-3.10/tuntap-correctly-handle-error-in-tun_set_iff.patch b/queue-3.10/tuntap-correctly-handle-error-in-tun_set_iff.patch new file mode 100644 index 00000000000..d855b5300be --- /dev/null +++ b/queue-3.10/tuntap-correctly-handle-error-in-tun_set_iff.patch @@ -0,0 +1,59 @@ +From 091e93e54f0a795f3f156ce876a4fbe998e15e00 Mon Sep 17 00:00:00 2001 +From: Jason Wang +Date: Wed, 11 Sep 2013 18:09:48 +0800 +Subject: tuntap: correctly handle error in tun_set_iff() + +From: Jason Wang + +[ Upstream commit 662ca437e714caaab855b12415d6ffd815985bc0 ] + +Commit c8d68e6be1c3b242f1c598595830890b65cea64a +(tuntap: multiqueue support) only call free_netdev() on error in +tun_set_iff(). This causes several issues: + +- memory of tun security were leaked +- use after free since the flow gc timer was not deleted and the tfile + were not detached + +This patch solves the above issues. + +Reported-by: Wannes Rombouts +Cc: Michael S. Tsirkin +Signed-off-by: Jason Wang +Acked-by: Michael S. Tsirkin +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/tun.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -1693,11 +1693,11 @@ static int tun_set_iff(struct net *net, + INIT_LIST_HEAD(&tun->disabled); + err = tun_attach(tun, file); + if (err < 0) +- goto err_free_dev; ++ goto err_free_flow; + + err = register_netdevice(tun->dev); + if (err < 0) +- goto err_free_dev; ++ goto err_detach; + + if (device_create_file(&tun->dev->dev, &dev_attr_tun_flags) || + device_create_file(&tun->dev->dev, &dev_attr_owner) || +@@ -1741,7 +1741,12 @@ static int tun_set_iff(struct net *net, + strcpy(ifr->ifr_name, tun->dev->name); + return 0; + +- err_free_dev: ++err_detach: ++ tun_detach_all(dev); ++err_free_flow: ++ tun_flow_uninit(tun); ++ security_tun_dev_free_security(tun->security); ++err_free_dev: + free_netdev(dev); + return err; + } diff --git a/queue-3.10/via-rhine-fix-vlan-priority-field-pcp-ieee-802.1p.patch b/queue-3.10/via-rhine-fix-vlan-priority-field-pcp-ieee-802.1p.patch new file mode 100644 index 00000000000..67a7950a968 --- /dev/null +++ b/queue-3.10/via-rhine-fix-vlan-priority-field-pcp-ieee-802.1p.patch @@ -0,0 +1,48 @@ +From 49dd3e14a5389e365b016913de25a97dd838c468 Mon Sep 17 00:00:00 2001 +From: Roger Luethi +Date: Sat, 21 Sep 2013 14:24:11 +0200 +Subject: via-rhine: fix VLAN priority field (PCP, IEEE 802.1p) + +From: Roger Luethi + +[ Upstream commit 207070f5221e2a901d56a49df9cde47d9b716cd7 ] + +Outgoing packets sent by via-rhine have their VLAN PCP field off by one +(when hardware acceleration is enabled). The TX descriptor expects only VID +and PCP (without a CFI/DEI bit). + +Peter Boström noticed and reported the bug. + +Signed-off-by: Roger Luethi +Cc: Peter Boström +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/via/via-rhine.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/via/via-rhine.c ++++ b/drivers/net/ethernet/via/via-rhine.c +@@ -32,7 +32,7 @@ + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + + #define DRV_NAME "via-rhine" +-#define DRV_VERSION "1.5.0" ++#define DRV_VERSION "1.5.1" + #define DRV_RELDATE "2010-10-09" + + #include +@@ -1694,7 +1694,12 @@ static netdev_tx_t rhine_start_tx(struct + cpu_to_le32(TXDESC | (skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN)); + + if (unlikely(vlan_tx_tag_present(skb))) { +- rp->tx_ring[entry].tx_status = cpu_to_le32((vlan_tx_tag_get(skb)) << 16); ++ u16 vid_pcp = vlan_tx_tag_get(skb); ++ ++ /* drop CFI/DEI bit, register needs VID and PCP */ ++ vid_pcp = (vid_pcp & VLAN_VID_MASK) | ++ ((vid_pcp & VLAN_PRIO_MASK) >> 1); ++ rp->tx_ring[entry].tx_status = cpu_to_le32((vid_pcp) << 16); + /* request tagging */ + rp->tx_ring[entry].desc_length |= cpu_to_le32(0x020000); + } diff --git a/queue-3.10/xen-netback-count-number-required-slots-for-an-skb-more-carefully.patch b/queue-3.10/xen-netback-count-number-required-slots-for-an-skb-more-carefully.patch new file mode 100644 index 00000000000..3ec5e6339a4 --- /dev/null +++ b/queue-3.10/xen-netback-count-number-required-slots-for-an-skb-more-carefully.patch @@ -0,0 +1,175 @@ +From 32d742bd7e4ac89e8ed552b1c99809036c4dd66e Mon Sep 17 00:00:00 2001 +From: David Vrabel +Date: Wed, 11 Sep 2013 14:52:48 +0100 +Subject: xen-netback: count number required slots for an skb more carefully + +From: David Vrabel + +[ Upstream commit 6e43fc04a6bc357d260583b8440882f28069207f ] + +When a VM is providing an iSCSI target and the LUN is used by the +backend domain, the generated skbs for direct I/O writes to the disk +have large, multi-page skb->data but no frags. + +With some lengths and starting offsets, xen_netbk_count_skb_slots() +would be one short because the simple calculation of +DIV_ROUND_UP(skb_headlen(), PAGE_SIZE) was not accounting for the +decisions made by start_new_rx_buffer() which does not guarantee +responses are fully packed. + +For example, a skb with length < 2 pages but which spans 3 pages would +be counted as requiring 2 slots but would actually use 3 slots. + +skb->data: + + | 1111|222222222222|3333 | + +Fully packed, this would need 2 slots: + + |111122222222|22223333 | + +But because the 2nd page wholy fits into a slot it is not split across +slots and goes into a slot of its own: + + |1111 |222222222222|3333 | + +Miscounting the number of slots means netback may push more responses +than the number of available requests. This will cause the frontend +to get very confused and report "Too many frags/slots". The frontend +never recovers and will eventually BUG. + +Fix this by counting the number of required slots more carefully. In +xen_netbk_count_skb_slots(), more closely follow the algorithm used by +xen_netbk_gop_skb() by introducing xen_netbk_count_frag_slots() which +is the dry-run equivalent of netbk_gop_frag_copy(). + +Signed-off-by: David Vrabel +Acked-by: Ian Campbell +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/xen-netback/netback.c | 94 +++++++++++++++++++++++++------------- + 1 file changed, 64 insertions(+), 30 deletions(-) + +--- a/drivers/net/xen-netback/netback.c ++++ b/drivers/net/xen-netback/netback.c +@@ -354,6 +354,49 @@ static bool start_new_rx_buffer(int offs + return false; + } + ++struct xenvif_count_slot_state { ++ unsigned long copy_off; ++ bool head; ++}; ++ ++unsigned int xenvif_count_frag_slots(struct xenvif *vif, ++ unsigned long offset, unsigned long size, ++ struct xenvif_count_slot_state *state) ++{ ++ unsigned count = 0; ++ ++ offset &= ~PAGE_MASK; ++ ++ while (size > 0) { ++ unsigned long bytes; ++ ++ bytes = PAGE_SIZE - offset; ++ ++ if (bytes > size) ++ bytes = size; ++ ++ if (start_new_rx_buffer(state->copy_off, bytes, state->head)) { ++ count++; ++ state->copy_off = 0; ++ } ++ ++ if (state->copy_off + bytes > MAX_BUFFER_OFFSET) ++ bytes = MAX_BUFFER_OFFSET - state->copy_off; ++ ++ state->copy_off += bytes; ++ ++ offset += bytes; ++ size -= bytes; ++ ++ if (offset == PAGE_SIZE) ++ offset = 0; ++ ++ state->head = false; ++ } ++ ++ return count; ++} ++ + /* + * Figure out how many ring slots we're going to need to send @skb to + * the guest. This function is essentially a dry run of +@@ -361,48 +404,39 @@ static bool start_new_rx_buffer(int offs + */ + unsigned int xen_netbk_count_skb_slots(struct xenvif *vif, struct sk_buff *skb) + { ++ struct xenvif_count_slot_state state; + unsigned int count; +- int i, copy_off; ++ unsigned char *data; ++ unsigned i; + +- count = DIV_ROUND_UP(skb_headlen(skb), PAGE_SIZE); ++ state.head = true; ++ state.copy_off = 0; + +- copy_off = skb_headlen(skb) % PAGE_SIZE; ++ /* Slot for the first (partial) page of data. */ ++ count = 1; + ++ /* Need a slot for the GSO prefix for GSO extra data? */ + if (skb_shinfo(skb)->gso_size) + count++; + +- for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { +- unsigned long size = skb_frag_size(&skb_shinfo(skb)->frags[i]); +- unsigned long offset = skb_shinfo(skb)->frags[i].page_offset; +- unsigned long bytes; +- +- offset &= ~PAGE_MASK; +- +- while (size > 0) { +- BUG_ON(offset >= PAGE_SIZE); +- BUG_ON(copy_off > MAX_BUFFER_OFFSET); ++ data = skb->data; ++ while (data < skb_tail_pointer(skb)) { ++ unsigned long offset = offset_in_page(data); ++ unsigned long size = PAGE_SIZE - offset; + +- bytes = PAGE_SIZE - offset; ++ if (data + size > skb_tail_pointer(skb)) ++ size = skb_tail_pointer(skb) - data; + +- if (bytes > size) +- bytes = size; ++ count += xenvif_count_frag_slots(vif, offset, size, &state); + +- if (start_new_rx_buffer(copy_off, bytes, 0)) { +- count++; +- copy_off = 0; +- } +- +- if (copy_off + bytes > MAX_BUFFER_OFFSET) +- bytes = MAX_BUFFER_OFFSET - copy_off; +- +- copy_off += bytes; ++ data += size; ++ } + +- offset += bytes; +- size -= bytes; ++ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { ++ unsigned long size = skb_frag_size(&skb_shinfo(skb)->frags[i]); ++ unsigned long offset = skb_shinfo(skb)->frags[i].page_offset; + +- if (offset == PAGE_SIZE) +- offset = 0; +- } ++ count += xenvif_count_frag_slots(vif, offset, size, &state); + } + return count; + }