From: Greg Kroah-Hartman Date: Sat, 13 Jun 2015 16:51:30 +0000 (-0700) Subject: 3.14-stable patches X-Git-Tag: v3.10.81~19 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=147aacd59e470333cb0351ec74fcb85a96992721;p=thirdparty%2Fkernel%2Fstable-queue.git 3.14-stable patches added patches: bridge-disable-softirqs-around-br_fdb_update-to-avoid-lockup.patch bridge-fix-parsing-of-mldv2-reports.patch ipv4-avoid-crashing-in-ip_error.patch ipv4-udp-verify-multicast-group-is-ours-in-upd_v4_early_demux.patch net-core-correct-an-over-stringent-device-loop-detection.patch net-dp83640-fix-broken-calibration-routine.patch net-dp83640-reinforce-locking-rules.patch net-phy-allow-eee-for-all-rgmii-variants.patch net_sched-invoke-attach-after-setting-dev-qdisc.patch tcp-ipv6-fix-flow-label-setting-in-time_wait-state.patch udp-fix-behavior-of-wrong-checksums.patch unix-caif-sk_socket-can-disappear-when-state-is-unlocked.patch x86-bpf_jit-fix-compilation-of-large-bpf-programs.patch xen-netback-read-hotplug-script-once-at-start-of-day.patch --- diff --git a/queue-3.14/bridge-disable-softirqs-around-br_fdb_update-to-avoid-lockup.patch b/queue-3.14/bridge-disable-softirqs-around-br_fdb_update-to-avoid-lockup.patch new file mode 100644 index 00000000000..3b22b548630 --- /dev/null +++ b/queue-3.14/bridge-disable-softirqs-around-br_fdb_update-to-avoid-lockup.patch @@ -0,0 +1,46 @@ +From foo@baz Sat Jun 13 09:49:06 PDT 2015 +From: Nikolay Aleksandrov +Date: Sat, 6 Jun 2015 06:49:00 -0700 +Subject: bridge: disable softirqs around br_fdb_update to avoid lockup + +From: Nikolay Aleksandrov + +[ Upstream commit c4c832f89dc468cf11dc0dd17206bace44526651 ] + +br_fdb_update() can be called in process context in the following way: +br_fdb_add() -> __br_fdb_add() -> br_fdb_update() (if NTF_USE flag is set) +so we need to disable softirqs because there are softirq users of the +hash_lock. One easy way to reproduce this is to modify the bridge utility +to set NTF_USE, enable stp and then set maxageing to a low value so +br_fdb_cleanup() is called frequently and then just add new entries in +a loop. This happens because br_fdb_cleanup() is called from timer/softirq +context. The spin locks in br_fdb_update were _bh before commit f8ae737deea1 +("[BRIDGE]: forwarding remove unneeded preempt and bh diasables") +and at the time that commit was correct because br_fdb_update() couldn't be +called from process context, but that changed after commit: +292d1398983f ("bridge: add NTF_USE support") +Using local_bh_disable/enable around br_fdb_update() allows us to keep +using the spin_lock/unlock in br_fdb_update for the fast-path. + +Signed-off-by: Nikolay Aleksandrov +Fixes: 292d1398983f ("bridge: add NTF_USE support") +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/bridge/br_fdb.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/bridge/br_fdb.c ++++ b/net/bridge/br_fdb.c +@@ -705,9 +705,11 @@ static int __br_fdb_add(struct ndmsg *nd + int err = 0; + + if (ndm->ndm_flags & NTF_USE) { ++ local_bh_disable(); + rcu_read_lock(); + br_fdb_update(p->br, p, addr, vid, true); + rcu_read_unlock(); ++ local_bh_enable(); + } else { + spin_lock_bh(&p->br->hash_lock); + err = fdb_add_entry(p, addr, ndm->ndm_state, diff --git a/queue-3.14/bridge-fix-parsing-of-mldv2-reports.patch b/queue-3.14/bridge-fix-parsing-of-mldv2-reports.patch new file mode 100644 index 00000000000..ec47ad1c676 --- /dev/null +++ b/queue-3.14/bridge-fix-parsing-of-mldv2-reports.patch @@ -0,0 +1,63 @@ +From foo@baz Sat Jun 13 09:49:06 PDT 2015 +From: Thadeu Lima de Souza Cascardo +Date: Fri, 22 May 2015 12:18:59 -0300 +Subject: bridge: fix parsing of MLDv2 reports + +From: Thadeu Lima de Souza Cascardo + +[ Upstream commit 47cc84ce0c2fe75c99ea5963c4b5704dd78ead54 ] + +When more than a multicast address is present in a MLDv2 report, all but +the first address is ignored, because the code breaks out of the loop if +there has not been an error adding that address. + +This has caused failures when two guests connected through the bridge +tried to communicate using IPv6. Neighbor discoveries would not be +transmitted to the other guest when both used a link-local address and a +static address. + +This only happens when there is a MLDv2 querier in the network. + +The fix will only break out of the loop when there is a failure adding a +multicast address. + +The mdb before the patch: + +dev ovirtmgmt port vnet0 grp ff02::1:ff7d:6603 temp +dev ovirtmgmt port vnet1 grp ff02::1:ff7d:6604 temp +dev ovirtmgmt port bond0.86 grp ff02::2 temp + +After the patch: + +dev ovirtmgmt port vnet0 grp ff02::1:ff7d:6603 temp +dev ovirtmgmt port vnet1 grp ff02::1:ff7d:6604 temp +dev ovirtmgmt port bond0.86 grp ff02::fb temp +dev ovirtmgmt port bond0.86 grp ff02::2 temp +dev ovirtmgmt port bond0.86 grp ff02::d temp +dev ovirtmgmt port vnet0 grp ff02::1:ff00:76 temp +dev ovirtmgmt port bond0.86 grp ff02::16 temp +dev ovirtmgmt port vnet1 grp ff02::1:ff00:77 temp +dev ovirtmgmt port bond0.86 grp ff02::1:ff00:def temp +dev ovirtmgmt port bond0.86 grp ff02::1:ffa1:40bf temp + +Fixes: 08b202b67264 ("bridge br_multicast: IPv6 MLD support.") +Reported-by: Rik Theys +Signed-off-by: Thadeu Lima de Souza Cascardo +Tested-by: Rik Theys +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/bridge/br_multicast.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/bridge/br_multicast.c ++++ b/net/bridge/br_multicast.c +@@ -1056,7 +1056,7 @@ static int br_ip6_multicast_mld2_report( + + err = br_ip6_multicast_add_group(br, port, &grec->grec_mca, + vid); +- if (!err) ++ if (err) + break; + } + diff --git a/queue-3.14/ipv4-avoid-crashing-in-ip_error.patch b/queue-3.14/ipv4-avoid-crashing-in-ip_error.patch new file mode 100644 index 00000000000..c33d36191dd --- /dev/null +++ b/queue-3.14/ipv4-avoid-crashing-in-ip_error.patch @@ -0,0 +1,60 @@ +From foo@baz Sat Jun 13 09:49:06 PDT 2015 +From: "Eric W. Biederman" +Date: Fri, 22 May 2015 04:58:12 -0500 +Subject: ipv4: Avoid crashing in ip_error + +From: "Eric W. Biederman" + +[ Upstream commit 381c759d9916c42959515ad34a6d467e24a88e93 ] + +ip_error does not check if in_dev is NULL before dereferencing it. + +IThe following sequence of calls is possible: +CPU A CPU B +ip_rcv_finish + ip_route_input_noref() + ip_route_input_slow() + inetdev_destroy() + dst_input() + +With the result that a network device can be destroyed while processing +an input packet. + +A crash was triggered with only unicast packets in flight, and +forwarding enabled on the only network device. The error condition +was created by the removal of the network device. + +As such it is likely the that error code was -EHOSTUNREACH, and the +action taken by ip_error (if in_dev had been accessible) would have +been to not increment any counters and to have tried and likely failed +to send an icmp error as the network device is going away. + +Therefore handle this weird case by just dropping the packet if +!in_dev. It will result in dropping the packet sooner, and will not +result in an actual change of behavior. + +Fixes: 251da4130115b ("ipv4: Cache ip_error() routes even when not forwarding.") +Reported-by: Vittorio Gambaletta +Tested-by: Vittorio Gambaletta +Signed-off-by: Vittorio Gambaletta +Signed-off-by: "Eric W. Biederman" +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/route.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -910,6 +910,10 @@ static int ip_error(struct sk_buff *skb) + bool send; + int code; + ++ /* IP on this device is disabled. */ ++ if (!in_dev) ++ goto out; ++ + net = dev_net(rt->dst.dev); + if (!IN_DEV_FORWARD(in_dev)) { + switch (rt->dst.error) { diff --git a/queue-3.14/ipv4-udp-verify-multicast-group-is-ours-in-upd_v4_early_demux.patch b/queue-3.14/ipv4-udp-verify-multicast-group-is-ours-in-upd_v4_early_demux.patch new file mode 100644 index 00000000000..336e58a8a85 --- /dev/null +++ b/queue-3.14/ipv4-udp-verify-multicast-group-is-ours-in-upd_v4_early_demux.patch @@ -0,0 +1,73 @@ +From foo@baz Sat Jun 13 09:49:06 PDT 2015 +From: Shawn Bohrer +Date: Wed, 3 Jun 2015 16:27:38 -0500 +Subject: ipv4/udp: Verify multicast group is ours in upd_v4_early_demux() + +From: Shawn Bohrer + +[ Upstream commit 6e540309326188f769e03bb4c6dd8ff6752930c2 ] + +421b3885bf6d56391297844f43fb7154a6396e12 "udp: ipv4: Add udp early +demux" introduced a regression that allowed sockets bound to INADDR_ANY +to receive packets from multicast groups that the socket had not joined. +For example a socket that had joined 224.168.2.9 could also receive +packets from 225.168.2.9 despite not having joined that group if +ip_early_demux is enabled. + +Fix this by calling ip_check_mc_rcu() in udp_v4_early_demux() to verify +that the multicast packet is indeed ours. + +Signed-off-by: Shawn Bohrer +Reported-by: Yurij M. Plotnikov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/udp.c | 18 +++++++++++++++--- + 1 file changed, 15 insertions(+), 3 deletions(-) + +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -90,6 +90,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -1922,6 +1923,7 @@ void udp_v4_early_demux(struct sk_buff * + struct sock *sk; + struct dst_entry *dst; + int dif = skb->dev->ifindex; ++ int ours; + + /* validate the packet */ + if (!pskb_may_pull(skb, skb_transport_offset(skb) + sizeof(struct udphdr))) +@@ -1931,14 +1933,24 @@ void udp_v4_early_demux(struct sk_buff * + uh = udp_hdr(skb); + + if (skb->pkt_type == PACKET_BROADCAST || +- skb->pkt_type == PACKET_MULTICAST) ++ skb->pkt_type == PACKET_MULTICAST) { ++ struct in_device *in_dev = __in_dev_get_rcu(skb->dev); ++ ++ if (!in_dev) ++ return; ++ ++ ours = ip_check_mc_rcu(in_dev, iph->daddr, iph->saddr, ++ iph->protocol); ++ if (!ours) ++ return; + sk = __udp4_lib_mcast_demux_lookup(net, uh->dest, iph->daddr, + uh->source, iph->saddr, dif); +- else if (skb->pkt_type == PACKET_HOST) ++ } else if (skb->pkt_type == PACKET_HOST) { + sk = __udp4_lib_demux_lookup(net, uh->dest, iph->daddr, + uh->source, iph->saddr, dif); +- else ++ } else { + return; ++ } + + if (!sk) + return; diff --git a/queue-3.14/net-core-correct-an-over-stringent-device-loop-detection.patch b/queue-3.14/net-core-correct-an-over-stringent-device-loop-detection.patch new file mode 100644 index 00000000000..8e3eab829d1 --- /dev/null +++ b/queue-3.14/net-core-correct-an-over-stringent-device-loop-detection.patch @@ -0,0 +1,53 @@ +From foo@baz Sat Jun 13 09:49:06 PDT 2015 +From: Vlad Yasevich +Date: Sat, 2 May 2015 21:33:44 -0400 +Subject: net: core: Correct an over-stringent device loop detection. + +From: Vlad Yasevich + +[ Upstream commit d66bf7dd27573ee5ea90484899ee952c19ccb194 ] + +The code in __netdev_upper_dev_link() has an over-stringent +loop detection logic that actually prevents valid configurations +from working correctly. + +In particular, the logic returns an error if an upper device +is already in the list of all upper devices for a given dev. +This particular check seems to be a overzealous as it disallows +perfectly valid configurations. For example: + # ip l a link eth0 name eth0.10 type vlan id 10 + # ip l a dev br0 typ bridge + # ip l s eth0.10 master br0 + # ip l s eth0 master br0 <--- Will fail + +If you switch the last two commands (add eth0 first), then both +will succeed. If after that, you remove eth0 and try to re-add +it, it will fail! + +It appears to be enough to simply check adj_list to keeps things +safe. + +I've tried stacking multiple devices multiple times in all different +combinations, and either rx_handler registration prevented the stacking +of the device linking cought the error. + +Signed-off-by: Vladislav Yasevich +Acked-by: Jiri Pirko +Acked-by: Veaceslav Falico +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/dev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -4903,7 +4903,7 @@ static int __netdev_upper_dev_link(struc + if (__netdev_find_adj(upper_dev, dev, &upper_dev->all_adj_list.upper)) + return -EBUSY; + +- if (__netdev_find_adj(dev, upper_dev, &dev->all_adj_list.upper)) ++ if (__netdev_find_adj(dev, upper_dev, &dev->adj_list.upper)) + return -EEXIST; + + if (master && netdev_master_upper_dev_get(dev)) diff --git a/queue-3.14/net-dp83640-fix-broken-calibration-routine.patch b/queue-3.14/net-dp83640-fix-broken-calibration-routine.patch new file mode 100644 index 00000000000..b094b42c483 --- /dev/null +++ b/queue-3.14/net-dp83640-fix-broken-calibration-routine.patch @@ -0,0 +1,38 @@ +From foo@baz Sat Jun 13 09:49:06 PDT 2015 +From: Richard Cochran +Date: Mon, 25 May 2015 11:55:43 +0200 +Subject: net: dp83640: fix broken calibration routine. + +From: Richard Cochran + +[ Upstream commit 397a253af5031de4a4612210055935309af4472c ] + +Currently, the calibration function that corrects the initial offsets +among multiple devices only works the first time. If the function is +called more than once, the calibration fails and bogus offsets will be +programmed into the devices. + +In a well hidden spot, the device documentation tells that trigger indexes +0 and 1 are special in allowing the TRIG_IF_LATE flag to actually work. + +This patch fixes the issue by using one of the special triggers during the +recalibration method. + +Signed-off-by: Richard Cochran +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/phy/dp83640.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/phy/dp83640.c ++++ b/drivers/net/phy/dp83640.c +@@ -45,7 +45,7 @@ + #define PSF_TX 0x1000 + #define EXT_EVENT 1 + #define CAL_EVENT 7 +-#define CAL_TRIGGER 7 ++#define CAL_TRIGGER 1 + #define PER_TRIGGER 6 + + #define MII_DP83640_MICR 0x11 diff --git a/queue-3.14/net-dp83640-reinforce-locking-rules.patch b/queue-3.14/net-dp83640-reinforce-locking-rules.patch new file mode 100644 index 00000000000..76ea0e07135 --- /dev/null +++ b/queue-3.14/net-dp83640-reinforce-locking-rules.patch @@ -0,0 +1,77 @@ +From foo@baz Sat Jun 13 09:49:06 PDT 2015 +From: Richard Cochran +Date: Mon, 25 May 2015 11:55:44 +0200 +Subject: net: dp83640: reinforce locking rules. + +From: Richard Cochran + +[ Upstream commit a935865c828c8cd20501f618c69f659a5b6d6a5f ] + +Callers of the ext_write function are supposed to hold a mutex that +protects the state of the dialed page, but one caller was missing the +lock from the very start, and over time the code has been changed +without following the rule. This patch cleans up the call sites in +violation of the rule. + +Signed-off-by: Richard Cochran +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/phy/dp83640.c | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +--- a/drivers/net/phy/dp83640.c ++++ b/drivers/net/phy/dp83640.c +@@ -442,7 +442,9 @@ static int ptp_dp83640_enable(struct ptp + else + evnt |= EVNT_RISE; + } ++ mutex_lock(&clock->extreg_lock); + ext_write(0, phydev, PAGE5, PTP_EVNT, evnt); ++ mutex_unlock(&clock->extreg_lock); + return 0; + + case PTP_CLK_REQ_PEROUT: +@@ -463,6 +465,8 @@ static u8 status_frame_src[6] = { 0x08, + + static void enable_status_frames(struct phy_device *phydev, bool on) + { ++ struct dp83640_private *dp83640 = phydev->priv; ++ struct dp83640_clock *clock = dp83640->clock; + u16 cfg0 = 0, ver; + + if (on) +@@ -470,9 +474,13 @@ static void enable_status_frames(struct + + ver = (PSF_PTPVER & VERSIONPTP_MASK) << VERSIONPTP_SHIFT; + ++ mutex_lock(&clock->extreg_lock); ++ + ext_write(0, phydev, PAGE5, PSF_CFG0, cfg0); + ext_write(0, phydev, PAGE6, PSF_CFG1, ver); + ++ mutex_unlock(&clock->extreg_lock); ++ + if (!phydev->attached_dev) { + pr_warn("expected to find an attached netdevice\n"); + return; +@@ -1063,11 +1071,18 @@ static int dp83640_config_init(struct ph + + if (clock->chosen && !list_empty(&clock->phylist)) + recalibrate(clock); +- else ++ else { ++ mutex_lock(&clock->extreg_lock); + enable_broadcast(phydev, clock->page, 1); ++ mutex_unlock(&clock->extreg_lock); ++ } + + enable_status_frames(phydev, true); ++ ++ mutex_lock(&clock->extreg_lock); + ext_write(0, phydev, PAGE4, PTP_CTL, PTP_ENABLE); ++ mutex_unlock(&clock->extreg_lock); ++ + return 0; + } + diff --git a/queue-3.14/net-phy-allow-eee-for-all-rgmii-variants.patch b/queue-3.14/net-phy-allow-eee-for-all-rgmii-variants.patch new file mode 100644 index 00000000000..89829ffc794 --- /dev/null +++ b/queue-3.14/net-phy-allow-eee-for-all-rgmii-variants.patch @@ -0,0 +1,44 @@ +From foo@baz Sat Jun 13 09:49:06 PDT 2015 +From: Florian Fainelli +Date: Fri, 15 May 2015 16:30:41 -0700 +Subject: net: phy: Allow EEE for all RGMII variants + +From: Florian Fainelli + +[ Upstream commit 7e14069651591c81046ffaec13c3dac8cb70f5fb ] + +RGMII interfaces come in multiple flavors: RGMII with transmit or +receive internal delay, no delays at all, or delays in both direction. + +This change extends the initial check for PHY_INTERFACE_MODE_RGMII to +cover all of these variants since EEE should be allowed for any of these +modes, since it is a property of the RGMII, hence Gigabit PHY capability +more than the RGMII electrical interface and its delays. + +Fixes: a59a4d192166 ("phy: add the EEE support and the way to access to the MMD registers") +Signed-off-by: Florian Fainelli +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/phy/phy.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/net/phy/phy.c ++++ b/drivers/net/phy/phy.c +@@ -965,12 +965,14 @@ int phy_init_eee(struct phy_device *phyd + { + /* According to 802.3az,the EEE is supported only in full duplex-mode. + * Also EEE feature is active when core is operating with MII, GMII +- * or RGMII. ++ * or RGMII (all kinds). Internal PHYs are also allowed to proceed and ++ * should return an error if they do not support EEE. + */ + if ((phydev->duplex == DUPLEX_FULL) && + ((phydev->interface == PHY_INTERFACE_MODE_MII) || + (phydev->interface == PHY_INTERFACE_MODE_GMII) || +- (phydev->interface == PHY_INTERFACE_MODE_RGMII))) { ++ (phydev->interface >= PHY_INTERFACE_MODE_RGMII && ++ phydev->interface <= PHY_INTERFACE_MODE_RGMII_TXID))) { + int eee_lp, eee_cap, eee_adv; + u32 lp, cap, adv; + int status; diff --git a/queue-3.14/net_sched-invoke-attach-after-setting-dev-qdisc.patch b/queue-3.14/net_sched-invoke-attach-after-setting-dev-qdisc.patch new file mode 100644 index 00000000000..cc458639c7e --- /dev/null +++ b/queue-3.14/net_sched-invoke-attach-after-setting-dev-qdisc.patch @@ -0,0 +1,110 @@ +From foo@baz Sat Jun 13 09:49:06 PDT 2015 +From: WANG Cong +Date: Tue, 26 May 2015 16:08:48 -0700 +Subject: net_sched: invoke ->attach() after setting dev->qdisc + +From: WANG Cong + +[ Upstream commit 86e363dc3b50bfd50a1f315934583fbda673ab8d ] + +For mq qdisc, we add per tx queue qdisc to root qdisc +for display purpose, however, that happens too early, +before the new dev->qdisc is finally set, this causes +q->list points to an old root qdisc which is going to be +freed right before assigning with a new one. + +Fix this by moving ->attach() after setting dev->qdisc. + +For the record, this fixes the following crash: + + ------------[ cut here ]------------ + WARNING: CPU: 1 PID: 975 at lib/list_debug.c:59 __list_del_entry+0x5a/0x98() + list_del corruption. prev->next should be ffff8800d1998ae8, but was 6b6b6b6b6b6b6b6b + CPU: 1 PID: 975 Comm: tc Not tainted 4.1.0-rc4+ #1019 + Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 + 0000000000000009 ffff8800d73fb928 ffffffff81a44e7f 0000000047574756 + ffff8800d73fb978 ffff8800d73fb968 ffffffff810790da ffff8800cfc4cd20 + ffffffff814e725b ffff8800d1998ae8 ffffffff82381250 0000000000000000 + Call Trace: + [] dump_stack+0x4c/0x65 + [] warn_slowpath_common+0x9c/0xb6 + [] ? __list_del_entry+0x5a/0x98 + [] warn_slowpath_fmt+0x46/0x48 + [] ? dev_graft_qdisc+0x5e/0x6a + [] __list_del_entry+0x5a/0x98 + [] list_del+0xe/0x2d + [] qdisc_list_del+0x1e/0x20 + [] qdisc_destroy+0x30/0xd6 + [] qdisc_graft+0x11d/0x243 + [] tc_get_qdisc+0x1a6/0x1d4 + [] ? mark_lock+0x2e/0x226 + [] rtnetlink_rcv_msg+0x181/0x194 + [] ? rtnl_lock+0x17/0x19 + [] ? rtnl_lock+0x17/0x19 + [] ? __rtnl_unlock+0x17/0x17 + [] netlink_rcv_skb+0x4d/0x93 + [] rtnetlink_rcv+0x26/0x2d + [] netlink_unicast+0xcb/0x150 + [] ? might_fault+0x59/0xa9 + [] netlink_sendmsg+0x4fa/0x51c + [] sock_sendmsg_nosec+0x12/0x1d + [] sock_sendmsg+0x29/0x2e + [] ___sys_sendmsg+0x1b4/0x23a + [] ? native_sched_clock+0x35/0x37 + [] ? sched_clock_local+0x12/0x72 + [] ? sched_clock_cpu+0x9e/0xb7 + [] ? current_kernel_time+0xe/0x32 + [] ? lock_release_holdtime.part.29+0x71/0x7f + [] ? read_seqcount_begin.constprop.27+0x5f/0x76 + [] ? trace_hardirqs_on_caller+0x17d/0x199 + [] ? __fget_light+0x50/0x78 + [] __sys_sendmsg+0x42/0x60 + [] SyS_sendmsg+0x12/0x1c + [] system_call_fastpath+0x12/0x6f + ---[ end trace ef29d3fb28e97ae7 ]--- + +For long term, we probably need to clean up the qdisc_graft() code +in case it hides other bugs like this. + +Fixes: 95dc19299f74 ("pkt_sched: give visibility to mq slave qdiscs") +Cc: Jamal Hadi Salim +Signed-off-by: Cong Wang +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/sched/sch_api.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/net/sched/sch_api.c ++++ b/net/sched/sch_api.c +@@ -812,10 +812,8 @@ static int qdisc_graft(struct net_device + if (dev->flags & IFF_UP) + dev_deactivate(dev); + +- if (new && new->ops->attach) { +- new->ops->attach(new); +- num_q = 0; +- } ++ if (new && new->ops->attach) ++ goto skip; + + for (i = 0; i < num_q; i++) { + struct netdev_queue *dev_queue = dev_ingress_queue(dev); +@@ -831,12 +829,16 @@ static int qdisc_graft(struct net_device + qdisc_destroy(old); + } + ++skip: + if (!ingress) { + notify_and_destroy(net, skb, n, classid, + dev->qdisc, new); + if (new && !new->ops->attach) + atomic_inc(&new->refcnt); + dev->qdisc = new ? : &noop_qdisc; ++ ++ if (new && new->ops->attach) ++ new->ops->attach(new); + } else { + notify_and_destroy(net, skb, n, classid, old, new); + } diff --git a/queue-3.14/series b/queue-3.14/series index 47644bd3afc..277ee782352 100644 --- a/queue-3.14/series +++ b/queue-3.14/series @@ -1 +1,15 @@ crush-ensuring-at-most-num-rep-osds-are-selected.patch +net-core-correct-an-over-stringent-device-loop-detection.patch +x86-bpf_jit-fix-compilation-of-large-bpf-programs.patch +net-phy-allow-eee-for-all-rgmii-variants.patch +tcp-ipv6-fix-flow-label-setting-in-time_wait-state.patch +ipv4-avoid-crashing-in-ip_error.patch +bridge-fix-parsing-of-mldv2-reports.patch +net-dp83640-fix-broken-calibration-routine.patch +net-dp83640-reinforce-locking-rules.patch +unix-caif-sk_socket-can-disappear-when-state-is-unlocked.patch +net_sched-invoke-attach-after-setting-dev-qdisc.patch +udp-fix-behavior-of-wrong-checksums.patch +xen-netback-read-hotplug-script-once-at-start-of-day.patch +ipv4-udp-verify-multicast-group-is-ours-in-upd_v4_early_demux.patch +bridge-disable-softirqs-around-br_fdb_update-to-avoid-lockup.patch diff --git a/queue-3.14/tcp-ipv6-fix-flow-label-setting-in-time_wait-state.patch b/queue-3.14/tcp-ipv6-fix-flow-label-setting-in-time_wait-state.patch new file mode 100644 index 00000000000..ce802df9117 --- /dev/null +++ b/queue-3.14/tcp-ipv6-fix-flow-label-setting-in-time_wait-state.patch @@ -0,0 +1,48 @@ +From foo@baz Sat Jun 13 09:49:06 PDT 2015 +From: Florent Fourcot +Date: Sat, 16 May 2015 00:24:59 +0200 +Subject: tcp/ipv6: fix flow label setting in TIME_WAIT state + +From: Florent Fourcot + +[ Upstream commit 21858cd02dabcf290564cbf4769b101eba54d7bb ] + +commit 1d13a96c74fc ("ipv6: tcp: fix flowlabel value in ACK messages +send from TIME_WAIT") added the flow label in the last TCP packets. +Unfortunately, it was not casted properly. + +This patch replace the buggy shift with be32_to_cpu/cpu_to_be32. + +Fixes: 1d13a96c74fc ("ipv6: tcp: fix flowlabel value in ACK messages") +Reported-by: Eric Dumazet +Signed-off-by: Florent Fourcot +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp_minisocks.c | 2 +- + net/ipv6/tcp_ipv6.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/net/ipv4/tcp_minisocks.c ++++ b/net/ipv4/tcp_minisocks.c +@@ -297,7 +297,7 @@ void tcp_time_wait(struct sock *sk, int + tw->tw_v6_daddr = sk->sk_v6_daddr; + tw->tw_v6_rcv_saddr = sk->sk_v6_rcv_saddr; + tw->tw_tclass = np->tclass; +- tw->tw_flowlabel = np->flow_label >> 12; ++ tw->tw_flowlabel = be32_to_cpu(np->flow_label & IPV6_FLOWLABEL_MASK); + tw->tw_ipv6only = np->ipv6only; + } + #endif +--- a/net/ipv6/tcp_ipv6.c ++++ b/net/ipv6/tcp_ipv6.c +@@ -905,7 +905,7 @@ static void tcp_v6_timewait_ack(struct s + tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, + tcp_time_stamp + tcptw->tw_ts_offset, + tcptw->tw_ts_recent, tcp_twsk_md5_key(tcptw), +- tw->tw_tclass, (tw->tw_flowlabel << 12)); ++ tw->tw_tclass, cpu_to_be32(tw->tw_flowlabel)); + + inet_twsk_put(tw); + } diff --git a/queue-3.14/udp-fix-behavior-of-wrong-checksums.patch b/queue-3.14/udp-fix-behavior-of-wrong-checksums.patch new file mode 100644 index 00000000000..00bd32aca37 --- /dev/null +++ b/queue-3.14/udp-fix-behavior-of-wrong-checksums.patch @@ -0,0 +1,63 @@ +From foo@baz Sat Jun 13 09:49:06 PDT 2015 +From: Eric Dumazet +Date: Sat, 30 May 2015 09:16:53 -0700 +Subject: udp: fix behavior of wrong checksums + +From: Eric Dumazet + +[ Upstream commit beb39db59d14990e401e235faf66a6b9b31240b0 ] + +We have two problems in UDP stack related to bogus checksums : + +1) We return -EAGAIN to application even if receive queue is not empty. + This breaks applications using edge trigger epoll() + +2) Under UDP flood, we can loop forever without yielding to other + processes, potentially hanging the host, especially on non SMP. + +This patch is an attempt to make things better. + +We might in the future add extra support for rt applications +wanting to better control time spent doing a recv() in a hostile +environment. For example we could validate checksums before queuing +packets in socket receive queue. + +Signed-off-by: Eric Dumazet +Cc: Willem de Bruijn +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/udp.c | 6 ++---- + net/ipv6/udp.c | 6 ++---- + 2 files changed, 4 insertions(+), 8 deletions(-) + +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -1317,10 +1317,8 @@ csum_copy_err: + } + unlock_sock_fast(sk, slow); + +- if (noblock) +- return -EAGAIN; +- +- /* starting over for a new packet */ ++ /* starting over for a new packet, but check if we need to yield */ ++ cond_resched(); + msg->msg_flags &= ~MSG_TRUNC; + goto try_again; + } +--- a/net/ipv6/udp.c ++++ b/net/ipv6/udp.c +@@ -515,10 +515,8 @@ csum_copy_err: + } + unlock_sock_fast(sk, slow); + +- if (noblock) +- return -EAGAIN; +- +- /* starting over for a new packet */ ++ /* starting over for a new packet, but check if we need to yield */ ++ cond_resched(); + msg->msg_flags &= ~MSG_TRUNC; + goto try_again; + } diff --git a/queue-3.14/unix-caif-sk_socket-can-disappear-when-state-is-unlocked.patch b/queue-3.14/unix-caif-sk_socket-can-disappear-when-state-is-unlocked.patch new file mode 100644 index 00000000000..86c79f47900 --- /dev/null +++ b/queue-3.14/unix-caif-sk_socket-can-disappear-when-state-is-unlocked.patch @@ -0,0 +1,71 @@ +From foo@baz Sat Jun 13 09:49:06 PDT 2015 +From: Mark Salyzyn +Date: Tue, 26 May 2015 08:22:19 -0700 +Subject: unix/caif: sk_socket can disappear when state is unlocked + +From: Mark Salyzyn + +[ Upstream commit b48732e4a48d80ed4a14812f0bab09560846514e ] + +got a rare NULL pointer dereference in clear_bit + +Signed-off-by: Mark Salyzyn +Acked-by: Hannes Frederic Sowa +---- +v2: switch to sock_flag(sk, SOCK_DEAD) and added net/caif/caif_socket.c +v3: return -ECONNRESET in upstream caller of wait function for SOCK_DEAD +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/caif/caif_socket.c | 8 ++++++++ + net/unix/af_unix.c | 8 ++++++++ + 2 files changed, 16 insertions(+) + +--- a/net/caif/caif_socket.c ++++ b/net/caif/caif_socket.c +@@ -332,6 +332,10 @@ static long caif_stream_data_wait(struct + release_sock(sk); + timeo = schedule_timeout(timeo); + lock_sock(sk); ++ ++ if (sock_flag(sk, SOCK_DEAD)) ++ break; ++ + clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); + } + +@@ -376,6 +380,10 @@ static int caif_stream_recvmsg(struct ki + struct sk_buff *skb; + + lock_sock(sk); ++ if (sock_flag(sk, SOCK_DEAD)) { ++ err = -ECONNRESET; ++ goto unlock; ++ } + skb = skb_dequeue(&sk->sk_receive_queue); + caif_check_flow_release(sk); + +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -1893,6 +1893,10 @@ static long unix_stream_data_wait(struct + unix_state_unlock(sk); + timeo = freezable_schedule_timeout(timeo); + unix_state_lock(sk); ++ ++ if (sock_flag(sk, SOCK_DEAD)) ++ break; ++ + clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); + } + +@@ -1957,6 +1961,10 @@ static int unix_stream_recvmsg(struct ki + struct sk_buff *skb, *last; + + unix_state_lock(sk); ++ if (sock_flag(sk, SOCK_DEAD)) { ++ err = -ECONNRESET; ++ goto unlock; ++ } + last = skb = skb_peek(&sk->sk_receive_queue); + again: + if (skb == NULL) { diff --git a/queue-3.14/x86-bpf_jit-fix-compilation-of-large-bpf-programs.patch b/queue-3.14/x86-bpf_jit-fix-compilation-of-large-bpf-programs.patch new file mode 100644 index 00000000000..10b237a7d79 --- /dev/null +++ b/queue-3.14/x86-bpf_jit-fix-compilation-of-large-bpf-programs.patch @@ -0,0 +1,46 @@ +From foo@baz Sat Jun 13 09:49:06 PDT 2015 +From: Alexei Starovoitov +Date: Fri, 22 May 2015 15:42:55 -0700 +Subject: x86: bpf_jit: fix compilation of large bpf programs + +From: Alexei Starovoitov + +[ Upstream commit 3f7352bf21f8fd7ba3e2fcef9488756f188e12be ] + +x86 has variable length encoding. x86 JIT compiler is trying +to pick the shortest encoding for given bpf instruction. +While doing so the jump targets are changing, so JIT is doing +multiple passes over the program. Typical program needs 3 passes. +Some very short programs converge with 2 passes. Large programs +may need 4 or 5. But specially crafted bpf programs may hit the +pass limit and if the program converges on the last iteration +the JIT compiler will be producing an image full of 'int 3' insns. +Fix this corner case by doing final iteration over bpf program. + +Fixes: 0a14842f5a3c ("net: filter: Just In Time compiler for x86-64") +Reported-by: Daniel Borkmann +Signed-off-by: Alexei Starovoitov +Tested-by: Daniel Borkmann +Acked-by: Daniel Borkmann +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/net/bpf_jit_comp.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/arch/x86/net/bpf_jit_comp.c ++++ b/arch/x86/net/bpf_jit_comp.c +@@ -211,7 +211,12 @@ void bpf_jit_compile(struct sk_filter *f + } + cleanup_addr = proglen; /* epilogue address */ + +- for (pass = 0; pass < 10; pass++) { ++ /* JITed image shrinks with every pass and the loop iterates ++ * until the image stops shrinking. Very large bpf programs ++ * may converge on the last pass. In such case do one more ++ * pass to emit the final image ++ */ ++ for (pass = 0; pass < 10 || image; pass++) { + u8 seen_or_pass0 = (pass == 0) ? (SEEN_XREG | SEEN_DATAREF | SEEN_MEM) : seen; + /* no prologue/epilogue for trivial filters (RET something) */ + proglen = 0; diff --git a/queue-3.14/xen-netback-read-hotplug-script-once-at-start-of-day.patch b/queue-3.14/xen-netback-read-hotplug-script-once-at-start-of-day.patch new file mode 100644 index 00000000000..bd22384c7ec --- /dev/null +++ b/queue-3.14/xen-netback-read-hotplug-script-once-at-start-of-day.patch @@ -0,0 +1,117 @@ +From foo@baz Sat Jun 13 09:49:06 PDT 2015 +From: Ian Campbell +Date: Mon, 1 Jun 2015 11:30:24 +0100 +Subject: xen: netback: read hotplug script once at start of day. + +From: Ian Campbell + +[ Upstream commit 31a418986a5852034d520a5bab546821ff1ccf3d ] + +When we come to tear things down in netback_remove() and generate the +uevent it is possible that the xenstore directory has already been +removed (details below). + +In such cases netback_uevent() won't be able to read the hotplug +script and will write a xenstore error node. + +A recent change to the hypervisor exposed this race such that we now +sometimes lose it (where apparently we didn't ever before). + +Instead read the hotplug script configuration during setup and use it +for the lifetime of the backend device. + +The apparently more obvious fix of moving the transition to +state=Closed in netback_remove() to after the uevent does not work +because it is possible that we are already in state=Closed (in +reaction to the guest having disconnected as it shutdown). Being +already in Closed means the toolstack is at liberty to start tearing +down the xenstore directories. In principal it might be possible to +arrange to unregister the device sooner (e.g on transition to Closing) +such that xenstore would still be there but this state machine is +fragile and prone to anger... + +A modern Xen system only relies on the hotplug uevent for driver +domains, when the backend is in the same domain as the toolstack it +will run the necessary setup/teardown directly in the correct sequence +wrt xenstore changes. + +Signed-off-by: Ian Campbell +Acked-by: Wei Liu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/xen-netback/xenbus.c | 33 +++++++++++++++++++-------------- + 1 file changed, 19 insertions(+), 14 deletions(-) + +--- a/drivers/net/xen-netback/xenbus.c ++++ b/drivers/net/xen-netback/xenbus.c +@@ -32,6 +32,8 @@ struct backend_info { + enum xenbus_state frontend_state; + struct xenbus_watch hotplug_status_watch; + u8 have_hotplug_status_watch:1; ++ ++ const char *hotplug_script; + }; + + static int connect_rings(struct backend_info *); +@@ -54,6 +56,7 @@ static int netback_remove(struct xenbus_ + xenvif_free(be->vif); + be->vif = NULL; + } ++ kfree(be->hotplug_script); + kfree(be); + dev_set_drvdata(&dev->dev, NULL); + return 0; +@@ -71,6 +74,7 @@ static int netback_probe(struct xenbus_d + struct xenbus_transaction xbt; + int err; + int sg; ++ const char *script; + struct backend_info *be = kzalloc(sizeof(struct backend_info), + GFP_KERNEL); + if (!be) { +@@ -157,6 +161,15 @@ static int netback_probe(struct xenbus_d + if (err) + pr_debug("Error writing feature-split-event-channels\n"); + ++ script = xenbus_read(XBT_NIL, dev->nodename, "script", NULL); ++ if (IS_ERR(script)) { ++ err = PTR_ERR(script); ++ xenbus_dev_fatal(dev, err, "reading script"); ++ goto fail; ++ } ++ ++ be->hotplug_script = script; ++ + err = xenbus_switch_state(dev, XenbusStateInitWait); + if (err) + goto fail; +@@ -187,22 +200,14 @@ static int netback_uevent(struct xenbus_ + struct kobj_uevent_env *env) + { + struct backend_info *be = dev_get_drvdata(&xdev->dev); +- char *val; + +- val = xenbus_read(XBT_NIL, xdev->nodename, "script", NULL); +- if (IS_ERR(val)) { +- int err = PTR_ERR(val); +- xenbus_dev_fatal(xdev, err, "reading script"); +- return err; +- } else { +- if (add_uevent_var(env, "script=%s", val)) { +- kfree(val); +- return -ENOMEM; +- } +- kfree(val); +- } ++ if (!be) ++ return 0; ++ ++ if (add_uevent_var(env, "script=%s", be->hotplug_script)) ++ return -ENOMEM; + +- if (!be || !be->vif) ++ if (!be->vif) + return 0; + + return add_uevent_var(env, "vif=%s", be->vif->dev->name);