From: Greg Kroah-Hartman Date: Thu, 19 Jun 2014 17:40:56 +0000 (-0700) Subject: 3.14-stable patches X-Git-Tag: v3.4.95~35 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8ceeeb2308c72e64261115a9925273fca7d26e5f;p=thirdparty%2Fkernel%2Fstable-queue.git 3.14-stable patches added patches: bridge-prevent-insertion-of-fdb-entry-with-disallowed.patch ipip-sit-fix-ipv4_-update_pmtu-redirect-calls.patch ipv4-fix-a-race-in-ip4_datagram_release_cb.patch ipv6-fix-regression-caused-by-efe4208-in.patch net-add-variants-of-capable-for-use-on-netlink.patch net-add-variants-of-capable-for-use-on-on-sockets.patch net-filter-fix-sparc32-typo.patch net-filter-fix-typo-in-sparc-bpf-jit.patch net-fix-inet_getid-and-ipv6_select_ident-bugs.patch net-force-a-list_del-in-unregister_netdevice_many.patch net-mlx4_core-keep-only-one-driver-entry-release.patch net-mlx4_core-preserve-pci_dev_data-after.patch net-move-the-permission-check-in.patch net-qmi_wwan-add-olivetti-olicard-modems.patch net-tunnels-enable-module-autoloading.patch net-use-netlink_ns_capable-to-verify-the-permisions.patch netlink-only-check-file-credentials-for-implicit.patch netlink-rate-limit-leftover-bytes-warning-and-print.patch netlink-rename-netlink_capable-netlink_allowed.patch qlcnic-info-leak-in-qlcnic_dcb_peer_app_info.patch rtnetlink-fix-userspace-api-breakage-for-iproute2.patch sctp-fix-sk_ack_backlog-wrap-around-problem.patch sfc-pio-restrict-to-64bit-arch-and-use-64-bit-writes.patch sh_eth-fix-sh7619-771x-support.patch sh_eth-use-rnc-mode-for-packet-reception.patch tcp-fix-cwnd-undo-on-dsack-in-f-rto.patch team-fix-mtu-setting.patch udp-ipv4-do-not-waste-time-in.patch vxlan-use-dev-needed_headroom-instead-of.patch --- diff --git a/queue-3.14/bridge-prevent-insertion-of-fdb-entry-with-disallowed.patch b/queue-3.14/bridge-prevent-insertion-of-fdb-entry-with-disallowed.patch new file mode 100644 index 00000000000..97f5f15c034 --- /dev/null +++ b/queue-3.14/bridge-prevent-insertion-of-fdb-entry-with-disallowed.patch @@ -0,0 +1,103 @@ +From foo@baz Thu Jun 19 10:28:46 PDT 2014 +From: Toshiaki Makita +Date: Mon, 26 May 2014 15:15:53 +0900 +Subject: bridge: Prevent insertion of FDB entry with disallowed + vlan + +From: Toshiaki Makita + +[ Upstream commit e0d7968ab6c8bce2437b36fa7f04117e333f196d ] + +br_handle_local_finish() is allowing us to insert an FDB entry with +disallowed vlan. For example, when port 1 and 2 are communicating in +vlan 10, and even if vlan 10 is disallowed on port 3, port 3 can +interfere with their communication by spoofed src mac address with +vlan id 10. + +Note: Even if it is judged that a frame should not be learned, it should +not be dropped because it is destined for not forwarding layer but higher +layer. See IEEE 802.1Q-2011 8.13.10. + +Signed-off-by: Toshiaki Makita +Acked-by: Vlad Yasevich +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/bridge/br_input.c | 4 ++-- + net/bridge/br_private.h | 7 +++++++ + net/bridge/br_vlan.c | 28 ++++++++++++++++++++++++++++ + 3 files changed, 37 insertions(+), 2 deletions(-) + +--- a/net/bridge/br_input.c ++++ b/net/bridge/br_input.c +@@ -147,8 +147,8 @@ static int br_handle_local_finish(struct + struct net_bridge_port *p = br_port_get_rcu(skb->dev); + u16 vid = 0; + +- br_vlan_get_tag(skb, &vid); +- if (p->flags & BR_LEARNING) ++ /* check if vlan is allowed, to avoid spoofing */ ++ if (p->flags & BR_LEARNING && br_should_learn(p, skb, &vid)) + br_fdb_update(p->br, p, eth_hdr(skb)->h_source, vid, false); + return 0; /* process further */ + } +--- a/net/bridge/br_private.h ++++ b/net/bridge/br_private.h +@@ -581,6 +581,7 @@ bool br_allowed_ingress(struct net_bridg + struct sk_buff *skb, u16 *vid); + bool br_allowed_egress(struct net_bridge *br, const struct net_port_vlans *v, + const struct sk_buff *skb); ++bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid); + struct sk_buff *br_handle_vlan(struct net_bridge *br, + const struct net_port_vlans *v, + struct sk_buff *skb); +@@ -647,6 +648,12 @@ static inline bool br_allowed_egress(str + { + return true; + } ++ ++static inline bool br_should_learn(struct net_bridge_port *p, ++ struct sk_buff *skb, u16 *vid) ++{ ++ return true; ++} + + static inline struct sk_buff *br_handle_vlan(struct net_bridge *br, + const struct net_port_vlans *v, +--- a/net/bridge/br_vlan.c ++++ b/net/bridge/br_vlan.c +@@ -241,6 +241,34 @@ bool br_allowed_egress(struct net_bridge + return false; + } + ++/* Called under RCU */ ++bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid) ++{ ++ struct net_bridge *br = p->br; ++ struct net_port_vlans *v; ++ ++ if (!br->vlan_enabled) ++ return true; ++ ++ v = rcu_dereference(p->vlan_info); ++ if (!v) ++ return false; ++ ++ br_vlan_get_tag(skb, vid); ++ if (!*vid) { ++ *vid = br_get_pvid(v); ++ if (*vid == VLAN_N_VID) ++ return false; ++ ++ return true; ++ } ++ ++ if (test_bit(*vid, v->vlan_bitmap)) ++ return true; ++ ++ return false; ++} ++ + /* Must be protected by RTNL. + * Must be called with vid in range from 1 to 4094 inclusive. + */ diff --git a/queue-3.14/ipip-sit-fix-ipv4_-update_pmtu-redirect-calls.patch b/queue-3.14/ipip-sit-fix-ipv4_-update_pmtu-redirect-calls.patch new file mode 100644 index 00000000000..27458d8f515 --- /dev/null +++ b/queue-3.14/ipip-sit-fix-ipv4_-update_pmtu-redirect-calls.patch @@ -0,0 +1,57 @@ +From foo@baz Thu Jun 19 10:28:46 PDT 2014 +From: Dmitry Popov +Date: Fri, 6 Jun 2014 23:19:21 +0400 +Subject: ipip, sit: fix ipv4_{update_pmtu,redirect} calls + +From: Dmitry Popov + +[ Upstream commit 2346829e641b804ece9ac9298136b56d9567c278 ] + +ipv4_{update_pmtu,redirect} were called with tunnel's ifindex (t->dev is a +tunnel netdevice). It caused wrong route lookup and failure of pmtu update or +redirect. We should use the same ifindex that we use in ip_route_output_* in +*tunnel_xmit code. It is t->parms.link . + +Signed-off-by: Dmitry Popov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/ipip.c | 4 ++-- + net/ipv6/sit.c | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +--- a/net/ipv4/ipip.c ++++ b/net/ipv4/ipip.c +@@ -149,13 +149,13 @@ static int ipip_err(struct sk_buff *skb, + + if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) { + ipv4_update_pmtu(skb, dev_net(skb->dev), info, +- t->dev->ifindex, 0, IPPROTO_IPIP, 0); ++ t->parms.link, 0, IPPROTO_IPIP, 0); + err = 0; + goto out; + } + + if (type == ICMP_REDIRECT) { +- ipv4_redirect(skb, dev_net(skb->dev), t->dev->ifindex, 0, ++ ipv4_redirect(skb, dev_net(skb->dev), t->parms.link, 0, + IPPROTO_IPIP, 0); + err = 0; + goto out; +--- a/net/ipv6/sit.c ++++ b/net/ipv6/sit.c +@@ -560,12 +560,12 @@ static int ipip6_err(struct sk_buff *skb + + if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) { + ipv4_update_pmtu(skb, dev_net(skb->dev), info, +- t->dev->ifindex, 0, IPPROTO_IPV6, 0); ++ t->parms.link, 0, IPPROTO_IPV6, 0); + err = 0; + goto out; + } + if (type == ICMP_REDIRECT) { +- ipv4_redirect(skb, dev_net(skb->dev), t->dev->ifindex, 0, ++ ipv4_redirect(skb, dev_net(skb->dev), t->parms.link, 0, + IPPROTO_IPV6, 0); + err = 0; + goto out; diff --git a/queue-3.14/ipv4-fix-a-race-in-ip4_datagram_release_cb.patch b/queue-3.14/ipv4-fix-a-race-in-ip4_datagram_release_cb.patch new file mode 100644 index 00000000000..dee0ac3d679 --- /dev/null +++ b/queue-3.14/ipv4-fix-a-race-in-ip4_datagram_release_cb.patch @@ -0,0 +1,178 @@ +From foo@baz Thu Jun 19 10:28:46 PDT 2014 +From: Eric Dumazet +Date: Tue, 10 Jun 2014 06:43:01 -0700 +Subject: ipv4: fix a race in ip4_datagram_release_cb() + +From: Eric Dumazet + +[ Upstream commit 9709674e68646cee5a24e3000b3558d25412203a ] + +Alexey gave a AddressSanitizer[1] report that finally gave a good hint +at where was the origin of various problems already reported by Dormando +in the past [2] + +Problem comes from the fact that UDP can have a lockless TX path, and +concurrent threads can manipulate sk_dst_cache, while another thread, +is holding socket lock and calls __sk_dst_set() in +ip4_datagram_release_cb() (this was added in linux-3.8) + +It seems that all we need to do is to use sk_dst_check() and +sk_dst_set() so that all the writers hold same spinlock +(sk->sk_dst_lock) to prevent corruptions. + +TCP stack do not need this protection, as all sk_dst_cache writers hold +the socket lock. + +[1] +https://code.google.com/p/address-sanitizer/wiki/AddressSanitizerForKernel + +AddressSanitizer: heap-use-after-free in ipv4_dst_check +Read of size 2 by thread T15453: + [] ipv4_dst_check+0x1a/0x90 ./net/ipv4/route.c:1116 + [] __sk_dst_check+0x89/0xe0 ./net/core/sock.c:531 + [] ip4_datagram_release_cb+0x46/0x390 ??:0 + [] release_sock+0x17a/0x230 ./net/core/sock.c:2413 + [] ip4_datagram_connect+0x462/0x5d0 ??:0 + [] inet_dgram_connect+0x76/0xd0 ./net/ipv4/af_inet.c:534 + [] SYSC_connect+0x15c/0x1c0 ./net/socket.c:1701 + [] SyS_connect+0xe/0x10 ./net/socket.c:1682 + [] system_call_fastpath+0x16/0x1b +./arch/x86/kernel/entry_64.S:629 + +Freed by thread T15455: + [] dst_destroy+0xa8/0x160 ./net/core/dst.c:251 + [] dst_release+0x45/0x80 ./net/core/dst.c:280 + [] ip4_datagram_connect+0xa1/0x5d0 ??:0 + [] inet_dgram_connect+0x76/0xd0 ./net/ipv4/af_inet.c:534 + [] SYSC_connect+0x15c/0x1c0 ./net/socket.c:1701 + [] SyS_connect+0xe/0x10 ./net/socket.c:1682 + [] system_call_fastpath+0x16/0x1b +./arch/x86/kernel/entry_64.S:629 + +Allocated by thread T15453: + [] dst_alloc+0x81/0x2b0 ./net/core/dst.c:171 + [] rt_dst_alloc+0x47/0x50 ./net/ipv4/route.c:1406 + [< inlined >] __ip_route_output_key+0x3e8/0xf70 +__mkroute_output ./net/ipv4/route.c:1939 + [] __ip_route_output_key+0x3e8/0xf70 ./net/ipv4/route.c:2161 + [] ip_route_output_flow+0x14/0x30 ./net/ipv4/route.c:2249 + [] ip4_datagram_connect+0x317/0x5d0 ??:0 + [] inet_dgram_connect+0x76/0xd0 ./net/ipv4/af_inet.c:534 + [] SYSC_connect+0x15c/0x1c0 ./net/socket.c:1701 + [] SyS_connect+0xe/0x10 ./net/socket.c:1682 + [] system_call_fastpath+0x16/0x1b +./arch/x86/kernel/entry_64.S:629 + +[2] +<4>[196727.311203] general protection fault: 0000 [#1] SMP +<4>[196727.311224] Modules linked in: xt_TEE xt_dscp xt_DSCP macvlan bridge coretemp crc32_pclmul ghash_clmulni_intel gpio_ich microcode ipmi_watchdog ipmi_devintf sb_edac edac_core lpc_ich mfd_core tpm_tis tpm tpm_bios ipmi_si ipmi_msghandler isci igb libsas i2c_algo_bit ixgbe ptp pps_core mdio +<4>[196727.311333] CPU: 17 PID: 0 Comm: swapper/17 Not tainted 3.10.26 #1 +<4>[196727.311344] Hardware name: Supermicro X9DRi-LN4+/X9DR3-LN4+/X9DRi-LN4+/X9DR3-LN4+, BIOS 3.0 07/05/2013 +<4>[196727.311364] task: ffff885e6f069700 ti: ffff885e6f072000 task.ti: ffff885e6f072000 +<4>[196727.311377] RIP: 0010:[] [] ipv4_dst_destroy+0x4f/0x80 +<4>[196727.311399] RSP: 0018:ffff885effd23a70 EFLAGS: 00010282 +<4>[196727.311409] RAX: dead000000200200 RBX: ffff8854c398ecc0 RCX: 0000000000000040 +<4>[196727.311423] RDX: dead000000100100 RSI: dead000000100100 RDI: dead000000200200 +<4>[196727.311437] RBP: ffff885effd23a80 R08: ffffffff815fd9e0 R09: ffff885d5a590800 +<4>[196727.311451] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 +<4>[196727.311464] R13: ffffffff81c8c280 R14: 0000000000000000 R15: ffff880e85ee16ce +<4>[196727.311510] FS: 0000000000000000(0000) GS:ffff885effd20000(0000) knlGS:0000000000000000 +<4>[196727.311554] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +<4>[196727.311581] CR2: 00007a46751eb000 CR3: 0000005e65688000 CR4: 00000000000407e0 +<4>[196727.311625] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +<4>[196727.311669] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 +<4>[196727.311713] Stack: +<4>[196727.311733] ffff8854c398ecc0 ffff8854c398ecc0 ffff885effd23ab0 ffffffff815b7f42 +<4>[196727.311784] ffff88be6595bc00 ffff8854c398ecc0 0000000000000000 ffff8854c398ecc0 +<4>[196727.311834] ffff885effd23ad0 ffffffff815b86c6 ffff885d5a590800 ffff8816827821c0 +<4>[196727.311885] Call Trace: +<4>[196727.311907] +<4>[196727.311912] [] dst_destroy+0x32/0xe0 +<4>[196727.311959] [] dst_release+0x56/0x80 +<4>[196727.311986] [] tcp_v4_do_rcv+0x2a5/0x4a0 +<4>[196727.312013] [] tcp_v4_rcv+0x7da/0x820 +<4>[196727.312041] [] ? ip_rcv_finish+0x360/0x360 +<4>[196727.312070] [] ? nf_hook_slow+0x7d/0x150 +<4>[196727.312097] [] ? ip_rcv_finish+0x360/0x360 +<4>[196727.312125] [] ip_local_deliver_finish+0xb2/0x230 +<4>[196727.312154] [] ip_local_deliver+0x4a/0x90 +<4>[196727.312183] [] ip_rcv_finish+0x119/0x360 +<4>[196727.312212] [] ip_rcv+0x22b/0x340 +<4>[196727.312242] [] ? macvlan_broadcast+0x160/0x160 [macvlan] +<4>[196727.312275] [] __netif_receive_skb_core+0x512/0x640 +<4>[196727.312308] [] ? kmem_cache_alloc+0x13b/0x150 +<4>[196727.312338] [] __netif_receive_skb+0x21/0x70 +<4>[196727.312368] [] netif_receive_skb+0x31/0xa0 +<4>[196727.312397] [] napi_gro_receive+0xe8/0x140 +<4>[196727.312433] [] ixgbe_poll+0x551/0x11f0 [ixgbe] +<4>[196727.312463] [] ? ip_rcv+0x22b/0x340 +<4>[196727.312491] [] net_rx_action+0x111/0x210 +<4>[196727.312521] [] ? __netif_receive_skb+0x21/0x70 +<4>[196727.312552] [] __do_softirq+0xd0/0x270 +<4>[196727.312583] [] call_softirq+0x1c/0x30 +<4>[196727.312613] [] do_softirq+0x55/0x90 +<4>[196727.312640] [] irq_exit+0x55/0x60 +<4>[196727.312668] [] do_IRQ+0x63/0xe0 +<4>[196727.312696] [] common_interrupt+0x6a/0x6a +<4>[196727.312722] +<1>[196727.313071] RIP [] ipv4_dst_destroy+0x4f/0x80 +<4>[196727.313100] RSP +<4>[196727.313377] ---[ end trace 64b3f14fae0f2e29 ]--- +<0>[196727.380908] Kernel panic - not syncing: Fatal exception in interrupt + +Reported-by: Alexey Preobrazhensky +Reported-by: dormando +Signed-off-by: Eric Dumazet +Fixes: 8141ed9fcedb2 ("ipv4: Add a socket release callback for datagram sockets") +Cc: Steffen Klassert +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/datagram.c | 20 +++++++++++++++----- + 1 file changed, 15 insertions(+), 5 deletions(-) + +--- a/net/ipv4/datagram.c ++++ b/net/ipv4/datagram.c +@@ -86,18 +86,26 @@ out: + } + EXPORT_SYMBOL(ip4_datagram_connect); + ++/* Because UDP xmit path can manipulate sk_dst_cache without holding ++ * socket lock, we need to use sk_dst_set() here, ++ * even if we own the socket lock. ++ */ + void ip4_datagram_release_cb(struct sock *sk) + { + const struct inet_sock *inet = inet_sk(sk); + const struct ip_options_rcu *inet_opt; + __be32 daddr = inet->inet_daddr; ++ struct dst_entry *dst; + struct flowi4 fl4; + struct rtable *rt; + +- if (! __sk_dst_get(sk) || __sk_dst_check(sk, 0)) +- return; +- + rcu_read_lock(); ++ ++ dst = __sk_dst_get(sk); ++ if (!dst || !dst->obsolete || dst->ops->check(dst, 0)) { ++ rcu_read_unlock(); ++ return; ++ } + inet_opt = rcu_dereference(inet->inet_opt); + if (inet_opt && inet_opt->opt.srr) + daddr = inet_opt->opt.faddr; +@@ -105,8 +113,10 @@ void ip4_datagram_release_cb(struct sock + inet->inet_saddr, inet->inet_dport, + inet->inet_sport, sk->sk_protocol, + RT_CONN_FLAGS(sk), sk->sk_bound_dev_if); +- if (!IS_ERR(rt)) +- __sk_dst_set(sk, &rt->dst); ++ ++ dst = !IS_ERR(rt) ? &rt->dst : NULL; ++ sk_dst_set(sk, dst); ++ + rcu_read_unlock(); + } + EXPORT_SYMBOL_GPL(ip4_datagram_release_cb); diff --git a/queue-3.14/ipv6-fix-regression-caused-by-efe4208-in.patch b/queue-3.14/ipv6-fix-regression-caused-by-efe4208-in.patch new file mode 100644 index 00000000000..9bcee0a818d --- /dev/null +++ b/queue-3.14/ipv6-fix-regression-caused-by-efe4208-in.patch @@ -0,0 +1,50 @@ +From foo@baz Thu Jun 19 10:28:46 PDT 2014 +From: Sven Wegener +Date: Thu, 29 May 2014 20:27:05 +0000 +Subject: ipv6: Fix regression caused by efe4208 in + udp_v6_mcast_next() + +From: Sven Wegener + +[ Upstream commit 3bfdc59a6c24608ed23e903f670aaf5f58c7a6f3 ] + +Commit efe4208 ("ipv6: make lookups simpler and faster") introduced a +regression in udp_v6_mcast_next(), resulting in multicast packets not +reaching the destination sockets under certain conditions. + +The packet's IPv6 addresses are wrongly compared to the IPv6 addresses +from the function's socket argument, which indicates the starting point +for looping, instead of the loop variable. If the addresses from the +first socket do not match the packet's addresses, no socket in the list +will match. + +Signed-off-by: Sven Wegener +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/udp.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/net/ipv6/udp.c ++++ b/net/ipv6/udp.c +@@ -716,15 +716,15 @@ static struct sock *udp_v6_mcast_next(st + if (inet->inet_dport != rmt_port) + continue; + } +- if (!ipv6_addr_any(&sk->sk_v6_daddr) && +- !ipv6_addr_equal(&sk->sk_v6_daddr, rmt_addr)) ++ if (!ipv6_addr_any(&s->sk_v6_daddr) && ++ !ipv6_addr_equal(&s->sk_v6_daddr, rmt_addr)) + continue; + + if (s->sk_bound_dev_if && s->sk_bound_dev_if != dif) + continue; + +- if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr)) { +- if (!ipv6_addr_equal(&sk->sk_v6_rcv_saddr, loc_addr)) ++ if (!ipv6_addr_any(&s->sk_v6_rcv_saddr)) { ++ if (!ipv6_addr_equal(&s->sk_v6_rcv_saddr, loc_addr)) + continue; + } + if (!inet6_mc_check(s, loc_addr, rmt_addr)) diff --git a/queue-3.14/net-add-variants-of-capable-for-use-on-netlink.patch b/queue-3.14/net-add-variants-of-capable-for-use-on-netlink.patch new file mode 100644 index 00000000000..5cbec955dcd --- /dev/null +++ b/queue-3.14/net-add-variants-of-capable-for-use-on-netlink.patch @@ -0,0 +1,113 @@ +From foo@baz Thu Jun 19 10:28:46 PDT 2014 +From: "Eric W. Biederman" +Date: Wed, 23 Apr 2014 14:28:03 -0700 +Subject: net: Add variants of capable for use on netlink + messages + +From: "Eric W. Biederman" + +[ Upstream commit aa4cf9452f469f16cea8c96283b641b4576d4a7b ] + +netlink_net_capable - The common case use, for operations that are safe on a network namespace +netlink_capable - For operations that are only known to be safe for the global root +netlink_ns_capable - The general case of capable used to handle special cases + +__netlink_ns_capable - Same as netlink_ns_capable except taking a netlink_skb_parms instead of + the skbuff of a netlink message. + +Signed-off-by: "Eric W. Biederman" +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/netlink.h | 7 +++++ + net/netlink/af_netlink.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 72 insertions(+) + +--- a/include/linux/netlink.h ++++ b/include/linux/netlink.h +@@ -169,4 +169,11 @@ struct netlink_tap { + extern int netlink_add_tap(struct netlink_tap *nt); + extern int netlink_remove_tap(struct netlink_tap *nt); + ++bool __netlink_ns_capable(const struct netlink_skb_parms *nsp, ++ struct user_namespace *ns, int cap); ++bool netlink_ns_capable(const struct sk_buff *skb, ++ struct user_namespace *ns, int cap); ++bool netlink_capable(const struct sk_buff *skb, int cap); ++bool netlink_net_capable(const struct sk_buff *skb, int cap); ++ + #endif /* __LINUX_NETLINK_H */ +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -1360,6 +1360,71 @@ retry: + return err; + } + ++/** ++ * __netlink_ns_capable - General netlink message capability test ++ * @nsp: NETLINK_CB of the socket buffer holding a netlink command from userspace. ++ * @user_ns: The user namespace of the capability to use ++ * @cap: The capability to use ++ * ++ * Test to see if the opener of the socket we received the message ++ * from had when the netlink socket was created and the sender of the ++ * message has has the capability @cap in the user namespace @user_ns. ++ */ ++bool __netlink_ns_capable(const struct netlink_skb_parms *nsp, ++ struct user_namespace *user_ns, int cap) ++{ ++ return sk_ns_capable(nsp->sk, user_ns, cap); ++} ++EXPORT_SYMBOL(__netlink_ns_capable); ++ ++/** ++ * netlink_ns_capable - General netlink message capability test ++ * @skb: socket buffer holding a netlink command from userspace ++ * @user_ns: The user namespace of the capability to use ++ * @cap: The capability to use ++ * ++ * Test to see if the opener of the socket we received the message ++ * from had when the netlink socket was created and the sender of the ++ * message has has the capability @cap in the user namespace @user_ns. ++ */ ++bool netlink_ns_capable(const struct sk_buff *skb, ++ struct user_namespace *user_ns, int cap) ++{ ++ return __netlink_ns_capable(&NETLINK_CB(skb), user_ns, cap); ++} ++EXPORT_SYMBOL(netlink_ns_capable); ++ ++/** ++ * netlink_capable - Netlink global message capability test ++ * @skb: socket buffer holding a netlink command from userspace ++ * @cap: The capability to use ++ * ++ * Test to see if the opener of the socket we received the message ++ * from had when the netlink socket was created and the sender of the ++ * message has has the capability @cap in all user namespaces. ++ */ ++bool netlink_capable(const struct sk_buff *skb, int cap) ++{ ++ return netlink_ns_capable(skb, &init_user_ns, cap); ++} ++EXPORT_SYMBOL(netlink_capable); ++ ++/** ++ * netlink_net_capable - Netlink network namespace message capability test ++ * @skb: socket buffer holding a netlink command from userspace ++ * @cap: The capability to use ++ * ++ * Test to see if the opener of the socket we received the message ++ * from had when the netlink socket was created and the sender of the ++ * message has has the capability @cap over the network namespace of ++ * the socket we received the message from. ++ */ ++bool netlink_net_capable(const struct sk_buff *skb, int cap) ++{ ++ return netlink_ns_capable(skb, sock_net(skb->sk)->user_ns, cap); ++} ++EXPORT_SYMBOL(netlink_net_capable); ++ + static inline int netlink_allowed(const struct socket *sock, unsigned int flag) + { + return (nl_table[sock->sk->sk_protocol].flags & flag) || diff --git a/queue-3.14/net-add-variants-of-capable-for-use-on-on-sockets.patch b/queue-3.14/net-add-variants-of-capable-for-use-on-on-sockets.patch new file mode 100644 index 00000000000..4279b259793 --- /dev/null +++ b/queue-3.14/net-add-variants-of-capable-for-use-on-on-sockets.patch @@ -0,0 +1,93 @@ +From foo@baz Thu Jun 19 10:28:46 PDT 2014 +From: "Eric W. Biederman" +Date: Wed, 23 Apr 2014 14:26:56 -0700 +Subject: net: Add variants of capable for use on on sockets + +From: "Eric W. Biederman" + +[ Upstream commit a3b299da869d6e78cf42ae0b1b41797bcb8c5e4b ] + +sk_net_capable - The common case, operations that are safe in a network namespace. +sk_capable - Operations that are not known to be safe in a network namespace +sk_ns_capable - The general case for special cases. + +Signed-off-by: "Eric W. Biederman" +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/net/sock.h | 5 +++++ + net/core/sock.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 54 insertions(+) + +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -2278,6 +2278,11 @@ int sock_get_timestampns(struct sock *, + int sock_recv_errqueue(struct sock *sk, struct msghdr *msg, int len, int level, + int type); + ++bool sk_ns_capable(const struct sock *sk, ++ struct user_namespace *user_ns, int cap); ++bool sk_capable(const struct sock *sk, int cap); ++bool sk_net_capable(const struct sock *sk, int cap); ++ + /* + * Enable debug/info messages + */ +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -145,6 +145,55 @@ + static DEFINE_MUTEX(proto_list_mutex); + static LIST_HEAD(proto_list); + ++/** ++ * sk_ns_capable - General socket capability test ++ * @sk: Socket to use a capability on or through ++ * @user_ns: The user namespace of the capability to use ++ * @cap: The capability to use ++ * ++ * Test to see if the opener of the socket had when the socket was ++ * created and the current process has the capability @cap in the user ++ * namespace @user_ns. ++ */ ++bool sk_ns_capable(const struct sock *sk, ++ struct user_namespace *user_ns, int cap) ++{ ++ return file_ns_capable(sk->sk_socket->file, user_ns, cap) && ++ ns_capable(user_ns, cap); ++} ++EXPORT_SYMBOL(sk_ns_capable); ++ ++/** ++ * sk_capable - Socket global capability test ++ * @sk: Socket to use a capability on or through ++ * @cap: The global capbility to use ++ * ++ * Test to see if the opener of the socket had when the socket was ++ * created and the current process has the capability @cap in all user ++ * namespaces. ++ */ ++bool sk_capable(const struct sock *sk, int cap) ++{ ++ return sk_ns_capable(sk, &init_user_ns, cap); ++} ++EXPORT_SYMBOL(sk_capable); ++ ++/** ++ * sk_net_capable - Network namespace socket capability test ++ * @sk: Socket to use a capability on or through ++ * @cap: The capability to use ++ * ++ * Test to see if the opener of the socket had when the socke was created ++ * and the current process has the capability @cap over the network namespace ++ * the socket is a member of. ++ */ ++bool sk_net_capable(const struct sock *sk, int cap) ++{ ++ return sk_ns_capable(sk, sock_net(sk)->user_ns, cap); ++} ++EXPORT_SYMBOL(sk_net_capable); ++ ++ + #ifdef CONFIG_MEMCG_KMEM + int mem_cgroup_sockets_init(struct mem_cgroup *memcg, struct cgroup_subsys *ss) + { diff --git a/queue-3.14/net-filter-fix-sparc32-typo.patch b/queue-3.14/net-filter-fix-sparc32-typo.patch new file mode 100644 index 00000000000..058938d447c --- /dev/null +++ b/queue-3.14/net-filter-fix-sparc32-typo.patch @@ -0,0 +1,28 @@ +From foo@baz Thu Jun 19 10:28:46 PDT 2014 +From: Alexei Starovoitov +Date: Fri, 6 Jun 2014 08:35:59 -0700 +Subject: net: filter: fix sparc32 typo + +From: Alexei Starovoitov + +[ Upstream commit 588f5d629b3369aba88f52217d1c473a28fa7723 ] + +Fixes: 569810d1e327 ("net: filter: fix typo in sparc BPF JIT") +Signed-off-by: Alexei Starovoitov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + arch/sparc/net/bpf_jit_comp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/sparc/net/bpf_jit_comp.c ++++ b/arch/sparc/net/bpf_jit_comp.c +@@ -85,7 +85,7 @@ static void bpf_flush_icache(void *start + #ifdef CONFIG_SPARC64 + #define BE_PTR (F2(0, 1) | CONDE | (2 << 20)) + #else +-#define BE_PTR BNE ++#define BE_PTR BE + #endif + + #define SETHI(K, REG) \ diff --git a/queue-3.14/net-filter-fix-typo-in-sparc-bpf-jit.patch b/queue-3.14/net-filter-fix-typo-in-sparc-bpf-jit.patch new file mode 100644 index 00000000000..20076e85b08 --- /dev/null +++ b/queue-3.14/net-filter-fix-typo-in-sparc-bpf-jit.patch @@ -0,0 +1,52 @@ +From foo@baz Thu Jun 19 10:28:46 PDT 2014 +From: Alexei Starovoitov +Date: Thu, 5 Jun 2014 22:47:44 -0700 +Subject: net: filter: fix typo in sparc BPF JIT + +From: Alexei Starovoitov + +[ Upstream commit 569810d1e3278907264f5b115281fca3f0038d53 ] + +fix typo in sparc codegen for SKF_AD_IFINDEX and SKF_AD_HATYPE +classic BPF extensions + +Fixes: 2809a2087cc4 ("net: filter: Just In Time compiler for sparc") +Signed-off-by: Alexei Starovoitov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + arch/sparc/net/bpf_jit_comp.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/arch/sparc/net/bpf_jit_comp.c ++++ b/arch/sparc/net/bpf_jit_comp.c +@@ -83,9 +83,9 @@ static void bpf_flush_icache(void *start + #define BNE (F2(0, 2) | CONDNE) + + #ifdef CONFIG_SPARC64 +-#define BNE_PTR (F2(0, 1) | CONDNE | (2 << 20)) ++#define BE_PTR (F2(0, 1) | CONDE | (2 << 20)) + #else +-#define BNE_PTR BNE ++#define BE_PTR BNE + #endif + + #define SETHI(K, REG) \ +@@ -600,7 +600,7 @@ void bpf_jit_compile(struct sk_filter *f + case BPF_S_ANC_IFINDEX: + emit_skb_loadptr(dev, r_A); + emit_cmpi(r_A, 0); +- emit_branch(BNE_PTR, cleanup_addr + 4); ++ emit_branch(BE_PTR, cleanup_addr + 4); + emit_nop(); + emit_load32(r_A, struct net_device, ifindex, r_A); + break; +@@ -613,7 +613,7 @@ void bpf_jit_compile(struct sk_filter *f + case BPF_S_ANC_HATYPE: + emit_skb_loadptr(dev, r_A); + emit_cmpi(r_A, 0); +- emit_branch(BNE_PTR, cleanup_addr + 4); ++ emit_branch(BE_PTR, cleanup_addr + 4); + emit_nop(); + emit_load16(r_A, struct net_device, type, r_A); + break; diff --git a/queue-3.14/net-fix-inet_getid-and-ipv6_select_ident-bugs.patch b/queue-3.14/net-fix-inet_getid-and-ipv6_select_ident-bugs.patch new file mode 100644 index 00000000000..df485827fd3 --- /dev/null +++ b/queue-3.14/net-fix-inet_getid-and-ipv6_select_ident-bugs.patch @@ -0,0 +1,84 @@ +From foo@baz Thu Jun 19 10:28:46 PDT 2014 +From: Eric Dumazet +Date: Thu, 29 May 2014 08:45:14 -0700 +Subject: net: fix inet_getid() and ipv6_select_ident() bugs + +From: Eric Dumazet + +[ Upstream commit 39c36094d78c39e038c1e499b2364e13bce36f54 ] + +I noticed we were sending wrong IPv4 ID in TCP flows when MTU discovery +is disabled. +Note how GSO/TSO packets do not have monotonically incrementing ID. + +06:37:41.575531 IP (id 14227, proto: TCP (6), length: 4396) +06:37:41.575534 IP (id 14272, proto: TCP (6), length: 65212) +06:37:41.575544 IP (id 14312, proto: TCP (6), length: 57972) +06:37:41.575678 IP (id 14317, proto: TCP (6), length: 7292) +06:37:41.575683 IP (id 14361, proto: TCP (6), length: 63764) + +It appears I introduced this bug in linux-3.1. + +inet_getid() must return the old value of peer->ip_id_count, +not the new one. + +Lets revert this part, and remove the prevention of +a null identification field in IPv6 Fragment Extension Header, +which is dubious and not even done properly. + +Fixes: 87c48fa3b463 ("ipv6: make fragment identifications less predictable") +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/net/inetpeer.h | 9 +-------- + net/ipv6/output_core.c | 11 +++-------- + 2 files changed, 4 insertions(+), 16 deletions(-) + +--- a/include/net/inetpeer.h ++++ b/include/net/inetpeer.h +@@ -177,16 +177,9 @@ static inline void inet_peer_refcheck(co + /* can be called with or without local BH being disabled */ + static inline int inet_getid(struct inet_peer *p, int more) + { +- int old, new; + more++; + inet_peer_refcheck(p); +- do { +- old = atomic_read(&p->ip_id_count); +- new = old + more; +- if (!new) +- new = 1; +- } while (atomic_cmpxchg(&p->ip_id_count, old, new) != old); +- return new; ++ return atomic_add_return(more, &p->ip_id_count) - more; + } + + #endif /* _NET_INETPEER_H */ +--- a/net/ipv6/output_core.c ++++ b/net/ipv6/output_core.c +@@ -10,7 +10,7 @@ + void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt) + { + static atomic_t ipv6_fragmentation_id; +- int old, new; ++ int ident; + + #if IS_ENABLED(CONFIG_IPV6) + if (rt && !(rt->dst.flags & DST_NOPEER)) { +@@ -26,13 +26,8 @@ void ipv6_select_ident(struct frag_hdr * + } + } + #endif +- do { +- old = atomic_read(&ipv6_fragmentation_id); +- new = old + 1; +- if (!new) +- new = 1; +- } while (atomic_cmpxchg(&ipv6_fragmentation_id, old, new) != old); +- fhdr->identification = htonl(new); ++ ident = atomic_inc_return(&ipv6_fragmentation_id); ++ fhdr->identification = htonl(ident); + } + EXPORT_SYMBOL(ipv6_select_ident); + diff --git a/queue-3.14/net-force-a-list_del-in-unregister_netdevice_many.patch b/queue-3.14/net-force-a-list_del-in-unregister_netdevice_many.patch new file mode 100644 index 00000000000..6ec572a400c --- /dev/null +++ b/queue-3.14/net-force-a-list_del-in-unregister_netdevice_many.patch @@ -0,0 +1,86 @@ +From foo@baz Thu Jun 19 10:28:46 PDT 2014 +From: Eric Dumazet +Date: Fri, 6 Jun 2014 06:44:03 -0700 +Subject: net: force a list_del() in unregister_netdevice_many() + +From: Eric Dumazet + +[ Upstream commit 87757a917b0b3c0787e0563c679762152be81312 ] + +unregister_netdevice_many() API is error prone and we had too +many bugs because of dangling LIST_HEAD on stacks. + +See commit f87e6f47933e3e ("net: dont leave active on stack LIST_HEAD") + +In fact, instead of making sure no caller leaves an active list_head, +just force a list_del() in the callee. No one seems to need to access +the list after unregister_netdevice_many() + +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/macvlan.c | 1 - + net/core/dev.c | 5 ++++- + net/core/rtnetlink.c | 1 - + net/mac80211/iface.c | 1 - + 4 files changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/net/macvlan.c ++++ b/drivers/net/macvlan.c +@@ -1043,7 +1043,6 @@ static int macvlan_device_event(struct n + list_for_each_entry_safe(vlan, next, &port->vlans, list) + vlan->dev->rtnl_link_ops->dellink(vlan->dev, &list_kill); + unregister_netdevice_many(&list_kill); +- list_del(&list_kill); + break; + case NETDEV_PRE_TYPE_CHANGE: + /* Forbid underlaying device to change its type. */ +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -6548,6 +6548,9 @@ EXPORT_SYMBOL(unregister_netdevice_queue + /** + * unregister_netdevice_many - unregister many devices + * @head: list of devices ++ * ++ * Note: As most callers use a stack allocated list_head, ++ * we force a list_del() to make sure stack wont be corrupted later. + */ + void unregister_netdevice_many(struct list_head *head) + { +@@ -6557,6 +6560,7 @@ void unregister_netdevice_many(struct li + rollback_registered_many(head); + list_for_each_entry(dev, head, unreg_list) + net_set_todo(dev); ++ list_del(head); + } + } + EXPORT_SYMBOL(unregister_netdevice_many); +@@ -7012,7 +7016,6 @@ static void __net_exit default_device_ex + } + } + unregister_netdevice_many(&dev_kill_list); +- list_del(&dev_kill_list); + rtnl_unlock(); + } + +--- a/net/core/rtnetlink.c ++++ b/net/core/rtnetlink.c +@@ -1735,7 +1735,6 @@ static int rtnl_dellink(struct sk_buff * + + ops->dellink(dev, &list_kill); + unregister_netdevice_many(&list_kill); +- list_del(&list_kill); + return 0; + } + +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -1761,7 +1761,6 @@ void ieee80211_remove_interfaces(struct + } + mutex_unlock(&local->iflist_mtx); + unregister_netdevice_many(&unreg_list); +- list_del(&unreg_list); + + list_for_each_entry_safe(sdata, tmp, &wdev_list, list) { + list_del(&sdata->list); diff --git a/queue-3.14/net-mlx4_core-keep-only-one-driver-entry-release.patch b/queue-3.14/net-mlx4_core-keep-only-one-driver-entry-release.patch new file mode 100644 index 00000000000..900c69aa6ee --- /dev/null +++ b/queue-3.14/net-mlx4_core-keep-only-one-driver-entry-release.patch @@ -0,0 +1,46 @@ +From foo@baz Thu Jun 19 10:28:46 PDT 2014 +From: Wei Yang +Date: Sun, 8 Jun 2014 13:49:46 +0300 +Subject: net/mlx4_core: Keep only one driver entry release + mlx4_priv + +From: Wei Yang + +[ Upstream commit da1de8dfff09d33d4a5345762c21b487028e25f5 ] + +Following commit befdf89 "net/mlx4_core: Preserve pci_dev_data after +__mlx4_remove_one()", there are two mlx4 pci callbacks which will +attempt to release the mlx4_priv object -- .shutdown and .remove. + +This leads to a use-after-free access to the already freed mlx4_priv +instance and trigger a "Kernel access of bad area" crash when both +.shutdown and .remove are called. + +During reboot or kexec, .shutdown is called, with the VFs probed to +the host going through shutdown first and then the PF. Later, the PF +will trigger VFs' .remove since VFs still have driver attached. + +Fix that by keeping only one driver entry which releases mlx4_priv. + +Fixes: befdf89 ('net/mlx4_core: Preserve pci_dev_data after __mlx4_remove_one()') +CC: Bjorn Helgaas +Signed-off-by: Or Gerlitz +Signed-off-by: Jack Morgenstein +Signed-off-by: Wei Yang +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/mellanox/mlx4/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/mellanox/mlx4/main.c ++++ b/drivers/net/ethernet/mellanox/mlx4/main.c +@@ -2718,7 +2718,7 @@ static struct pci_driver mlx4_driver = { + .name = DRV_NAME, + .id_table = mlx4_pci_table, + .probe = mlx4_init_one, +- .shutdown = mlx4_remove_one, ++ .shutdown = __mlx4_remove_one, + .remove = mlx4_remove_one, + .err_handler = &mlx4_err_handler, + }; diff --git a/queue-3.14/net-mlx4_core-preserve-pci_dev_data-after.patch b/queue-3.14/net-mlx4_core-preserve-pci_dev_data-after.patch new file mode 100644 index 00000000000..48ca10acad7 --- /dev/null +++ b/queue-3.14/net-mlx4_core-preserve-pci_dev_data-after.patch @@ -0,0 +1,275 @@ +From foo@baz Thu Jun 19 10:28:46 PDT 2014 +From: Wei Yang +Date: Sun, 1 Jun 2014 15:24:35 +0800 +Subject: net/mlx4_core: Preserve pci_dev_data after + __mlx4_remove_one() + +From: Wei Yang + +[ Upstream commit befdf8978accecac2e0739e6b5075afc62db37fe ] + +pci_match_id() just match the static pci_device_id, which may return NULL if +someone binds the driver to a device manually using +/sys/bus/pci/drivers/.../new_id. + +This patch wrap up a helper function __mlx4_remove_one() which does the tear +down function but preserve the drv_data. Functions like +mlx4_pci_err_detected() and mlx4_restart_one() will call this one with out +releasing drvdata. + +Fixes: 97a5221 "net/mlx4_core: pass pci_device_id.driver_data to __mlx4_init_one during reset". + +CC: Bjorn Helgaas +CC: Amir Vadai +CC: Jack Morgenstein +CC: Or Gerlitz +Signed-off-by: Wei Yang +Acked-by: Jack Morgenstein +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/mellanox/mlx4/main.c | 168 ++++++++++++++++-------------- + drivers/net/ethernet/mellanox/mlx4/mlx4.h | 1 + 2 files changed, 94 insertions(+), 75 deletions(-) + +--- a/drivers/net/ethernet/mellanox/mlx4/main.c ++++ b/drivers/net/ethernet/mellanox/mlx4/main.c +@@ -2275,13 +2275,8 @@ static int __mlx4_init_one(struct pci_de + /* Allow large DMA segments, up to the firmware limit of 1 GB */ + dma_set_max_seg_size(&pdev->dev, 1024 * 1024 * 1024); + +- priv = kzalloc(sizeof(*priv), GFP_KERNEL); +- if (!priv) { +- err = -ENOMEM; +- goto err_release_regions; +- } +- +- dev = &priv->dev; ++ dev = pci_get_drvdata(pdev); ++ priv = mlx4_priv(dev); + dev->pdev = pdev; + INIT_LIST_HEAD(&priv->ctx_list); + spin_lock_init(&priv->ctx_lock); +@@ -2465,8 +2460,7 @@ slave_start: + mlx4_sense_init(dev); + mlx4_start_sense(dev); + +- priv->pci_dev_data = pci_dev_data; +- pci_set_drvdata(pdev, dev); ++ priv->removed = 0; + + return 0; + +@@ -2532,84 +2526,108 @@ err_disable_pdev: + + static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id) + { ++ struct mlx4_priv *priv; ++ struct mlx4_dev *dev; ++ + printk_once(KERN_INFO "%s", mlx4_version); + ++ priv = kzalloc(sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ dev = &priv->dev; ++ pci_set_drvdata(pdev, dev); ++ priv->pci_dev_data = id->driver_data; ++ + return __mlx4_init_one(pdev, id->driver_data); + } + +-static void mlx4_remove_one(struct pci_dev *pdev) ++static void __mlx4_remove_one(struct pci_dev *pdev) + { + struct mlx4_dev *dev = pci_get_drvdata(pdev); + struct mlx4_priv *priv = mlx4_priv(dev); ++ int pci_dev_data; + int p; + +- if (dev) { +- /* in SRIOV it is not allowed to unload the pf's +- * driver while there are alive vf's */ +- if (mlx4_is_master(dev)) { +- if (mlx4_how_many_lives_vf(dev)) +- printk(KERN_ERR "Removing PF when there are assigned VF's !!!\n"); +- } +- mlx4_stop_sense(dev); +- mlx4_unregister_device(dev); ++ if (priv->removed) ++ return; + +- for (p = 1; p <= dev->caps.num_ports; p++) { +- mlx4_cleanup_port_info(&priv->port[p]); +- mlx4_CLOSE_PORT(dev, p); +- } ++ pci_dev_data = priv->pci_dev_data; + +- if (mlx4_is_master(dev)) +- mlx4_free_resource_tracker(dev, +- RES_TR_FREE_SLAVES_ONLY); ++ /* in SRIOV it is not allowed to unload the pf's ++ * driver while there are alive vf's */ ++ if (mlx4_is_master(dev) && mlx4_how_many_lives_vf(dev)) ++ printk(KERN_ERR "Removing PF when there are assigned VF's !!!\n"); ++ mlx4_stop_sense(dev); ++ mlx4_unregister_device(dev); ++ ++ for (p = 1; p <= dev->caps.num_ports; p++) { ++ mlx4_cleanup_port_info(&priv->port[p]); ++ mlx4_CLOSE_PORT(dev, p); ++ } + +- mlx4_cleanup_counters_table(dev); +- mlx4_cleanup_qp_table(dev); +- mlx4_cleanup_srq_table(dev); +- mlx4_cleanup_cq_table(dev); +- mlx4_cmd_use_polling(dev); +- mlx4_cleanup_eq_table(dev); +- mlx4_cleanup_mcg_table(dev); +- mlx4_cleanup_mr_table(dev); +- mlx4_cleanup_xrcd_table(dev); +- mlx4_cleanup_pd_table(dev); ++ if (mlx4_is_master(dev)) ++ mlx4_free_resource_tracker(dev, ++ RES_TR_FREE_SLAVES_ONLY); + +- if (mlx4_is_master(dev)) +- mlx4_free_resource_tracker(dev, +- RES_TR_FREE_STRUCTS_ONLY); ++ mlx4_cleanup_counters_table(dev); ++ mlx4_cleanup_qp_table(dev); ++ mlx4_cleanup_srq_table(dev); ++ mlx4_cleanup_cq_table(dev); ++ mlx4_cmd_use_polling(dev); ++ mlx4_cleanup_eq_table(dev); ++ mlx4_cleanup_mcg_table(dev); ++ mlx4_cleanup_mr_table(dev); ++ mlx4_cleanup_xrcd_table(dev); ++ mlx4_cleanup_pd_table(dev); + +- iounmap(priv->kar); +- mlx4_uar_free(dev, &priv->driver_uar); +- mlx4_cleanup_uar_table(dev); +- if (!mlx4_is_slave(dev)) +- mlx4_clear_steering(dev); +- mlx4_free_eq_table(dev); +- if (mlx4_is_master(dev)) +- mlx4_multi_func_cleanup(dev); +- mlx4_close_hca(dev); +- if (mlx4_is_slave(dev)) +- mlx4_multi_func_cleanup(dev); +- mlx4_cmd_cleanup(dev); +- +- if (dev->flags & MLX4_FLAG_MSI_X) +- pci_disable_msix(pdev); +- if (dev->flags & MLX4_FLAG_SRIOV) { +- mlx4_warn(dev, "Disabling SR-IOV\n"); +- pci_disable_sriov(pdev); +- } ++ if (mlx4_is_master(dev)) ++ mlx4_free_resource_tracker(dev, ++ RES_TR_FREE_STRUCTS_ONLY); + +- if (!mlx4_is_slave(dev)) +- mlx4_free_ownership(dev); ++ iounmap(priv->kar); ++ mlx4_uar_free(dev, &priv->driver_uar); ++ mlx4_cleanup_uar_table(dev); ++ if (!mlx4_is_slave(dev)) ++ mlx4_clear_steering(dev); ++ mlx4_free_eq_table(dev); ++ if (mlx4_is_master(dev)) ++ mlx4_multi_func_cleanup(dev); ++ mlx4_close_hca(dev); ++ if (mlx4_is_slave(dev)) ++ mlx4_multi_func_cleanup(dev); ++ mlx4_cmd_cleanup(dev); + +- kfree(dev->caps.qp0_tunnel); +- kfree(dev->caps.qp0_proxy); +- kfree(dev->caps.qp1_tunnel); +- kfree(dev->caps.qp1_proxy); +- +- kfree(priv); +- pci_release_regions(pdev); +- pci_disable_device(pdev); +- pci_set_drvdata(pdev, NULL); ++ if (dev->flags & MLX4_FLAG_MSI_X) ++ pci_disable_msix(pdev); ++ if (dev->flags & MLX4_FLAG_SRIOV) { ++ mlx4_warn(dev, "Disabling SR-IOV\n"); ++ pci_disable_sriov(pdev); + } ++ ++ if (!mlx4_is_slave(dev)) ++ mlx4_free_ownership(dev); ++ ++ kfree(dev->caps.qp0_tunnel); ++ kfree(dev->caps.qp0_proxy); ++ kfree(dev->caps.qp1_tunnel); ++ kfree(dev->caps.qp1_proxy); ++ ++ pci_release_regions(pdev); ++ pci_disable_device(pdev); ++ memset(priv, 0, sizeof(*priv)); ++ priv->pci_dev_data = pci_dev_data; ++ priv->removed = 1; ++} ++ ++static void mlx4_remove_one(struct pci_dev *pdev) ++{ ++ struct mlx4_dev *dev = pci_get_drvdata(pdev); ++ struct mlx4_priv *priv = mlx4_priv(dev); ++ ++ __mlx4_remove_one(pdev); ++ kfree(priv); ++ pci_set_drvdata(pdev, NULL); + } + + int mlx4_restart_one(struct pci_dev *pdev) +@@ -2619,7 +2637,7 @@ int mlx4_restart_one(struct pci_dev *pde + int pci_dev_data; + + pci_dev_data = priv->pci_dev_data; +- mlx4_remove_one(pdev); ++ __mlx4_remove_one(pdev); + return __mlx4_init_one(pdev, pci_dev_data); + } + +@@ -2674,7 +2692,7 @@ MODULE_DEVICE_TABLE(pci, mlx4_pci_table) + static pci_ers_result_t mlx4_pci_err_detected(struct pci_dev *pdev, + pci_channel_state_t state) + { +- mlx4_remove_one(pdev); ++ __mlx4_remove_one(pdev); + + return state == pci_channel_io_perm_failure ? + PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_NEED_RESET; +@@ -2682,11 +2700,11 @@ static pci_ers_result_t mlx4_pci_err_det + + static pci_ers_result_t mlx4_pci_slot_reset(struct pci_dev *pdev) + { +- const struct pci_device_id *id; +- int ret; ++ struct mlx4_dev *dev = pci_get_drvdata(pdev); ++ struct mlx4_priv *priv = mlx4_priv(dev); ++ int ret; + +- id = pci_match_id(mlx4_pci_table, pdev); +- ret = __mlx4_init_one(pdev, id->driver_data); ++ ret = __mlx4_init_one(pdev, priv->pci_dev_data); + + return ret ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED; + } +--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h ++++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h +@@ -796,6 +796,7 @@ struct mlx4_priv { + spinlock_t ctx_lock; + + int pci_dev_data; ++ int removed; + + struct list_head pgdir_list; + struct mutex pgdir_mutex; diff --git a/queue-3.14/net-move-the-permission-check-in.patch b/queue-3.14/net-move-the-permission-check-in.patch new file mode 100644 index 00000000000..659566a04f3 --- /dev/null +++ b/queue-3.14/net-move-the-permission-check-in.patch @@ -0,0 +1,98 @@ +From foo@baz Thu Jun 19 10:28:46 PDT 2014 +From: "Eric W. Biederman" +Date: Wed, 23 Apr 2014 14:26:25 -0700 +Subject: net: Move the permission check in + sock_diag_put_filterinfo to packet_diag_dump + +From: "Eric W. Biederman" + +[ Upstream commit a53b72c83a4216f2eb883ed45a0cbce014b8e62d ] + +The permission check in sock_diag_put_filterinfo is wrong, and it is so removed +from it's sources it is not clear why it is wrong. Move the computation +into packet_diag_dump and pass a bool of the result into sock_diag_filterinfo. + +This does not yet correct the capability check but instead simply moves it to make +it clear what is going on. + +Reported-by: Andy Lutomirski +Signed-off-by: "Eric W. Biederman" +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/sock_diag.h | 2 +- + net/core/sock_diag.c | 4 ++-- + net/packet/diag.c | 7 ++++++- + 3 files changed, 9 insertions(+), 4 deletions(-) + +--- a/include/linux/sock_diag.h ++++ b/include/linux/sock_diag.h +@@ -23,7 +23,7 @@ int sock_diag_check_cookie(void *sk, __u + void sock_diag_save_cookie(void *sk, __u32 *cookie); + + int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attr); +-int sock_diag_put_filterinfo(struct sock *sk, ++int sock_diag_put_filterinfo(bool may_report_filterinfo, struct sock *sk, + struct sk_buff *skb, int attrtype); + + #endif +--- a/net/core/sock_diag.c ++++ b/net/core/sock_diag.c +@@ -49,7 +49,7 @@ int sock_diag_put_meminfo(struct sock *s + } + EXPORT_SYMBOL_GPL(sock_diag_put_meminfo); + +-int sock_diag_put_filterinfo(struct sock *sk, ++int sock_diag_put_filterinfo(bool may_report_filterinfo, struct sock *sk, + struct sk_buff *skb, int attrtype) + { + struct nlattr *attr; +@@ -57,7 +57,7 @@ int sock_diag_put_filterinfo(struct sock + unsigned int len; + int err = 0; + +- if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) { ++ if (!may_report_filterinfo) { + nla_reserve(skb, attrtype, 0); + return 0; + } +--- a/net/packet/diag.c ++++ b/net/packet/diag.c +@@ -128,6 +128,7 @@ static int pdiag_put_fanout(struct packe + + static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, + struct packet_diag_req *req, ++ bool may_report_filterinfo, + struct user_namespace *user_ns, + u32 portid, u32 seq, u32 flags, int sk_ino) + { +@@ -172,7 +173,8 @@ static int sk_diag_fill(struct sock *sk, + goto out_nlmsg_trim; + + if ((req->pdiag_show & PACKET_SHOW_FILTER) && +- sock_diag_put_filterinfo(sk, skb, PACKET_DIAG_FILTER)) ++ sock_diag_put_filterinfo(may_report_filterinfo, sk, skb, ++ PACKET_DIAG_FILTER)) + goto out_nlmsg_trim; + + return nlmsg_end(skb, nlh); +@@ -188,9 +190,11 @@ static int packet_diag_dump(struct sk_bu + struct packet_diag_req *req; + struct net *net; + struct sock *sk; ++ bool may_report_filterinfo; + + net = sock_net(skb->sk); + req = nlmsg_data(cb->nlh); ++ may_report_filterinfo = ns_capable(net->user_ns, CAP_NET_ADMIN); + + mutex_lock(&net->packet.sklist_lock); + sk_for_each(sk, &net->packet.sklist) { +@@ -200,6 +204,7 @@ static int packet_diag_dump(struct sk_bu + goto next; + + if (sk_diag_fill(sk, skb, req, ++ may_report_filterinfo, + sk_user_ns(NETLINK_CB(cb->skb).sk), + NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, NLM_F_MULTI, diff --git a/queue-3.14/net-qmi_wwan-add-olivetti-olicard-modems.patch b/queue-3.14/net-qmi_wwan-add-olivetti-olicard-modems.patch new file mode 100644 index 00000000000..87ab589c2b5 --- /dev/null +++ b/queue-3.14/net-qmi_wwan-add-olivetti-olicard-modems.patch @@ -0,0 +1,42 @@ +From foo@baz Thu Jun 19 10:28:46 PDT 2014 +From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= +Date: Fri, 6 Jun 2014 17:27:59 +0200 +Subject: net: qmi_wwan: add Olivetti Olicard modems +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= + +[ Upstream commit ba6de0f5304ccdc45ae260e7e0feb6e0ef2dd558 ] + +Lars writes: "I'm only 99% sure that the net interfaces are qmi +interfaces, nothing to lose by adding them in my opinion." + +And I tend to agree based on the similarity with the two Olicard +modems we already have here. + +Reported-by: Lars Melin +Signed-off-by: Bjørn Mork +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/usb/qmi_wwan.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/net/usb/qmi_wwan.c ++++ b/drivers/net/usb/qmi_wwan.c +@@ -752,7 +752,12 @@ static const struct usb_device_id produc + {QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */ + {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */ + {QMI_FIXED_INTF(0x1bc7, 0x1201, 2)}, /* Telit LE920 */ +- {QMI_FIXED_INTF(0x0b3c, 0xc005, 6)}, /* Olivetti Olicard 200 */ ++ {QMI_FIXED_INTF(0x0b3c, 0xc000, 4)}, /* Olivetti Olicard 100 */ ++ {QMI_FIXED_INTF(0x0b3c, 0xc001, 4)}, /* Olivetti Olicard 120 */ ++ {QMI_FIXED_INTF(0x0b3c, 0xc002, 4)}, /* Olivetti Olicard 140 */ ++ {QMI_FIXED_INTF(0x0b3c, 0xc004, 6)}, /* Olivetti Olicard 155 */ ++ {QMI_FIXED_INTF(0x0b3c, 0xc005, 6)}, /* Olivetti Olicard 200 */ ++ {QMI_FIXED_INTF(0x0b3c, 0xc00a, 6)}, /* Olivetti Olicard 160 */ + {QMI_FIXED_INTF(0x0b3c, 0xc00b, 4)}, /* Olivetti Olicard 500 */ + {QMI_FIXED_INTF(0x1e2d, 0x0060, 4)}, /* Cinterion PLxx */ + {QMI_FIXED_INTF(0x1e2d, 0x0053, 4)}, /* Cinterion PHxx,PXxx */ diff --git a/queue-3.14/net-tunnels-enable-module-autoloading.patch b/queue-3.14/net-tunnels-enable-module-autoloading.patch new file mode 100644 index 00000000000..6b17113a7a3 --- /dev/null +++ b/queue-3.14/net-tunnels-enable-module-autoloading.patch @@ -0,0 +1,49 @@ +From foo@baz Thu Jun 19 10:28:46 PDT 2014 +From: Tom Gundersen +Date: Thu, 15 May 2014 23:21:30 +0200 +Subject: net: tunnels - enable module autoloading + +From: Tom Gundersen + +[ Upstream commit f98f89a0104454f35a62d681683c844f6dbf4043 ] + +Enable the module alias hookup to allow tunnel modules to be autoloaded on demand. + +This is in line with how most other netdev kinds work, and will allow userspace +to create tunnels without having CAP_SYS_MODULE. + +Signed-off-by: Tom Gundersen +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/ipip.c | 1 + + net/ipv6/ip6_tunnel.c | 1 + + net/ipv6/sit.c | 1 + + 3 files changed, 3 insertions(+) + +--- a/net/ipv4/ipip.c ++++ b/net/ipv4/ipip.c +@@ -486,4 +486,5 @@ static void __exit ipip_fini(void) + module_init(ipip_init); + module_exit(ipip_fini); + MODULE_LICENSE("GPL"); ++MODULE_ALIAS_RTNL_LINK("ipip"); + MODULE_ALIAS_NETDEV("tunl0"); +--- a/net/ipv6/ip6_tunnel.c ++++ b/net/ipv6/ip6_tunnel.c +@@ -61,6 +61,7 @@ + MODULE_AUTHOR("Ville Nuorvala"); + MODULE_DESCRIPTION("IPv6 tunneling device"); + MODULE_LICENSE("GPL"); ++MODULE_ALIAS_RTNL_LINK("ip6tnl"); + MODULE_ALIAS_NETDEV("ip6tnl0"); + + #ifdef IP6_TNL_DEBUG +--- a/net/ipv6/sit.c ++++ b/net/ipv6/sit.c +@@ -1850,4 +1850,5 @@ xfrm_tunnel_failed: + module_init(sit_init); + module_exit(sit_cleanup); + MODULE_LICENSE("GPL"); ++MODULE_ALIAS_RTNL_LINK("sit"); + MODULE_ALIAS_NETDEV("sit0"); diff --git a/queue-3.14/net-use-netlink_ns_capable-to-verify-the-permisions.patch b/queue-3.14/net-use-netlink_ns_capable-to-verify-the-permisions.patch new file mode 100644 index 00000000000..cb117040f9f --- /dev/null +++ b/queue-3.14/net-use-netlink_ns_capable-to-verify-the-permisions.patch @@ -0,0 +1,395 @@ +From foo@baz Thu Jun 19 10:28:46 PDT 2014 +From: "Eric W. Biederman" +Date: Wed, 23 Apr 2014 14:29:27 -0700 +Subject: net: Use netlink_ns_capable to verify the permisions + of netlink messages + +From: "Eric W. Biederman" + +[ Upstream commit 90f62cf30a78721641e08737bda787552428061e ] + +It is possible by passing a netlink socket to a more privileged +executable and then to fool that executable into writing to the socket +data that happens to be valid netlink message to do something that +privileged executable did not intend to do. + +To keep this from happening replace bare capable and ns_capable calls +with netlink_capable, netlink_net_calls and netlink_ns_capable calls. +Which act the same as the previous calls except they verify that the +opener of the socket had the desired permissions as well. + +Reported-by: Andy Lutomirski +Signed-off-by: "Eric W. Biederman" +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + crypto/crypto_user.c | 2 +- + drivers/connector/cn_proc.c | 2 +- + drivers/scsi/scsi_netlink.c | 2 +- + kernel/audit.c | 4 ++-- + net/can/gw.c | 4 ++-- + net/core/rtnetlink.c | 20 +++++++++++--------- + net/dcb/dcbnl.c | 2 +- + net/decnet/dn_dev.c | 4 ++-- + net/decnet/dn_fib.c | 4 ++-- + net/decnet/netfilter/dn_rtmsg.c | 2 +- + net/netfilter/nfnetlink.c | 2 +- + net/netlink/genetlink.c | 2 +- + net/packet/diag.c | 2 +- + net/phonet/pn_netlink.c | 8 ++++---- + net/sched/act_api.c | 2 +- + net/sched/cls_api.c | 2 +- + net/sched/sch_api.c | 6 +++--- + net/tipc/netlink.c | 2 +- + net/xfrm/xfrm_user.c | 2 +- + 19 files changed, 38 insertions(+), 36 deletions(-) + +--- a/crypto/crypto_user.c ++++ b/crypto/crypto_user.c +@@ -466,7 +466,7 @@ static int crypto_user_rcv_msg(struct sk + type -= CRYPTO_MSG_BASE; + link = &crypto_dispatch[type]; + +- if (!capable(CAP_NET_ADMIN)) ++ if (!netlink_capable(skb, CAP_NET_ADMIN)) + return -EPERM; + + if ((type == (CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE) && +--- a/drivers/connector/cn_proc.c ++++ b/drivers/connector/cn_proc.c +@@ -369,7 +369,7 @@ static void cn_proc_mcast_ctl(struct cn_ + return; + + /* Can only change if privileged. */ +- if (!capable(CAP_NET_ADMIN)) { ++ if (!__netlink_ns_capable(nsp, &init_user_ns, CAP_NET_ADMIN)) { + err = EPERM; + goto out; + } +--- a/drivers/scsi/scsi_netlink.c ++++ b/drivers/scsi/scsi_netlink.c +@@ -77,7 +77,7 @@ scsi_nl_rcv_msg(struct sk_buff *skb) + goto next_msg; + } + +- if (!capable(CAP_SYS_ADMIN)) { ++ if (!netlink_capable(skb, CAP_SYS_ADMIN)) { + err = -EPERM; + goto next_msg; + } +--- a/kernel/audit.c ++++ b/kernel/audit.c +@@ -639,13 +639,13 @@ static int audit_netlink_ok(struct sk_bu + case AUDIT_TTY_SET: + case AUDIT_TRIM: + case AUDIT_MAKE_EQUIV: +- if (!capable(CAP_AUDIT_CONTROL)) ++ if (!netlink_capable(skb, CAP_AUDIT_CONTROL)) + err = -EPERM; + break; + case AUDIT_USER: + case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG: + case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2: +- if (!capable(CAP_AUDIT_WRITE)) ++ if (!netlink_capable(skb, CAP_AUDIT_WRITE)) + err = -EPERM; + break; + default: /* bad msg */ +--- a/net/can/gw.c ++++ b/net/can/gw.c +@@ -804,7 +804,7 @@ static int cgw_create_job(struct sk_buff + u8 limhops = 0; + int err = 0; + +- if (!capable(CAP_NET_ADMIN)) ++ if (!netlink_capable(skb, CAP_NET_ADMIN)) + return -EPERM; + + if (nlmsg_len(nlh) < sizeof(*r)) +@@ -893,7 +893,7 @@ static int cgw_remove_job(struct sk_buff + u8 limhops = 0; + int err = 0; + +- if (!capable(CAP_NET_ADMIN)) ++ if (!netlink_capable(skb, CAP_NET_ADMIN)) + return -EPERM; + + if (nlmsg_len(nlh) < sizeof(*r)) +--- a/net/core/rtnetlink.c ++++ b/net/core/rtnetlink.c +@@ -1428,7 +1428,8 @@ static int do_set_master(struct net_devi + return 0; + } + +-static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, ++static int do_setlink(const struct sk_buff *skb, ++ struct net_device *dev, struct ifinfomsg *ifm, + struct nlattr **tb, char *ifname, int modified) + { + const struct net_device_ops *ops = dev->netdev_ops; +@@ -1440,7 +1441,7 @@ static int do_setlink(struct net_device + err = PTR_ERR(net); + goto errout; + } +- if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) { ++ if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) { + err = -EPERM; + goto errout; + } +@@ -1694,7 +1695,7 @@ static int rtnl_setlink(struct sk_buff * + if (err < 0) + goto errout; + +- err = do_setlink(dev, ifm, tb, ifname, 0); ++ err = do_setlink(skb, dev, ifm, tb, ifname, 0); + errout: + return err; + } +@@ -1811,7 +1812,8 @@ err: + } + EXPORT_SYMBOL(rtnl_create_link); + +-static int rtnl_group_changelink(struct net *net, int group, ++static int rtnl_group_changelink(const struct sk_buff *skb, ++ struct net *net, int group, + struct ifinfomsg *ifm, + struct nlattr **tb) + { +@@ -1820,7 +1822,7 @@ static int rtnl_group_changelink(struct + + for_each_netdev(net, dev) { + if (dev->group == group) { +- err = do_setlink(dev, ifm, tb, NULL, 0); ++ err = do_setlink(skb, dev, ifm, tb, NULL, 0); + if (err < 0) + return err; + } +@@ -1962,12 +1964,12 @@ replay: + modified = 1; + } + +- return do_setlink(dev, ifm, tb, ifname, modified); ++ return do_setlink(skb, dev, ifm, tb, ifname, modified); + } + + if (!(nlh->nlmsg_flags & NLM_F_CREATE)) { + if (ifm->ifi_index == 0 && tb[IFLA_GROUP]) +- return rtnl_group_changelink(net, ++ return rtnl_group_changelink(skb, net, + nla_get_u32(tb[IFLA_GROUP]), + ifm, tb); + return -ENODEV; +@@ -2354,7 +2356,7 @@ static int rtnl_fdb_del(struct sk_buff * + int err = -EINVAL; + __u8 *addr; + +- if (!capable(CAP_NET_ADMIN)) ++ if (!netlink_capable(skb, CAP_NET_ADMIN)) + return -EPERM; + + err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL); +@@ -2806,7 +2808,7 @@ static int rtnetlink_rcv_msg(struct sk_b + sz_idx = type>>2; + kind = type&3; + +- if (kind != 2 && !ns_capable(net->user_ns, CAP_NET_ADMIN)) ++ if (kind != 2 && !netlink_net_capable(skb, CAP_NET_ADMIN)) + return -EPERM; + + if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) { +--- a/net/dcb/dcbnl.c ++++ b/net/dcb/dcbnl.c +@@ -1669,7 +1669,7 @@ static int dcb_doit(struct sk_buff *skb, + struct nlmsghdr *reply_nlh = NULL; + const struct reply_func *fn; + +- if ((nlh->nlmsg_type == RTM_SETDCB) && !capable(CAP_NET_ADMIN)) ++ if ((nlh->nlmsg_type == RTM_SETDCB) && !netlink_capable(skb, CAP_NET_ADMIN)) + return -EPERM; + + ret = nlmsg_parse(nlh, sizeof(*dcb), tb, DCB_ATTR_MAX, +--- a/net/decnet/dn_dev.c ++++ b/net/decnet/dn_dev.c +@@ -574,7 +574,7 @@ static int dn_nl_deladdr(struct sk_buff + struct dn_ifaddr __rcu **ifap; + int err = -EINVAL; + +- if (!capable(CAP_NET_ADMIN)) ++ if (!netlink_capable(skb, CAP_NET_ADMIN)) + return -EPERM; + + if (!net_eq(net, &init_net)) +@@ -618,7 +618,7 @@ static int dn_nl_newaddr(struct sk_buff + struct dn_ifaddr *ifa; + int err; + +- if (!capable(CAP_NET_ADMIN)) ++ if (!netlink_capable(skb, CAP_NET_ADMIN)) + return -EPERM; + + if (!net_eq(net, &init_net)) +--- a/net/decnet/dn_fib.c ++++ b/net/decnet/dn_fib.c +@@ -505,7 +505,7 @@ static int dn_fib_rtm_delroute(struct sk + struct nlattr *attrs[RTA_MAX+1]; + int err; + +- if (!capable(CAP_NET_ADMIN)) ++ if (!netlink_capable(skb, CAP_NET_ADMIN)) + return -EPERM; + + if (!net_eq(net, &init_net)) +@@ -530,7 +530,7 @@ static int dn_fib_rtm_newroute(struct sk + struct nlattr *attrs[RTA_MAX+1]; + int err; + +- if (!capable(CAP_NET_ADMIN)) ++ if (!netlink_capable(skb, CAP_NET_ADMIN)) + return -EPERM; + + if (!net_eq(net, &init_net)) +--- a/net/decnet/netfilter/dn_rtmsg.c ++++ b/net/decnet/netfilter/dn_rtmsg.c +@@ -107,7 +107,7 @@ static inline void dnrmg_receive_user_sk + if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len) + return; + +- if (!capable(CAP_NET_ADMIN)) ++ if (!netlink_capable(skb, CAP_NET_ADMIN)) + RCV_SKB_FAIL(-EPERM); + + /* Eventually we might send routing messages too */ +--- a/net/netfilter/nfnetlink.c ++++ b/net/netfilter/nfnetlink.c +@@ -367,7 +367,7 @@ static void nfnetlink_rcv(struct sk_buff + skb->len < nlh->nlmsg_len) + return; + +- if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) { ++ if (!netlink_net_capable(skb, CAP_NET_ADMIN)) { + netlink_ack(skb, nlh, -EPERM); + return; + } +--- a/net/netlink/genetlink.c ++++ b/net/netlink/genetlink.c +@@ -561,7 +561,7 @@ static int genl_family_rcv_msg(struct ge + return -EOPNOTSUPP; + + if ((ops->flags & GENL_ADMIN_PERM) && +- !capable(CAP_NET_ADMIN)) ++ !netlink_capable(skb, CAP_NET_ADMIN)) + return -EPERM; + + if ((nlh->nlmsg_flags & NLM_F_DUMP) == NLM_F_DUMP) { +--- a/net/packet/diag.c ++++ b/net/packet/diag.c +@@ -194,7 +194,7 @@ static int packet_diag_dump(struct sk_bu + + net = sock_net(skb->sk); + req = nlmsg_data(cb->nlh); +- may_report_filterinfo = ns_capable(net->user_ns, CAP_NET_ADMIN); ++ may_report_filterinfo = netlink_net_capable(cb->skb, CAP_NET_ADMIN); + + mutex_lock(&net->packet.sklist_lock); + sk_for_each(sk, &net->packet.sklist) { +--- a/net/phonet/pn_netlink.c ++++ b/net/phonet/pn_netlink.c +@@ -70,10 +70,10 @@ static int addr_doit(struct sk_buff *skb + int err; + u8 pnaddr; + +- if (!capable(CAP_NET_ADMIN)) ++ if (!netlink_capable(skb, CAP_NET_ADMIN)) + return -EPERM; + +- if (!capable(CAP_SYS_ADMIN)) ++ if (!netlink_capable(skb, CAP_SYS_ADMIN)) + return -EPERM; + + ASSERT_RTNL(); +@@ -233,10 +233,10 @@ static int route_doit(struct sk_buff *sk + int err; + u8 dst; + +- if (!capable(CAP_NET_ADMIN)) ++ if (!netlink_capable(skb, CAP_NET_ADMIN)) + return -EPERM; + +- if (!capable(CAP_SYS_ADMIN)) ++ if (!netlink_capable(skb, CAP_SYS_ADMIN)) + return -EPERM; + + ASSERT_RTNL(); +--- a/net/sched/act_api.c ++++ b/net/sched/act_api.c +@@ -908,7 +908,7 @@ static int tc_ctl_action(struct sk_buff + u32 portid = skb ? NETLINK_CB(skb).portid : 0; + int ret = 0, ovr = 0; + +- if ((n->nlmsg_type != RTM_GETACTION) && !capable(CAP_NET_ADMIN)) ++ if ((n->nlmsg_type != RTM_GETACTION) && !netlink_capable(skb, CAP_NET_ADMIN)) + return -EPERM; + + ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ACT_MAX, NULL); +--- a/net/sched/cls_api.c ++++ b/net/sched/cls_api.c +@@ -134,7 +134,7 @@ static int tc_ctl_tfilter(struct sk_buff + int err; + int tp_created = 0; + +- if ((n->nlmsg_type != RTM_GETTFILTER) && !capable(CAP_NET_ADMIN)) ++ if ((n->nlmsg_type != RTM_GETTFILTER) && !netlink_capable(skb, CAP_NET_ADMIN)) + return -EPERM; + + replay: +--- a/net/sched/sch_api.c ++++ b/net/sched/sch_api.c +@@ -1084,7 +1084,7 @@ static int tc_get_qdisc(struct sk_buff * + struct Qdisc *p = NULL; + int err; + +- if ((n->nlmsg_type != RTM_GETQDISC) && !capable(CAP_NET_ADMIN)) ++ if ((n->nlmsg_type != RTM_GETQDISC) && !netlink_capable(skb, CAP_NET_ADMIN)) + return -EPERM; + + err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); +@@ -1151,7 +1151,7 @@ static int tc_modify_qdisc(struct sk_buf + struct Qdisc *q, *p; + int err; + +- if (!capable(CAP_NET_ADMIN)) ++ if (!netlink_capable(skb, CAP_NET_ADMIN)) + return -EPERM; + + replay: +@@ -1491,7 +1491,7 @@ static int tc_ctl_tclass(struct sk_buff + u32 qid; + int err; + +- if ((n->nlmsg_type != RTM_GETTCLASS) && !capable(CAP_NET_ADMIN)) ++ if ((n->nlmsg_type != RTM_GETTCLASS) && !netlink_capable(skb, CAP_NET_ADMIN)) + return -EPERM; + + err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); +--- a/net/tipc/netlink.c ++++ b/net/tipc/netlink.c +@@ -47,7 +47,7 @@ static int handle_cmd(struct sk_buff *sk + int hdr_space = nlmsg_total_size(GENL_HDRLEN + TIPC_GENL_HDRLEN); + u16 cmd; + +- if ((req_userhdr->cmd & 0xC000) && (!capable(CAP_NET_ADMIN))) ++ if ((req_userhdr->cmd & 0xC000) && (!netlink_capable(skb, CAP_NET_ADMIN))) + cmd = TIPC_CMD_NOT_NET_ADMIN; + else + cmd = req_userhdr->cmd; +--- a/net/xfrm/xfrm_user.c ++++ b/net/xfrm/xfrm_user.c +@@ -2350,7 +2350,7 @@ static int xfrm_user_rcv_msg(struct sk_b + link = &xfrm_dispatch[type]; + + /* All operations require privileges, even GET */ +- if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) ++ if (!netlink_net_capable(skb, CAP_NET_ADMIN)) + return -EPERM; + + if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) || diff --git a/queue-3.14/netlink-only-check-file-credentials-for-implicit.patch b/queue-3.14/netlink-only-check-file-credentials-for-implicit.patch new file mode 100644 index 00000000000..b5475d59dc1 --- /dev/null +++ b/queue-3.14/netlink-only-check-file-credentials-for-implicit.patch @@ -0,0 +1,108 @@ +From foo@baz Thu Jun 19 10:28:46 PDT 2014 +From: "Eric W. Biederman" +Date: Fri, 30 May 2014 11:04:00 -0700 +Subject: netlink: Only check file credentials for implicit + destinations + +From: "Eric W. Biederman" + +[ Upstream commit 2d7a85f4b06e9c27ff629f07a524c48074f07f81 ] + +It was possible to get a setuid root or setcap executable to write to +it's stdout or stderr (which has been set made a netlink socket) and +inadvertently reconfigure the networking stack. + +To prevent this we check that both the creator of the socket and +the currentl applications has permission to reconfigure the network +stack. + +Unfortunately this breaks Zebra which always uses sendto/sendmsg +and creates it's socket without any privileges. + +To keep Zebra working don't bother checking if the creator of the +socket has privilege when a destination address is specified. Instead +rely exclusively on the privileges of the sender of the socket. + +Note from Andy: This is exactly Eric's code except for some comment +clarifications and formatting fixes. Neither I nor, I think, anyone +else is thrilled with this approach, but I'm hesitant to wait on a +better fix since 3.15 is almost here. + +Note to stable maintainers: This is a mess. An earlier series of +patches in 3.15 fix a rather serious security issue (CVE-2014-0181), +but they did so in a way that breaks Zebra. The offending series +includes: + + commit aa4cf9452f469f16cea8c96283b641b4576d4a7b + Author: Eric W. Biederman + Date: Wed Apr 23 14:28:03 2014 -0700 + + net: Add variants of capable for use on netlink messages + +If a given kernel version is missing that series of fixes, it's +probably worth backporting it and this patch. if that series is +present, then this fix is critical if you care about Zebra. + +Cc: stable@vger.kernel.org +Signed-off-by: "Eric W. Biederman" +Signed-off-by: Andy Lutomirski +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/netlink.h | 7 ++++--- + net/netlink/af_netlink.c | 7 ++++++- + 2 files changed, 10 insertions(+), 4 deletions(-) + +--- a/include/linux/netlink.h ++++ b/include/linux/netlink.h +@@ -16,9 +16,10 @@ static inline struct nlmsghdr *nlmsg_hdr + } + + enum netlink_skb_flags { +- NETLINK_SKB_MMAPED = 0x1, /* Packet data is mmaped */ +- NETLINK_SKB_TX = 0x2, /* Packet was sent by userspace */ +- NETLINK_SKB_DELIVERED = 0x4, /* Packet was delivered */ ++ NETLINK_SKB_MMAPED = 0x1, /* Packet data is mmaped */ ++ NETLINK_SKB_TX = 0x2, /* Packet was sent by userspace */ ++ NETLINK_SKB_DELIVERED = 0x4, /* Packet was delivered */ ++ NETLINK_SKB_DST = 0x8, /* Dst set in sendto or sendmsg */ + }; + + struct netlink_skb_parms { +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -1373,7 +1373,9 @@ retry: + bool __netlink_ns_capable(const struct netlink_skb_parms *nsp, + struct user_namespace *user_ns, int cap) + { +- return sk_ns_capable(nsp->sk, user_ns, cap); ++ return ((nsp->flags & NETLINK_SKB_DST) || ++ file_ns_capable(nsp->sk->sk_socket->file, user_ns, cap)) && ++ ns_capable(user_ns, cap); + } + EXPORT_SYMBOL(__netlink_ns_capable); + +@@ -2293,6 +2295,7 @@ static int netlink_sendmsg(struct kiocb + struct sk_buff *skb; + int err; + struct scm_cookie scm; ++ u32 netlink_skb_flags = 0; + + if (msg->msg_flags&MSG_OOB) + return -EOPNOTSUPP; +@@ -2314,6 +2317,7 @@ static int netlink_sendmsg(struct kiocb + if ((dst_group || dst_portid) && + !netlink_allowed(sock, NL_CFG_F_NONROOT_SEND)) + goto out; ++ netlink_skb_flags |= NETLINK_SKB_DST; + } else { + dst_portid = nlk->dst_portid; + dst_group = nlk->dst_group; +@@ -2343,6 +2347,7 @@ static int netlink_sendmsg(struct kiocb + NETLINK_CB(skb).portid = nlk->portid; + NETLINK_CB(skb).dst_group = dst_group; + NETLINK_CB(skb).creds = siocb->scm->creds; ++ NETLINK_CB(skb).flags = netlink_skb_flags; + + err = -EFAULT; + if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { diff --git a/queue-3.14/netlink-rate-limit-leftover-bytes-warning-and-print.patch b/queue-3.14/netlink-rate-limit-leftover-bytes-warning-and-print.patch new file mode 100644 index 00000000000..20b550c1efc --- /dev/null +++ b/queue-3.14/netlink-rate-limit-leftover-bytes-warning-and-print.patch @@ -0,0 +1,38 @@ +From foo@baz Thu Jun 19 10:28:46 PDT 2014 +From: Michal Schmidt +Date: Mon, 2 Jun 2014 18:25:02 +0200 +Subject: netlink: rate-limit leftover bytes warning and print + process name + +From: Michal Schmidt + +[ Upstream commit bfc5184b69cf9eeb286137640351c650c27f118a ] + +Any process is able to send netlink messages with leftover bytes. +Make the warning rate-limited to prevent too much log spam. + +The warning is supposed to help find userspace bugs, so print the +triggering command name to implicate the buggy program. + +[v2: Use pr_warn_ratelimited instead of printk_ratelimited.] + +Signed-off-by: Michal Schmidt +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + lib/nlattr.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/lib/nlattr.c ++++ b/lib/nlattr.c +@@ -201,8 +201,8 @@ int nla_parse(struct nlattr **tb, int ma + } + + if (unlikely(rem > 0)) +- printk(KERN_WARNING "netlink: %d bytes leftover after parsing " +- "attributes.\n", rem); ++ pr_warn_ratelimited("netlink: %d bytes leftover after parsing attributes in process `%s'.\n", ++ rem, current->comm); + + err = 0; + errout: diff --git a/queue-3.14/netlink-rename-netlink_capable-netlink_allowed.patch b/queue-3.14/netlink-rename-netlink_capable-netlink_allowed.patch new file mode 100644 index 00000000000..f919dc55ca9 --- /dev/null +++ b/queue-3.14/netlink-rename-netlink_capable-netlink_allowed.patch @@ -0,0 +1,66 @@ +From foo@baz Thu Jun 19 10:28:46 PDT 2014 +From: "Eric W. Biederman" +Date: Wed, 23 Apr 2014 14:25:48 -0700 +Subject: netlink: Rename netlink_capable netlink_allowed + +From: "Eric W. Biederman" + +[ Upstream commit 5187cd055b6e81fc6526109456f8b20623148d5f ] + +netlink_capable is a static internal function in af_netlink.c and we +have better uses for the name netlink_capable. + +Signed-off-by: "Eric W. Biederman" +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/netlink/af_netlink.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -1360,7 +1360,7 @@ retry: + return err; + } + +-static inline int netlink_capable(const struct socket *sock, unsigned int flag) ++static inline int netlink_allowed(const struct socket *sock, unsigned int flag) + { + return (nl_table[sock->sk->sk_protocol].flags & flag) || + ns_capable(sock_net(sock->sk)->user_ns, CAP_NET_ADMIN); +@@ -1428,7 +1428,7 @@ static int netlink_bind(struct socket *s + + /* Only superuser is allowed to listen multicasts */ + if (nladdr->nl_groups) { +- if (!netlink_capable(sock, NL_CFG_F_NONROOT_RECV)) ++ if (!netlink_allowed(sock, NL_CFG_F_NONROOT_RECV)) + return -EPERM; + err = netlink_realloc_groups(sk); + if (err) +@@ -1490,7 +1490,7 @@ static int netlink_connect(struct socket + return -EINVAL; + + if ((nladdr->nl_groups || nladdr->nl_pid) && +- !netlink_capable(sock, NL_CFG_F_NONROOT_SEND)) ++ !netlink_allowed(sock, NL_CFG_F_NONROOT_SEND)) + return -EPERM; + + if (!nlk->portid) +@@ -2096,7 +2096,7 @@ static int netlink_setsockopt(struct soc + break; + case NETLINK_ADD_MEMBERSHIP: + case NETLINK_DROP_MEMBERSHIP: { +- if (!netlink_capable(sock, NL_CFG_F_NONROOT_RECV)) ++ if (!netlink_allowed(sock, NL_CFG_F_NONROOT_RECV)) + return -EPERM; + err = netlink_realloc_groups(sk); + if (err) +@@ -2247,7 +2247,7 @@ static int netlink_sendmsg(struct kiocb + dst_group = ffs(addr->nl_groups); + err = -EPERM; + if ((dst_group || dst_portid) && +- !netlink_capable(sock, NL_CFG_F_NONROOT_SEND)) ++ !netlink_allowed(sock, NL_CFG_F_NONROOT_SEND)) + goto out; + } else { + dst_portid = nlk->dst_portid; diff --git a/queue-3.14/qlcnic-info-leak-in-qlcnic_dcb_peer_app_info.patch b/queue-3.14/qlcnic-info-leak-in-qlcnic_dcb_peer_app_info.patch new file mode 100644 index 00000000000..bea960ab232 --- /dev/null +++ b/queue-3.14/qlcnic-info-leak-in-qlcnic_dcb_peer_app_info.patch @@ -0,0 +1,31 @@ +From foo@baz Thu Jun 19 10:28:46 PDT 2014 +From: Dan Carpenter +Date: Fri, 23 May 2014 19:37:21 +0300 +Subject: qlcnic: info leak in qlcnic_dcb_peer_app_info() + +From: Dan Carpenter + +[ Upstream commit 7df566bbdd0af0785542b89466a937e94257fcfb ] + +This function is called from dcbnl_build_peer_app(). The "info" +struct isn't initialized at all so we disclose 2 bytes of uninitialized +stack data. We should clear it before passing it to the user. + +Fixes: 48365e485275 ('qlcnic: dcb: Add support for CEE Netlink interface.') +Signed-off-by: Dan Carpenter +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c ++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c +@@ -1022,6 +1022,7 @@ static int qlcnic_dcb_peer_app_info(stru + struct qlcnic_dcb_cee *peer; + int i; + ++ memset(info, 0, sizeof(*info)); + *app_count = 0; + + if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state)) diff --git a/queue-3.14/rtnetlink-fix-userspace-api-breakage-for-iproute2.patch b/queue-3.14/rtnetlink-fix-userspace-api-breakage-for-iproute2.patch new file mode 100644 index 00000000000..76cf56cd7ec --- /dev/null +++ b/queue-3.14/rtnetlink-fix-userspace-api-breakage-for-iproute2.patch @@ -0,0 +1,86 @@ +From foo@baz Thu Jun 19 10:28:46 PDT 2014 +From: Michal Schmidt +Date: Wed, 28 May 2014 14:15:19 +0200 +Subject: rtnetlink: fix userspace API breakage for iproute2 < + v3.9.0 + +From: Michal Schmidt + +[ Upstream commit e5eca6d41f53db48edd8cf88a3f59d2c30227f8e ] + +When running RHEL6 userspace on a current upstream kernel, "ip link" +fails to show VF information. + +The reason is a kernel<->userspace API change introduced by commit +88c5b5ce5cb57 ("rtnetlink: Call nlmsg_parse() with correct header length"), +after which the kernel does not see iproute2's IFLA_EXT_MASK attribute +in the netlink request. + +iproute2 adjusted for the API change in its commit 63338dca4513 +("libnetlink: Use ifinfomsg instead of rtgenmsg in rtnl_wilddump_req_filter"). + +The problem has been noticed before: +http://marc.info/?l=linux-netdev&m=136692296022182&w=2 +(Subject: Re: getting VF link info seems to be broken in 3.9-rc8) + +We can do better than tell those with old userspace to upgrade. We can +recognize the old iproute2 in the kernel by checking the netlink message +length. Even when including the IFLA_EXT_MASK attribute, its netlink +message is shorter than struct ifinfomsg. + +With this patch "ip link" shows VF information in both old and new +iproute2 versions. + +Signed-off-by: Michal Schmidt +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/rtnetlink.c | 22 ++++++++++++++++++---- + 1 file changed, 18 insertions(+), 4 deletions(-) + +--- a/net/core/rtnetlink.c ++++ b/net/core/rtnetlink.c +@@ -1166,6 +1166,7 @@ static int rtnl_dump_ifinfo(struct sk_bu + struct nlattr *tb[IFLA_MAX+1]; + u32 ext_filter_mask = 0; + int err; ++ int hdrlen; + + s_h = cb->args[0]; + s_idx = cb->args[1]; +@@ -1173,8 +1174,17 @@ static int rtnl_dump_ifinfo(struct sk_bu + rcu_read_lock(); + cb->seq = net->dev_base_seq; + +- if (nlmsg_parse(cb->nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX, +- ifla_policy) >= 0) { ++ /* A hack to preserve kernel<->userspace interface. ++ * The correct header is ifinfomsg. It is consistent with rtnl_getlink. ++ * However, before Linux v3.9 the code here assumed rtgenmsg and that's ++ * what iproute2 < v3.9.0 used. ++ * We can detect the old iproute2. Even including the IFLA_EXT_MASK ++ * attribute, its netlink message is shorter than struct ifinfomsg. ++ */ ++ hdrlen = nlmsg_len(cb->nlh) < sizeof(struct ifinfomsg) ? ++ sizeof(struct rtgenmsg) : sizeof(struct ifinfomsg); ++ ++ if (nlmsg_parse(cb->nlh, hdrlen, tb, IFLA_MAX, ifla_policy) >= 0) { + + if (tb[IFLA_EXT_MASK]) + ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]); +@@ -2085,9 +2095,13 @@ static u16 rtnl_calcit(struct sk_buff *s + struct nlattr *tb[IFLA_MAX+1]; + u32 ext_filter_mask = 0; + u16 min_ifinfo_dump_size = 0; ++ int hdrlen; ++ ++ /* Same kernel<->userspace interface hack as in rtnl_dump_ifinfo. */ ++ hdrlen = nlmsg_len(nlh) < sizeof(struct ifinfomsg) ? ++ sizeof(struct rtgenmsg) : sizeof(struct ifinfomsg); + +- if (nlmsg_parse(nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX, +- ifla_policy) >= 0) { ++ if (nlmsg_parse(nlh, hdrlen, tb, IFLA_MAX, ifla_policy) >= 0) { + if (tb[IFLA_EXT_MASK]) + ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]); + } diff --git a/queue-3.14/sctp-fix-sk_ack_backlog-wrap-around-problem.patch b/queue-3.14/sctp-fix-sk_ack_backlog-wrap-around-problem.patch new file mode 100644 index 00000000000..0ab7f65ccc6 --- /dev/null +++ b/queue-3.14/sctp-fix-sk_ack_backlog-wrap-around-problem.patch @@ -0,0 +1,44 @@ +From foo@baz Thu Jun 19 10:28:46 PDT 2014 +From: Xufeng Zhang +Date: Thu, 12 Jun 2014 10:53:36 +0800 +Subject: sctp: Fix sk_ack_backlog wrap-around problem + +From: Xufeng Zhang + +[ Upstream commit d3217b15a19a4779c39b212358a5c71d725822ee ] + +Consider the scenario: +For a TCP-style socket, while processing the COOKIE_ECHO chunk in +sctp_sf_do_5_1D_ce(), after it has passed a series of sanity check, +a new association would be created in sctp_unpack_cookie(), but afterwards, +some processing maybe failed, and sctp_association_free() will be called to +free the previously allocated association, in sctp_association_free(), +sk_ack_backlog value is decremented for this socket, since the initial +value for sk_ack_backlog is 0, after the decrement, it will be 65535, +a wrap-around problem happens, and if we want to establish new associations +afterward in the same socket, ABORT would be triggered since sctp deem the +accept queue as full. +Fix this issue by only decrementing sk_ack_backlog for associations in +the endpoint's list. + +Fix-suggested-by: Neil Horman +Signed-off-by: Xufeng Zhang +Acked-by: Daniel Borkmann +Acked-by: Vlad Yasevich +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/sctp/associola.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/sctp/associola.c ++++ b/net/sctp/associola.c +@@ -330,7 +330,7 @@ void sctp_association_free(struct sctp_a + /* Only real associations count against the endpoint, so + * don't bother for if this is a temporary association. + */ +- if (!asoc->temp) { ++ if (!list_empty(&asoc->asocs)) { + list_del(&asoc->asocs); + + /* Decrement the backlog value for a TCP-style listening diff --git a/queue-3.14/series b/queue-3.14/series index 133448f52c3..6f246e53fb2 100644 --- a/queue-3.14/series +++ b/queue-3.14/series @@ -4,3 +4,32 @@ iscsi-target-reject-mutual-authentication-with-reflected-chap_c.patch ima-audit-log-files-opened-with-o_direct-flag.patch ima-introduce-ima_kernel_read.patch evm-prohibit-userspace-writing-security.evm-hmac-value.patch +netlink-rename-netlink_capable-netlink_allowed.patch +net-move-the-permission-check-in.patch +net-add-variants-of-capable-for-use-on-on-sockets.patch +net-add-variants-of-capable-for-use-on-netlink.patch +net-use-netlink_ns_capable-to-verify-the-permisions.patch +netlink-only-check-file-credentials-for-implicit.patch +qlcnic-info-leak-in-qlcnic_dcb_peer_app_info.patch +ipv6-fix-regression-caused-by-efe4208-in.patch +netlink-rate-limit-leftover-bytes-warning-and-print.patch +bridge-prevent-insertion-of-fdb-entry-with-disallowed.patch +net-tunnels-enable-module-autoloading.patch +net-fix-inet_getid-and-ipv6_select_ident-bugs.patch +team-fix-mtu-setting.patch +tcp-fix-cwnd-undo-on-dsack-in-f-rto.patch +sh_eth-use-rnc-mode-for-packet-reception.patch +sh_eth-fix-sh7619-771x-support.patch +net-filter-fix-typo-in-sparc-bpf-jit.patch +net-filter-fix-sparc32-typo.patch +net-qmi_wwan-add-olivetti-olicard-modems.patch +net-force-a-list_del-in-unregister_netdevice_many.patch +ipip-sit-fix-ipv4_-update_pmtu-redirect-calls.patch +sfc-pio-restrict-to-64bit-arch-and-use-64-bit-writes.patch +ipv4-fix-a-race-in-ip4_datagram_release_cb.patch +sctp-fix-sk_ack_backlog-wrap-around-problem.patch +rtnetlink-fix-userspace-api-breakage-for-iproute2.patch +vxlan-use-dev-needed_headroom-instead-of.patch +udp-ipv4-do-not-waste-time-in.patch +net-mlx4_core-preserve-pci_dev_data-after.patch +net-mlx4_core-keep-only-one-driver-entry-release.patch diff --git a/queue-3.14/sfc-pio-restrict-to-64bit-arch-and-use-64-bit-writes.patch b/queue-3.14/sfc-pio-restrict-to-64bit-arch-and-use-64-bit-writes.patch new file mode 100644 index 00000000000..1301f35eab0 --- /dev/null +++ b/queue-3.14/sfc-pio-restrict-to-64bit-arch-and-use-64-bit-writes.patch @@ -0,0 +1,120 @@ +From foo@baz Thu Jun 19 10:28:46 PDT 2014 +From: Jon Cooper +Date: Wed, 11 Jun 2014 14:33:08 +0100 +Subject: sfc: PIO:Restrict to 64bit arch and use 64-bit writes. + +From: Jon Cooper + +[ Upstream commit daf37b556e437ec1ea1a597dcfeff338068380e1 ] + +Fixes:ee45fd92c739 +("sfc: Use TX PIO for sufficiently small packets") + +The linux net driver uses memcpy_toio() in order to copy into +the PIO buffers. +Even on a 64bit machine this causes 32bit accesses to a write- +combined memory region. +There are hardware limitations that mean that only 64bit +naturally aligned accesses are safe in all cases. +Due to being write-combined memory region two 32bit accesses +may be coalesced to form a 64bit non 64bit aligned access. +Solution was to open-code the memory copy routines using pointers +and to only enable PIO for x86_64 machines. + +Not tested on platforms other than x86_64 because this patch +disables the PIO feature on other platforms. +Compile-tested on x86 to ensure that works. + +The WARN_ON_ONCE() code in the previous version of this patch +has been moved into the internal sfc debug driver as the +assertion was unnecessary in the upstream kernel code. + +This bug fix applies to v3.13 and v3.14 stable branches. + +Signed-off-by: Shradha Shah +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/sfc/io.h | 7 +++++++ + drivers/net/ethernet/sfc/tx.c | 22 +++++++++++++++++----- + 2 files changed, 24 insertions(+), 5 deletions(-) + +--- a/drivers/net/ethernet/sfc/io.h ++++ b/drivers/net/ethernet/sfc/io.h +@@ -66,10 +66,17 @@ + #define EFX_USE_QWORD_IO 1 + #endif + ++/* Hardware issue requires that only 64-bit naturally aligned writes ++ * are seen by hardware. Its not strictly necessary to restrict to ++ * x86_64 arch, but done for safety since unusual write combining behaviour ++ * can break PIO. ++ */ ++#ifdef CONFIG_X86_64 + /* PIO is a win only if write-combining is possible */ + #ifdef ARCH_HAS_IOREMAP_WC + #define EFX_USE_PIO 1 + #endif ++#endif + + #ifdef EFX_USE_QWORD_IO + static inline void _efx_writeq(struct efx_nic *efx, __le64 value, +--- a/drivers/net/ethernet/sfc/tx.c ++++ b/drivers/net/ethernet/sfc/tx.c +@@ -189,6 +189,18 @@ struct efx_short_copy_buffer { + u8 buf[L1_CACHE_BYTES]; + }; + ++/* Copy in explicit 64-bit writes. */ ++static void efx_memcpy_64(void __iomem *dest, void *src, size_t len) ++{ ++ u64 *src64 = src; ++ u64 __iomem *dest64 = dest; ++ size_t l64 = len / 8; ++ size_t i; ++ ++ for (i = 0; i < l64; i++) ++ writeq(src64[i], &dest64[i]); ++} ++ + /* Copy to PIO, respecting that writes to PIO buffers must be dword aligned. + * Advances piobuf pointer. Leaves additional data in the copy buffer. + */ +@@ -198,7 +210,7 @@ static void efx_memcpy_toio_aligned(stru + { + int block_len = len & ~(sizeof(copy_buf->buf) - 1); + +- memcpy_toio(*piobuf, data, block_len); ++ efx_memcpy_64(*piobuf, data, block_len); + *piobuf += block_len; + len -= block_len; + +@@ -230,7 +242,7 @@ static void efx_memcpy_toio_aligned_cb(s + if (copy_buf->used < sizeof(copy_buf->buf)) + return; + +- memcpy_toio(*piobuf, copy_buf->buf, sizeof(copy_buf->buf)); ++ efx_memcpy_64(*piobuf, copy_buf->buf, sizeof(copy_buf->buf)); + *piobuf += sizeof(copy_buf->buf); + data += copy_to_buf; + len -= copy_to_buf; +@@ -245,7 +257,7 @@ static void efx_flush_copy_buffer(struct + { + /* if there's anything in it, write the whole buffer, including junk */ + if (copy_buf->used) +- memcpy_toio(piobuf, copy_buf->buf, sizeof(copy_buf->buf)); ++ efx_memcpy_64(piobuf, copy_buf->buf, sizeof(copy_buf->buf)); + } + + /* Traverse skb structure and copy fragments in to PIO buffer. +@@ -304,8 +316,8 @@ efx_enqueue_skb_pio(struct efx_tx_queue + */ + BUILD_BUG_ON(L1_CACHE_BYTES > + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))); +- memcpy_toio(tx_queue->piobuf, skb->data, +- ALIGN(skb->len, L1_CACHE_BYTES)); ++ efx_memcpy_64(tx_queue->piobuf, skb->data, ++ ALIGN(skb->len, L1_CACHE_BYTES)); + } + + EFX_POPULATE_QWORD_5(buffer->option, diff --git a/queue-3.14/sh_eth-fix-sh7619-771x-support.patch b/queue-3.14/sh_eth-fix-sh7619-771x-support.patch new file mode 100644 index 00000000000..a6b0448b57c --- /dev/null +++ b/queue-3.14/sh_eth-fix-sh7619-771x-support.patch @@ -0,0 +1,52 @@ +From foo@baz Thu Jun 19 10:28:46 PDT 2014 +From: Sergei Shtylyov +Date: Tue, 3 Jun 2014 23:42:26 +0400 +Subject: sh_eth: fix SH7619/771x support + +From: Sergei Shtylyov + +[ Upstream commit d8b0426af5b67973585712c9af36b86f6ea97815 ] + +Commit 4a55530f38e4 (net: sh_eth: modify the definitions of register) managed +to leave out the E-DMAC register entries in sh_eth_offset_fast_sh3_sh2[], thus +totally breaking SH7619/771x support. Add the missing entries using the data +from before that commit. + +Signed-off-by: Sergei Shtylyov +Acked-by: Yoshihiro Shimoda +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/renesas/sh_eth.c | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +--- a/drivers/net/ethernet/renesas/sh_eth.c ++++ b/drivers/net/ethernet/renesas/sh_eth.c +@@ -301,6 +301,27 @@ static const u16 sh_eth_offset_fast_sh4[ + }; + + static const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = { ++ [EDMR] = 0x0000, ++ [EDTRR] = 0x0004, ++ [EDRRR] = 0x0008, ++ [TDLAR] = 0x000c, ++ [RDLAR] = 0x0010, ++ [EESR] = 0x0014, ++ [EESIPR] = 0x0018, ++ [TRSCER] = 0x001c, ++ [RMFCR] = 0x0020, ++ [TFTR] = 0x0024, ++ [FDR] = 0x0028, ++ [RMCR] = 0x002c, ++ [EDOCR] = 0x0030, ++ [FCFTR] = 0x0034, ++ [RPADIR] = 0x0038, ++ [TRIMD] = 0x003c, ++ [RBWAR] = 0x0040, ++ [RDFAR] = 0x0044, ++ [TBRAR] = 0x004c, ++ [TDFAR] = 0x0050, ++ + [ECMR] = 0x0160, + [ECSR] = 0x0164, + [ECSIPR] = 0x0168, diff --git a/queue-3.14/sh_eth-use-rnc-mode-for-packet-reception.patch b/queue-3.14/sh_eth-use-rnc-mode-for-packet-reception.patch new file mode 100644 index 00000000000..3cbee61f1e0 --- /dev/null +++ b/queue-3.14/sh_eth-use-rnc-mode-for-packet-reception.patch @@ -0,0 +1,117 @@ +From foo@baz Thu Jun 19 10:28:46 PDT 2014 +From: Ben Dooks +Date: Tue, 3 Jun 2014 12:21:13 +0100 +Subject: sh_eth: use RNC mode for packet reception + +From: Ben Dooks + +[ Upstream commit 530aa2d0d9d55ab2775d47621ddf4b5b15bc1110 ] + +The current behaviour of the sh_eth driver is not to use the RNC bit +for the receive ring. This means that every packet recieved is not only +generating an IRQ but it also stops the receive ring DMA as well until +the driver re-enables it after unloading the packet. + +This means that a number of the following errors are generated due to +the receive packet FIFO overflowing due to nowhere to put packets: + + net eth0: Receive FIFO Overflow + +Since feedback from Yoshihiro Shimoda shows that every supported LSI +for this driver should have the bit enabled it seems the best way is +to remove the RMCR default value from the per-system data and just +write it when initialising the RMCR value. This is discussed in +the message (http://www.spinics.net/lists/netdev/msg284912.html). + +I have tested the RMCR_RNC configuration with NFS root filesystem and +the driver has not failed yet. There are further test reports from +Sergei Shtylov and others for both the R8A7790 and R8A7791. + +There is also feedback fron Cao Minh Hiep[1] which reports the +same issue in (http://comments.gmane.org/gmane.linux.network/316285) +showing this fixes issues with losing UDP datagrams under iperf. + +Tested-by: Sergei Shtylyov +Signed-off-by: Ben Dooks +Acked-by: Yoshihiro Shimoda +Acked-by: Simon Horman +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/renesas/sh_eth.c | 11 ++--------- + drivers/net/ethernet/renesas/sh_eth.h | 2 -- + 2 files changed, 2 insertions(+), 11 deletions(-) + +--- a/drivers/net/ethernet/renesas/sh_eth.c ++++ b/drivers/net/ethernet/renesas/sh_eth.c +@@ -539,7 +539,6 @@ static struct sh_eth_cpu_data sh7757_dat + .register_type = SH_ETH_REG_FAST_SH4, + + .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff, +- .rmcr_value = RMCR_RNC, + + .tx_check = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO, + .eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE | +@@ -617,7 +616,6 @@ static struct sh_eth_cpu_data sh7757_dat + EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE | + EESR_TDE | EESR_ECI, + .fdr_value = 0x0000072f, +- .rmcr_value = RMCR_RNC, + + .irq_flags = IRQF_SHARED, + .apr = 1, +@@ -745,7 +743,6 @@ static struct sh_eth_cpu_data r8a7740_da + EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE | + EESR_TDE | EESR_ECI, + .fdr_value = 0x0000070f, +- .rmcr_value = RMCR_RNC, + + .apr = 1, + .mpr = 1, +@@ -777,7 +774,6 @@ static struct sh_eth_cpu_data r7s72100_d + EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE | + EESR_TDE | EESR_ECI, + .fdr_value = 0x0000070f, +- .rmcr_value = RMCR_RNC, + + .no_psr = 1, + .apr = 1, +@@ -826,9 +822,6 @@ static void sh_eth_set_default_cpu_data( + if (!cd->fdr_value) + cd->fdr_value = DEFAULT_FDR_INIT; + +- if (!cd->rmcr_value) +- cd->rmcr_value = DEFAULT_RMCR_VALUE; +- + if (!cd->tx_check) + cd->tx_check = DEFAULT_TX_CHECK; + +@@ -1281,8 +1274,8 @@ static int sh_eth_dev_init(struct net_de + sh_eth_write(ndev, mdp->cd->fdr_value, FDR); + sh_eth_write(ndev, 0, TFTR); + +- /* Frame recv control */ +- sh_eth_write(ndev, mdp->cd->rmcr_value, RMCR); ++ /* Frame recv control (enable multiple-packets per rx irq) */ ++ sh_eth_write(ndev, RMCR_RNC, RMCR); + + sh_eth_write(ndev, DESC_I_RINT8 | DESC_I_RINT5 | DESC_I_TINT2, TRSCER); + +--- a/drivers/net/ethernet/renesas/sh_eth.h ++++ b/drivers/net/ethernet/renesas/sh_eth.h +@@ -320,7 +320,6 @@ enum TD_STS_BIT { + enum RMCR_BIT { + RMCR_RNC = 0x00000001, + }; +-#define DEFAULT_RMCR_VALUE 0x00000000 + + /* ECMR */ + enum FELIC_MODE_BIT { +@@ -467,7 +466,6 @@ struct sh_eth_cpu_data { + unsigned long fdr_value; + unsigned long fcftr_value; + unsigned long rpadir_value; +- unsigned long rmcr_value; + + /* interrupt checking mask */ + unsigned long tx_check; diff --git a/queue-3.14/tcp-fix-cwnd-undo-on-dsack-in-f-rto.patch b/queue-3.14/tcp-fix-cwnd-undo-on-dsack-in-f-rto.patch new file mode 100644 index 00000000000..62cad27ebca --- /dev/null +++ b/queue-3.14/tcp-fix-cwnd-undo-on-dsack-in-f-rto.patch @@ -0,0 +1,50 @@ +From foo@baz Thu Jun 19 10:28:46 PDT 2014 +From: Yuchung Cheng +Date: Fri, 30 May 2014 15:25:59 -0700 +Subject: tcp: fix cwnd undo on DSACK in F-RTO + +From: Yuchung Cheng + +[ Upstream commit 0cfa5c07d6d1d7f8e710fc671c5ba1ce85e09fa4 ] + +This bug is discovered by an recent F-RTO issue on tcpm list +https://www.ietf.org/mail-archive/web/tcpm/current/msg08794.html + +The bug is that currently F-RTO does not use DSACK to undo cwnd in +certain cases: upon receiving an ACK after the RTO retransmission in +F-RTO, and the ACK has DSACK indicating the retransmission is spurious, +the sender only calls tcp_try_undo_loss() if some never retransmisted +data is sacked (FLAG_ORIG_DATA_SACKED). + +The correct behavior is to unconditionally call tcp_try_undo_loss so +the DSACK information is used properly to undo the cwnd reduction. + +Signed-off-by: Yuchung Cheng +Signed-off-by: Neal Cardwell +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp_input.c | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -2683,13 +2683,12 @@ static void tcp_process_loss(struct sock + bool recovered = !before(tp->snd_una, tp->high_seq); + + if (tp->frto) { /* F-RTO RFC5682 sec 3.1 (sack enhanced version). */ +- if (flag & FLAG_ORIG_SACK_ACKED) { +- /* Step 3.b. A timeout is spurious if not all data are +- * lost, i.e., never-retransmitted data are (s)acked. +- */ +- tcp_try_undo_loss(sk, true); ++ /* Step 3.b. A timeout is spurious if not all data are ++ * lost, i.e., never-retransmitted data are (s)acked. ++ */ ++ if (tcp_try_undo_loss(sk, flag & FLAG_ORIG_SACK_ACKED)) + return; +- } ++ + if (after(tp->snd_nxt, tp->high_seq) && + (flag & FLAG_DATA_SACKED || is_dupack)) { + tp->frto = 0; /* Loss was real: 2nd part of step 3.a */ diff --git a/queue-3.14/team-fix-mtu-setting.patch b/queue-3.14/team-fix-mtu-setting.patch new file mode 100644 index 00000000000..6b38b3ce38d --- /dev/null +++ b/queue-3.14/team-fix-mtu-setting.patch @@ -0,0 +1,73 @@ +From foo@baz Thu Jun 19 10:28:46 PDT 2014 +From: Jiri Pirko +Date: Thu, 29 May 2014 20:46:17 +0200 +Subject: team: fix mtu setting + +From: Jiri Pirko + +[ Upstream commit 9d0d68faea6962d62dd501cd6e71ce5cc8ed262b ] + +Now it is not possible to set mtu to team device which has a port +enslaved to it. The reason is that when team_change_mtu() calls +dev_set_mtu() for port device, notificator for NETDEV_PRECHANGEMTU +event is called and team_device_event() returns NOTIFY_BAD forbidding +the change. So fix this by returning NOTIFY_DONE here in case team is +changing mtu in team_change_mtu(). + +Introduced-by: 3d249d4c "net: introduce ethernet teaming device" +Signed-off-by: Jiri Pirko +Acked-by: Flavio Leitner +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/team/team.c | 7 ++++++- + include/linux/if_team.h | 1 + + 2 files changed, 7 insertions(+), 1 deletion(-) + +--- a/drivers/net/team/team.c ++++ b/drivers/net/team/team.c +@@ -1732,6 +1732,7 @@ static int team_change_mtu(struct net_de + * to traverse list in reverse under rcu_read_lock + */ + mutex_lock(&team->lock); ++ team->port_mtu_change_allowed = true; + list_for_each_entry(port, &team->port_list, list) { + err = dev_set_mtu(port->dev, new_mtu); + if (err) { +@@ -1740,6 +1741,7 @@ static int team_change_mtu(struct net_de + goto unwind; + } + } ++ team->port_mtu_change_allowed = false; + mutex_unlock(&team->lock); + + dev->mtu = new_mtu; +@@ -1749,6 +1751,7 @@ static int team_change_mtu(struct net_de + unwind: + list_for_each_entry_continue_reverse(port, &team->port_list, list) + dev_set_mtu(port->dev, dev->mtu); ++ team->port_mtu_change_allowed = false; + mutex_unlock(&team->lock); + + return err; +@@ -2857,7 +2860,9 @@ static int team_device_event(struct noti + break; + case NETDEV_PRECHANGEMTU: + /* Forbid to change mtu of underlaying device */ +- return NOTIFY_BAD; ++ if (!port->team->port_mtu_change_allowed) ++ return NOTIFY_BAD; ++ break; + case NETDEV_PRE_TYPE_CHANGE: + /* Forbid to change type of underlaying device */ + return NOTIFY_BAD; +--- a/include/linux/if_team.h ++++ b/include/linux/if_team.h +@@ -194,6 +194,7 @@ struct team { + bool user_carrier_enabled; + bool queue_override_enabled; + struct list_head *qom_lists; /* array of queue override mapping lists */ ++ bool port_mtu_change_allowed; + struct { + unsigned int count; + unsigned int interval; /* in ms */ diff --git a/queue-3.14/udp-ipv4-do-not-waste-time-in.patch b/queue-3.14/udp-ipv4-do-not-waste-time-in.patch new file mode 100644 index 00000000000..90251a18f4b --- /dev/null +++ b/queue-3.14/udp-ipv4-do-not-waste-time-in.patch @@ -0,0 +1,45 @@ +From foo@baz Thu Jun 19 10:28:46 PDT 2014 +From: Eric Dumazet +Date: Thu, 12 Jun 2014 16:13:06 -0700 +Subject: udp: ipv4: do not waste time in + __udp4_lib_mcast_demux_lookup + +From: Eric Dumazet + +[ Upstream commit 63c6f81cdde58c41da62a8d8a209592e42a0203e ] + +Its too easy to add thousand of UDP sockets on a particular bucket, +and slow down an innocent multicast receiver. + +Early demux is supposed to be an optimization, we should avoid spending +too much time in it. + +It is interesting to note __udp4_lib_demux_lookup() only tries to +match first socket in the chain. + +10 is the threshold we already have in __udp4_lib_lookup() to switch +to secondary hash. + +Fixes: 421b3885bf6d5 ("udp: ipv4: Add udp early demux") +Signed-off-by: Eric Dumazet +Reported-by: David Held +Cc: Shawn Bohrer +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/udp.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -1833,6 +1833,10 @@ static struct sock *__udp4_lib_mcast_dem + unsigned int count, slot = udp_hashfn(net, hnum, udp_table.mask); + struct udp_hslot *hslot = &udp_table.hash[slot]; + ++ /* Do not bother scanning a too big list */ ++ if (hslot->count > 10) ++ return NULL; ++ + rcu_read_lock(); + begin: + count = 0; diff --git a/queue-3.14/vxlan-use-dev-needed_headroom-instead-of.patch b/queue-3.14/vxlan-use-dev-needed_headroom-instead-of.patch new file mode 100644 index 00000000000..eca51690ba6 --- /dev/null +++ b/queue-3.14/vxlan-use-dev-needed_headroom-instead-of.patch @@ -0,0 +1,55 @@ +From foo@baz Thu Jun 19 10:28:46 PDT 2014 +From: Cong Wang +Date: Thu, 12 Jun 2014 11:53:10 -0700 +Subject: vxlan: use dev->needed_headroom instead of + dev->hard_header_len + +From: Cong Wang + +[ Upstream commit 2853af6a2ea1a8ed09b09dd4fb578e7f435e8d34 ] + +When we mirror packets from a vxlan tunnel to other device, +the mirror device should see the same packets (that is, without +outer header). Because vxlan tunnel sets dev->hard_header_len, +tcf_mirred() resets mac header back to outer mac, the mirror device +actually sees packets with outer headers + +Vxlan tunnel should set dev->needed_headroom instead of +dev->hard_header_len, like what other ip tunnels do. This fixes +the above problem. + +Cc: "David S. Miller" +Cc: stephen hemminger +Cc: Pravin B Shelar +Signed-off-by: Cong Wang +Signed-off-by: Cong Wang +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/vxlan.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +--- a/drivers/net/vxlan.c ++++ b/drivers/net/vxlan.c +@@ -2282,9 +2282,9 @@ static void vxlan_setup(struct net_devic + eth_hw_addr_random(dev); + ether_setup(dev); + if (vxlan->default_dst.remote_ip.sa.sa_family == AF_INET6) +- dev->hard_header_len = ETH_HLEN + VXLAN6_HEADROOM; ++ dev->needed_headroom = ETH_HLEN + VXLAN6_HEADROOM; + else +- dev->hard_header_len = ETH_HLEN + VXLAN_HEADROOM; ++ dev->needed_headroom = ETH_HLEN + VXLAN_HEADROOM; + + dev->netdev_ops = &vxlan_netdev_ops; + dev->destructor = free_netdev; +@@ -2667,8 +2667,7 @@ static int vxlan_newlink(struct net *net + if (!tb[IFLA_MTU]) + dev->mtu = lowerdev->mtu - (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM); + +- /* update header length based on lower device */ +- dev->hard_header_len = lowerdev->hard_header_len + ++ dev->needed_headroom = lowerdev->hard_header_len + + (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM); + } else if (use_ipv6) + vxlan->flags |= VXLAN_F_IPV6;