]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 16 Apr 2016 17:05:25 +0000 (10:05 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 16 Apr 2016 17:05:25 +0000 (10:05 -0700)
added patches:
ath9k-fix-buffer-overrun-for-ar9287.patch
ax25-add-link-layer-header-validation-function.patch
bonding-fix-bond_get_stats.patch
bpf-avoid-copying-junk-bytes-in-bpf_get_current_comm.patch
bridge-allow-set-bridge-ageing-time-when-switchdev-disabled.patch
bridge-allow-zero-ageing-time.patch
cdc_ncm-toggle-altsetting-to-force-reset-before-setup.patch
farsync-fix-off-by-one-bug-in-fst_add_one.patch
ip6_tunnel-set-rtnl_link_ops-before-calling-register_netdevice.patch
ipv4-don-t-do-expensive-useless-work-during-inetdev-destroy.patch
ipv4-fix-broadcast-packets-reception.patch
ipv4-initialize-flowi4_flags-before-calling-fib_lookup.patch
ipv4-l2tp-fix-a-potential-issue-in-l2tp_ip_recv.patch
ipv4-only-create-late-gso-skb-if-skb-is-already-set-up-with-checksum_partial.patch
ipv6-count-in-extension-headers-in-skb-network_header.patch
ipv6-l2tp-fix-a-potential-issue-in-l2tp_ip6_recv.patch
ipv6-re-enable-fragment-header-matching-in-ipv6_find_hdr.patch
ipv6-udp-fix-udp_mib_ignoredmulti-updates.patch
macvtap-always-pass-ethernet-header-in-linear.patch
mld-igmp-fix-reserved-tailroom-calculation.patch
mlx4-add-missing-braces-in-verify_qp_parameters.patch
mlxsw-spectrum-check-requested-ageing-time-is-valid.patch
mpls-find_outdev-check-for-err-ptr-in-addition-to-null-check.patch
net-bcmgenet-fix-dma-api-length-mismatch.patch
net-fix-bridge-multicast-packet-checksum-validation.patch
net-fix-use-after-free-in-the-recvmmsg-exit-path.patch
net-jme-fix-suspend-resume-on-jmc260.patch
net-qca_spi-clear-iff_tx_skb_sharing.patch
net-qca_spi-don-t-clear-iff_broadcast.patch
net-validate-variable-length-ll-headers.patch
net-vrf-remove-direct-access-to-skb-data.patch
packet-validate-variable-length-ll-headers.patch
ppp-ensure-file-private_data-can-t-be-overridden.patch
ppp-release-rtnl-mutex-when-interface-creation-fails.patch
ppp-take-reference-on-channels-netns.patch
qlcnic-fix-mailbox-completion-handling-during-spurious-interrupt.patch
qlcnic-remove-unnecessary-usage-of-atomic_t.patch
qlge-fix-receive-packets-drop.patch
qmi_wwan-add-d-link-dwm-221-b1-device-id.patch
qmi_wwan-add-sierra-wireless-em74xx-device-id.patch
rocker-set-fdb-cleanup-timer-according-to-lowest-ageing-time.patch
rtnl-fix-msg-size-calculation-in-if_nlmsg_size.patch
sctp-lack-the-check-for-ports-in-sctp_v6_cmp_addr.patch
sh_eth-advance-rxdesc-later-in-sh_eth_ring_format.patch
sh_eth-fix-null-pointer-dereference-in-sh_eth_ring_format.patch
tcp-convert-cached-rtt-from-usec-to-jiffies-when-feeding-initial-rto.patch
tcp-dccp-remove-obsolete-warn_on-in-icmp-handlers.patch
tcp-fix-tcpi_segs_in-after-connection-establishment.patch
tipc-revert-tipc-use-existing-sk_write_queue-for-outgoing-packet-chain.patch
tun-bpf-fix-suspicious-rcu-usage-in-tun_-attach-detach-_filter.patch
tunnel-clear-ipcb-skb-opt-before-dst_link_failure-called.patch
tuntap-restore-default-qdisc.patch
udp6-fix-udp-ipv6-encap-resubmit-path.patch
usbnet-cleanup-after-bind-in-probe.patch
vxlan-fix-missing-options_len-update-on-rx-with-collect-metadata.patch
xfrm-fix-crash-observed-during-device-unregistration-and-decryption.patch

57 files changed:
queue-4.4/ath9k-fix-buffer-overrun-for-ar9287.patch [new file with mode: 0644]
queue-4.4/ax25-add-link-layer-header-validation-function.patch [new file with mode: 0644]
queue-4.4/bonding-fix-bond_get_stats.patch [new file with mode: 0644]
queue-4.4/bpf-avoid-copying-junk-bytes-in-bpf_get_current_comm.patch [new file with mode: 0644]
queue-4.4/bridge-allow-set-bridge-ageing-time-when-switchdev-disabled.patch [new file with mode: 0644]
queue-4.4/bridge-allow-zero-ageing-time.patch [new file with mode: 0644]
queue-4.4/cdc_ncm-toggle-altsetting-to-force-reset-before-setup.patch [new file with mode: 0644]
queue-4.4/farsync-fix-off-by-one-bug-in-fst_add_one.patch [new file with mode: 0644]
queue-4.4/ip6_tunnel-set-rtnl_link_ops-before-calling-register_netdevice.patch [new file with mode: 0644]
queue-4.4/ipv4-don-t-do-expensive-useless-work-during-inetdev-destroy.patch [new file with mode: 0644]
queue-4.4/ipv4-fix-broadcast-packets-reception.patch [new file with mode: 0644]
queue-4.4/ipv4-initialize-flowi4_flags-before-calling-fib_lookup.patch [new file with mode: 0644]
queue-4.4/ipv4-l2tp-fix-a-potential-issue-in-l2tp_ip_recv.patch [new file with mode: 0644]
queue-4.4/ipv4-only-create-late-gso-skb-if-skb-is-already-set-up-with-checksum_partial.patch [new file with mode: 0644]
queue-4.4/ipv6-count-in-extension-headers-in-skb-network_header.patch [new file with mode: 0644]
queue-4.4/ipv6-l2tp-fix-a-potential-issue-in-l2tp_ip6_recv.patch [new file with mode: 0644]
queue-4.4/ipv6-re-enable-fragment-header-matching-in-ipv6_find_hdr.patch [new file with mode: 0644]
queue-4.4/ipv6-udp-fix-udp_mib_ignoredmulti-updates.patch [new file with mode: 0644]
queue-4.4/macvtap-always-pass-ethernet-header-in-linear.patch [new file with mode: 0644]
queue-4.4/mld-igmp-fix-reserved-tailroom-calculation.patch [new file with mode: 0644]
queue-4.4/mlx4-add-missing-braces-in-verify_qp_parameters.patch [new file with mode: 0644]
queue-4.4/mlxsw-spectrum-check-requested-ageing-time-is-valid.patch [new file with mode: 0644]
queue-4.4/mpls-find_outdev-check-for-err-ptr-in-addition-to-null-check.patch [new file with mode: 0644]
queue-4.4/net-bcmgenet-fix-dma-api-length-mismatch.patch [new file with mode: 0644]
queue-4.4/net-fix-bridge-multicast-packet-checksum-validation.patch [new file with mode: 0644]
queue-4.4/net-fix-use-after-free-in-the-recvmmsg-exit-path.patch [new file with mode: 0644]
queue-4.4/net-jme-fix-suspend-resume-on-jmc260.patch [new file with mode: 0644]
queue-4.4/net-qca_spi-clear-iff_tx_skb_sharing.patch [new file with mode: 0644]
queue-4.4/net-qca_spi-don-t-clear-iff_broadcast.patch [new file with mode: 0644]
queue-4.4/net-validate-variable-length-ll-headers.patch [new file with mode: 0644]
queue-4.4/net-vrf-remove-direct-access-to-skb-data.patch [new file with mode: 0644]
queue-4.4/packet-validate-variable-length-ll-headers.patch [new file with mode: 0644]
queue-4.4/ppp-ensure-file-private_data-can-t-be-overridden.patch [new file with mode: 0644]
queue-4.4/ppp-release-rtnl-mutex-when-interface-creation-fails.patch [new file with mode: 0644]
queue-4.4/ppp-take-reference-on-channels-netns.patch [new file with mode: 0644]
queue-4.4/qlcnic-fix-mailbox-completion-handling-during-spurious-interrupt.patch [new file with mode: 0644]
queue-4.4/qlcnic-remove-unnecessary-usage-of-atomic_t.patch [new file with mode: 0644]
queue-4.4/qlge-fix-receive-packets-drop.patch [new file with mode: 0644]
queue-4.4/qmi_wwan-add-d-link-dwm-221-b1-device-id.patch [new file with mode: 0644]
queue-4.4/qmi_wwan-add-sierra-wireless-em74xx-device-id.patch [new file with mode: 0644]
queue-4.4/rocker-set-fdb-cleanup-timer-according-to-lowest-ageing-time.patch [new file with mode: 0644]
queue-4.4/rtnl-fix-msg-size-calculation-in-if_nlmsg_size.patch [new file with mode: 0644]
queue-4.4/sctp-lack-the-check-for-ports-in-sctp_v6_cmp_addr.patch [new file with mode: 0644]
queue-4.4/series
queue-4.4/sh_eth-advance-rxdesc-later-in-sh_eth_ring_format.patch [new file with mode: 0644]
queue-4.4/sh_eth-fix-null-pointer-dereference-in-sh_eth_ring_format.patch [new file with mode: 0644]
queue-4.4/tcp-convert-cached-rtt-from-usec-to-jiffies-when-feeding-initial-rto.patch [new file with mode: 0644]
queue-4.4/tcp-dccp-remove-obsolete-warn_on-in-icmp-handlers.patch [new file with mode: 0644]
queue-4.4/tcp-fix-tcpi_segs_in-after-connection-establishment.patch [new file with mode: 0644]
queue-4.4/tipc-revert-tipc-use-existing-sk_write_queue-for-outgoing-packet-chain.patch [new file with mode: 0644]
queue-4.4/tun-bpf-fix-suspicious-rcu-usage-in-tun_-attach-detach-_filter.patch [new file with mode: 0644]
queue-4.4/tunnel-clear-ipcb-skb-opt-before-dst_link_failure-called.patch [new file with mode: 0644]
queue-4.4/tuntap-restore-default-qdisc.patch [new file with mode: 0644]
queue-4.4/udp6-fix-udp-ipv6-encap-resubmit-path.patch [new file with mode: 0644]
queue-4.4/usbnet-cleanup-after-bind-in-probe.patch [new file with mode: 0644]
queue-4.4/vxlan-fix-missing-options_len-update-on-rx-with-collect-metadata.patch [new file with mode: 0644]
queue-4.4/xfrm-fix-crash-observed-during-device-unregistration-and-decryption.patch [new file with mode: 0644]

diff --git a/queue-4.4/ath9k-fix-buffer-overrun-for-ar9287.patch b/queue-4.4/ath9k-fix-buffer-overrun-for-ar9287.patch
new file mode 100644 (file)
index 0000000..0dd1707
--- /dev/null
@@ -0,0 +1,68 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Mon, 14 Mar 2016 15:18:36 +0100
+Subject: ath9k: fix buffer overrun for ar9287
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 83d6f1f15f8cce844b0a131cbc63e444620e48b5 ]
+
+Code that was added back in 2.6.38 has an obvious overflow
+when accessing a static array, and at the time it was added
+only a code comment was put in front of it as a reminder
+to have it reviewed properly.
+
+This has not happened, but gcc-6 now points to the specific
+overflow:
+
+drivers/net/wireless/ath/ath9k/eeprom.c: In function 'ath9k_hw_get_gain_boundaries_pdadcs':
+drivers/net/wireless/ath/ath9k/eeprom.c:483:44: error: array subscript is above array bounds [-Werror=array-bounds]
+     maxPwrT4[i] = data_9287[idxL].pwrPdg[i][4];
+                   ~~~~~~~~~~~~~~~~~~~~~~~~~^~~
+
+It turns out that the correct array length exists in the local
+'intercepts' variable of this function, so we can just use that
+instead of hardcoding '4', so this patch changes all three
+instances to use that variable. The other two instances were
+already correct, but it's more consistent this way.
+
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Fixes: 940cd2c12ebf ("ath9k_hw: merge the ar9287 version of ath9k_hw_get_gain_boundaries_pdadcs")
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wireless/ath/ath9k/eeprom.c |    7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath9k/eeprom.c
++++ b/drivers/net/wireless/ath/ath9k/eeprom.c
+@@ -403,10 +403,9 @@ void ath9k_hw_get_gain_boundaries_pdadcs
+       if (match) {
+               if (AR_SREV_9287(ah)) {
+-                      /* FIXME: array overrun? */
+                       for (i = 0; i < numXpdGains; i++) {
+                               minPwrT4[i] = data_9287[idxL].pwrPdg[i][0];
+-                              maxPwrT4[i] = data_9287[idxL].pwrPdg[i][4];
++                              maxPwrT4[i] = data_9287[idxL].pwrPdg[i][intercepts - 1];
+                               ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+                                               data_9287[idxL].pwrPdg[i],
+                                               data_9287[idxL].vpdPdg[i],
+@@ -416,7 +415,7 @@ void ath9k_hw_get_gain_boundaries_pdadcs
+               } else if (eeprom_4k) {
+                       for (i = 0; i < numXpdGains; i++) {
+                               minPwrT4[i] = data_4k[idxL].pwrPdg[i][0];
+-                              maxPwrT4[i] = data_4k[idxL].pwrPdg[i][4];
++                              maxPwrT4[i] = data_4k[idxL].pwrPdg[i][intercepts - 1];
+                               ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+                                               data_4k[idxL].pwrPdg[i],
+                                               data_4k[idxL].vpdPdg[i],
+@@ -426,7 +425,7 @@ void ath9k_hw_get_gain_boundaries_pdadcs
+               } else {
+                       for (i = 0; i < numXpdGains; i++) {
+                               minPwrT4[i] = data_def[idxL].pwrPdg[i][0];
+-                              maxPwrT4[i] = data_def[idxL].pwrPdg[i][4];
++                              maxPwrT4[i] = data_def[idxL].pwrPdg[i][intercepts - 1];
+                               ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+                                               data_def[idxL].pwrPdg[i],
+                                               data_def[idxL].vpdPdg[i],
diff --git a/queue-4.4/ax25-add-link-layer-header-validation-function.patch b/queue-4.4/ax25-add-link-layer-header-validation-function.patch
new file mode 100644 (file)
index 0000000..52c54a7
--- /dev/null
@@ -0,0 +1,49 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Willem de Bruijn <willemb@google.com>
+Date: Wed, 9 Mar 2016 21:58:33 -0500
+Subject: ax25: add link layer header validation function
+
+From: Willem de Bruijn <willemb@google.com>
+
+[ Upstream commit ea47781c26510e5d97f80f9aceafe9065bd5e3aa ]
+
+As variable length protocol, AX25 fails link layer header validation
+tests based on a minimum length. header_ops.validate allows protocols
+to validate headers that are shorter than hard_header_len. Implement
+this callback for AX25.
+
+See also http://comments.gmane.org/gmane.linux.network/401064
+
+Signed-off-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ax25/ax25_ip.c |   15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+--- a/net/ax25/ax25_ip.c
++++ b/net/ax25/ax25_ip.c
+@@ -228,8 +228,23 @@ netdev_tx_t ax25_ip_xmit(struct sk_buff
+ }
+ #endif
++static bool ax25_validate_header(const char *header, unsigned int len)
++{
++      ax25_digi digi;
++
++      if (!len)
++              return false;
++
++      if (header[0])
++              return true;
++
++      return ax25_addr_parse(header + 1, len - 1, NULL, NULL, &digi, NULL,
++                             NULL);
++}
++
+ const struct header_ops ax25_header_ops = {
+       .create = ax25_hard_header,
++      .validate = ax25_validate_header,
+ };
+ EXPORT_SYMBOL(ax25_header_ops);
diff --git a/queue-4.4/bonding-fix-bond_get_stats.patch b/queue-4.4/bonding-fix-bond_get_stats.patch
new file mode 100644 (file)
index 0000000..b3c3ff4
--- /dev/null
@@ -0,0 +1,141 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Eric Dumazet <edumazet@google.com>
+Date: Thu, 17 Mar 2016 17:23:36 -0700
+Subject: bonding: fix bond_get_stats()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit fe30937b65354c7fec244caebbdaae68e28ca797 ]
+
+bond_get_stats() can be called from rtnetlink (with RTNL held)
+or from /proc/net/dev seq handler (with RCU held)
+
+The logic added in commit 5f0c5f73e5ef ("bonding: make global bonding
+stats more reliable") kind of assumed only one cpu could run there.
+
+If multiple threads are reading /proc/net/dev, stats can be really
+messed up after a while.
+
+A second problem is that some fields are 32bit, so we need to properly
+handle the wrap around problem.
+
+Given that RTNL is not always held, we need to use
+bond_for_each_slave_rcu().
+
+Fixes: 5f0c5f73e5ef ("bonding: make global bonding stats more reliable")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Andy Gospodarek <gospo@cumulusnetworks.com>
+Cc: Jay Vosburgh <j.vosburgh@gmail.com>
+Cc: Veaceslav Falico <vfalico@gmail.com>
+Reviewed-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/bonding/bond_main.c |   63 +++++++++++++++++++++-------------------
+ include/net/bonding.h           |    1 
+ 2 files changed, 35 insertions(+), 29 deletions(-)
+
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -3260,6 +3260,30 @@ static int bond_close(struct net_device
+       return 0;
+ }
++/* fold stats, assuming all rtnl_link_stats64 fields are u64, but
++ * that some drivers can provide 32bit values only.
++ */
++static void bond_fold_stats(struct rtnl_link_stats64 *_res,
++                          const struct rtnl_link_stats64 *_new,
++                          const struct rtnl_link_stats64 *_old)
++{
++      const u64 *new = (const u64 *)_new;
++      const u64 *old = (const u64 *)_old;
++      u64 *res = (u64 *)_res;
++      int i;
++
++      for (i = 0; i < sizeof(*_res) / sizeof(u64); i++) {
++              u64 nv = new[i];
++              u64 ov = old[i];
++
++              /* detects if this particular field is 32bit only */
++              if (((nv | ov) >> 32) == 0)
++                      res[i] += (u32)nv - (u32)ov;
++              else
++                      res[i] += nv - ov;
++      }
++}
++
+ static struct rtnl_link_stats64 *bond_get_stats(struct net_device *bond_dev,
+                                               struct rtnl_link_stats64 *stats)
+ {
+@@ -3268,43 +3292,23 @@ static struct rtnl_link_stats64 *bond_ge
+       struct list_head *iter;
+       struct slave *slave;
++      spin_lock(&bond->stats_lock);
+       memcpy(stats, &bond->bond_stats, sizeof(*stats));
+-      bond_for_each_slave(bond, slave, iter) {
+-              const struct rtnl_link_stats64 *sstats =
++      rcu_read_lock();
++      bond_for_each_slave_rcu(bond, slave, iter) {
++              const struct rtnl_link_stats64 *new =
+                       dev_get_stats(slave->dev, &temp);
+-              struct rtnl_link_stats64 *pstats = &slave->slave_stats;
+-              stats->rx_packets +=  sstats->rx_packets - pstats->rx_packets;
+-              stats->rx_bytes += sstats->rx_bytes - pstats->rx_bytes;
+-              stats->rx_errors += sstats->rx_errors - pstats->rx_errors;
+-              stats->rx_dropped += sstats->rx_dropped - pstats->rx_dropped;
+-
+-              stats->tx_packets += sstats->tx_packets - pstats->tx_packets;;
+-              stats->tx_bytes += sstats->tx_bytes - pstats->tx_bytes;
+-              stats->tx_errors += sstats->tx_errors - pstats->tx_errors;
+-              stats->tx_dropped += sstats->tx_dropped - pstats->tx_dropped;
+-
+-              stats->multicast += sstats->multicast - pstats->multicast;
+-              stats->collisions += sstats->collisions - pstats->collisions;
+-
+-              stats->rx_length_errors += sstats->rx_length_errors - pstats->rx_length_errors;
+-              stats->rx_over_errors += sstats->rx_over_errors - pstats->rx_over_errors;
+-              stats->rx_crc_errors += sstats->rx_crc_errors - pstats->rx_crc_errors;
+-              stats->rx_frame_errors += sstats->rx_frame_errors - pstats->rx_frame_errors;
+-              stats->rx_fifo_errors += sstats->rx_fifo_errors - pstats->rx_fifo_errors;
+-              stats->rx_missed_errors += sstats->rx_missed_errors - pstats->rx_missed_errors;
+-
+-              stats->tx_aborted_errors += sstats->tx_aborted_errors - pstats->tx_aborted_errors;
+-              stats->tx_carrier_errors += sstats->tx_carrier_errors - pstats->tx_carrier_errors;
+-              stats->tx_fifo_errors += sstats->tx_fifo_errors - pstats->tx_fifo_errors;
+-              stats->tx_heartbeat_errors += sstats->tx_heartbeat_errors - pstats->tx_heartbeat_errors;
+-              stats->tx_window_errors += sstats->tx_window_errors - pstats->tx_window_errors;
++              bond_fold_stats(stats, new, &slave->slave_stats);
+               /* save off the slave stats for the next run */
+-              memcpy(pstats, sstats, sizeof(*sstats));
++              memcpy(&slave->slave_stats, new, sizeof(*new));
+       }
++      rcu_read_unlock();
++
+       memcpy(&bond->bond_stats, stats, sizeof(*stats));
++      spin_unlock(&bond->stats_lock);
+       return stats;
+ }
+@@ -4118,6 +4122,7 @@ void bond_setup(struct net_device *bond_
+       struct bonding *bond = netdev_priv(bond_dev);
+       spin_lock_init(&bond->mode_lock);
++      spin_lock_init(&bond->stats_lock);
+       bond->params = bonding_defaults;
+       /* Initialize pointers */
+--- a/include/net/bonding.h
++++ b/include/net/bonding.h
+@@ -214,6 +214,7 @@ struct bonding {
+        * ALB mode (6) - to sync the use and modifications of its hash table
+        */
+       spinlock_t mode_lock;
++      spinlock_t stats_lock;
+       u8       send_peer_notif;
+       u8       igmp_retrans;
+ #ifdef CONFIG_PROC_FS
diff --git a/queue-4.4/bpf-avoid-copying-junk-bytes-in-bpf_get_current_comm.patch b/queue-4.4/bpf-avoid-copying-junk-bytes-in-bpf_get_current_comm.patch
new file mode 100644 (file)
index 0000000..29ad320
--- /dev/null
@@ -0,0 +1,39 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Alexei Starovoitov <ast@fb.com>
+Date: Wed, 9 Mar 2016 20:02:33 -0800
+Subject: bpf: avoid copying junk bytes in bpf_get_current_comm()
+
+From: Alexei Starovoitov <ast@fb.com>
+
+[ Upstream commit cdc4e47da8f4c32eeb6b2061a8a834f4362a12b7 ]
+
+Lots of places in the kernel use memcpy(buf, comm, TASK_COMM_LEN); but
+the result is typically passed to print("%s", buf) and extra bytes
+after zero don't cause any harm.
+In bpf the result of bpf_get_current_comm() is used as the part of
+map key and was causing spurious hash map mismatches.
+Use strlcpy() to guarantee zero-terminated string.
+bpf verifier checks that output buffer is zero-initialized,
+so even for short task names the output buffer don't have junk bytes.
+Note it's not a security concern, since kprobe+bpf is root only.
+
+Fixes: ffeedafbf023 ("bpf: introduce current->pid, tgid, uid, gid, comm accessors")
+Reported-by: Tobias Waldekranz <tobias@waldekranz.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/bpf/helpers.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/kernel/bpf/helpers.c
++++ b/kernel/bpf/helpers.c
+@@ -166,7 +166,7 @@ static u64 bpf_get_current_comm(u64 r1,
+       if (!task)
+               return -EINVAL;
+-      memcpy(buf, task->comm, min_t(size_t, size, sizeof(task->comm)));
++      strlcpy(buf, task->comm, min_t(size_t, size, sizeof(task->comm)));
+       return 0;
+ }
diff --git a/queue-4.4/bridge-allow-set-bridge-ageing-time-when-switchdev-disabled.patch b/queue-4.4/bridge-allow-set-bridge-ageing-time-when-switchdev-disabled.patch
new file mode 100644 (file)
index 0000000..4c19e2b
--- /dev/null
@@ -0,0 +1,32 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
+Date: Tue, 29 Mar 2016 18:48:08 +0800
+Subject: bridge: Allow set bridge ageing time when switchdev disabled
+
+From: Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
+
+[ Upstream commit 5e263f712691615fb802f06c98d7638c378f5d11 ]
+
+When NET_SWITCHDEV=n, switchdev_port_attr_set will return -EOPNOTSUPP,
+we should ignore this error code and continue to set the ageing time.
+
+Fixes: c62987bbd8a1 ("bridge: push bridge setting ageing_time down to switchdev")
+Signed-off-by: Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
+Acked-by: Ido Schimmel <idosch@mellanox.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bridge/br_stp.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/bridge/br_stp.c
++++ b/net/bridge/br_stp.c
+@@ -586,7 +586,7 @@ int br_set_ageing_time(struct net_bridge
+       int err;
+       err = switchdev_port_attr_set(br->dev, &attr);
+-      if (err)
++      if (err && err != -EOPNOTSUPP)
+               return err;
+       br->ageing_time = t;
diff --git a/queue-4.4/bridge-allow-zero-ageing-time.patch b/queue-4.4/bridge-allow-zero-ageing-time.patch
new file mode 100644 (file)
index 0000000..2002e18
--- /dev/null
@@ -0,0 +1,68 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Stephen Hemminger <shemming@brocade.com>
+Date: Tue, 8 Mar 2016 12:59:35 -0800
+Subject: bridge: allow zero ageing time
+
+From: Stephen Hemminger <shemming@brocade.com>
+
+[ Upstream commit 4c656c13b254d598e83e586b7b4d36a2043dad85 ]
+
+This fixes a regression in the bridge ageing time caused by:
+commit c62987bbd8a1 ("bridge: push bridge setting ageing_time down to switchdev")
+
+There are users of Linux bridge which use the feature that if ageing time
+is set to 0 it causes entries to never expire. See:
+  https://www.linuxfoundation.org/collaborate/workgroups/networking/bridge
+
+For a pure software bridge, it is unnecessary for the code to have
+arbitrary restrictions on what values are allowable.
+
+Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
+Acked-by: Jiri Pirko <jiri@mellanox.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/if_bridge.h |    4 ----
+ net/bridge/br_stp.c       |   11 ++++++++---
+ 2 files changed, 8 insertions(+), 7 deletions(-)
+
+--- a/include/linux/if_bridge.h
++++ b/include/linux/if_bridge.h
+@@ -46,10 +46,6 @@ struct br_ip_list {
+ #define BR_LEARNING_SYNC      BIT(9)
+ #define BR_PROXYARP_WIFI      BIT(10)
+-/* values as per ieee8021QBridgeFdbAgingTime */
+-#define BR_MIN_AGEING_TIME    (10 * HZ)
+-#define BR_MAX_AGEING_TIME    (1000000 * HZ)
+-
+ #define BR_DEFAULT_AGEING_TIME        (300 * HZ)
+ extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *));
+--- a/net/bridge/br_stp.c
++++ b/net/bridge/br_stp.c
+@@ -567,6 +567,14 @@ int br_set_max_age(struct net_bridge *br
+ }
++/* Set time interval that dynamic forwarding entries live
++ * For pure software bridge, allow values outside the 802.1
++ * standard specification for special cases:
++ *  0 - entry never ages (all permanant)
++ *  1 - entry disappears (no persistance)
++ *
++ * Offloaded switch entries maybe more restrictive
++ */
+ int br_set_ageing_time(struct net_bridge *br, u32 ageing_time)
+ {
+       struct switchdev_attr attr = {
+@@ -577,9 +585,6 @@ int br_set_ageing_time(struct net_bridge
+       unsigned long t = clock_t_to_jiffies(ageing_time);
+       int err;
+-      if (t < BR_MIN_AGEING_TIME || t > BR_MAX_AGEING_TIME)
+-              return -ERANGE;
+-
+       err = switchdev_port_attr_set(br->dev, &attr);
+       if (err)
+               return err;
diff --git a/queue-4.4/cdc_ncm-toggle-altsetting-to-force-reset-before-setup.patch b/queue-4.4/cdc_ncm-toggle-altsetting-to-force-reset-before-setup.patch
new file mode 100644 (file)
index 0000000..7053d25
--- /dev/null
@@ -0,0 +1,44 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bjorn@mork.no>
+Date: Thu, 3 Mar 2016 22:20:53 +0100
+Subject: cdc_ncm: toggle altsetting to force reset before setup
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bjorn@mork.no>
+
+[ Upstream commit 48906f62c96cc2cd35753e59310cb70eb08cc6a5 ]
+
+Some devices will silently fail setup unless they are reset first.
+This is necessary even if the data interface is already in
+altsetting 0, which it will be when the device is probed for the
+first time.  Briefly toggling the altsetting forces a function
+reset regardless of the initial state.
+
+This fixes a setup problem observed on a number of Huawei devices,
+appearing to operate in NTB-32 mode even if we explicitly set them
+to NTB-16 mode.
+
+Signed-off-by: Bjørn Mork <bjorn@mork.no>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/usb/cdc_ncm.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/usb/cdc_ncm.c
++++ b/drivers/net/usb/cdc_ncm.c
+@@ -794,7 +794,11 @@ int cdc_ncm_bind_common(struct usbnet *d
+       iface_no = ctx->data->cur_altsetting->desc.bInterfaceNumber;
+-      /* reset data interface */
++      /* Reset data interface. Some devices will not reset properly
++       * unless they are configured first.  Toggle the altsetting to
++       * force a reset
++       */
++      usb_set_interface(dev->udev, iface_no, data_altsetting);
+       temp = usb_set_interface(dev->udev, iface_no, 0);
+       if (temp) {
+               dev_dbg(&intf->dev, "set interface failed\n");
diff --git a/queue-4.4/farsync-fix-off-by-one-bug-in-fst_add_one.patch b/queue-4.4/farsync-fix-off-by-one-bug-in-fst_add_one.patch
new file mode 100644 (file)
index 0000000..7a8679a
--- /dev/null
@@ -0,0 +1,54 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Mon, 14 Mar 2016 15:18:35 +0100
+Subject: farsync: fix off-by-one bug in fst_add_one
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit e725a66c0202b5f36c2f9d59d26a65c53bbf21f7 ]
+
+gcc-6 finds an out of bounds access in the fst_add_one function
+when calculating the end of the mmio area:
+
+drivers/net/wan/farsync.c: In function 'fst_add_one':
+drivers/net/wan/farsync.c:418:53: error: index 2 denotes an offset greater than size of 'u8[2][8192] {aka unsigned char[2][8192]}' [-Werror=array-bounds]
+ #define BUF_OFFSET(X)   (BFM_BASE + offsetof(struct buf_window, X))
+                                                     ^
+include/linux/compiler-gcc.h:158:21: note: in definition of macro '__compiler_offsetof'
+  __builtin_offsetof(a, b)
+                     ^
+drivers/net/wan/farsync.c:418:37: note: in expansion of macro 'offsetof'
+ #define BUF_OFFSET(X)   (BFM_BASE + offsetof(struct buf_window, X))
+                                     ^~~~~~~~
+drivers/net/wan/farsync.c:2519:36: note: in expansion of macro 'BUF_OFFSET'
+                                  + BUF_OFFSET ( txBuffer[i][NUM_TX_BUFFER][0]);
+                                    ^~~~~~~~~~
+
+The warning is correct, but not critical because this appears
+to be a write-only variable that is set by each WAN driver but
+never accessed afterwards.
+
+I'm taking the minimal fix here, using the correct pointer by
+pointing 'mem_end' to the last byte inside of the register area
+as all other WAN drivers do, rather than the first byte outside of
+it. An alternative would be to just remove the mem_end member
+entirely.
+
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wan/farsync.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/wan/farsync.c
++++ b/drivers/net/wan/farsync.c
+@@ -2516,7 +2516,7 @@ fst_add_one(struct pci_dev *pdev, const
+                 dev->mem_start   = card->phys_mem
+                                  + BUF_OFFSET ( txBuffer[i][0][0]);
+                 dev->mem_end     = card->phys_mem
+-                                 + BUF_OFFSET ( txBuffer[i][NUM_TX_BUFFER][0]);
++                                 + BUF_OFFSET ( txBuffer[i][NUM_TX_BUFFER - 1][LEN_RX_BUFFER - 1]);
+                 dev->base_addr   = card->pci_conf;
+                 dev->irq         = card->irq;
diff --git a/queue-4.4/ip6_tunnel-set-rtnl_link_ops-before-calling-register_netdevice.patch b/queue-4.4/ip6_tunnel-set-rtnl_link_ops-before-calling-register_netdevice.patch
new file mode 100644 (file)
index 0000000..fe621ff
--- /dev/null
@@ -0,0 +1,40 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Thadeu Lima de Souza Cascardo <cascardo@redhat.com>
+Date: Fri, 1 Apr 2016 17:17:50 -0300
+Subject: ip6_tunnel: set rtnl_link_ops before calling register_netdevice
+
+From: Thadeu Lima de Souza Cascardo <cascardo@redhat.com>
+
+[ Upstream commit b6ee376cb0b7fb4e7e07d6cd248bd40436fb9ba6 ]
+
+When creating an ip6tnl tunnel with ip tunnel, rtnl_link_ops is not set
+before ip6_tnl_create2 is called. When register_netdevice is called, there
+is no linkinfo attribute in the NEWLINK message because of that.
+
+Setting rtnl_link_ops before calling register_netdevice fixes that.
+
+Fixes: 0b112457229d ("ip6tnl: add support of link creation via rtnl")
+Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@redhat.com>
+Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/ip6_tunnel.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/ipv6/ip6_tunnel.c
++++ b/net/ipv6/ip6_tunnel.c
+@@ -343,12 +343,12 @@ static int ip6_tnl_create2(struct net_de
+       t = netdev_priv(dev);
++      dev->rtnl_link_ops = &ip6_link_ops;
+       err = register_netdevice(dev);
+       if (err < 0)
+               goto out;
+       strcpy(t->parms.name, dev->name);
+-      dev->rtnl_link_ops = &ip6_link_ops;
+       dev_hold(dev);
+       ip6_tnl_link(ip6n, t);
diff --git a/queue-4.4/ipv4-don-t-do-expensive-useless-work-during-inetdev-destroy.patch b/queue-4.4/ipv4-don-t-do-expensive-useless-work-during-inetdev-destroy.patch
new file mode 100644 (file)
index 0000000..89d61d4
--- /dev/null
@@ -0,0 +1,93 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: "David S. Miller" <davem@davemloft.net>
+Date: Sun, 13 Mar 2016 23:28:00 -0400
+Subject: ipv4: Don't do expensive useless work during inetdev destroy.
+
+From: "David S. Miller" <davem@davemloft.net>
+
+[ Upstream commit fbd40ea0180a2d328c5adc61414dc8bab9335ce2 ]
+
+When an inetdev is destroyed, every address assigned to the interface
+is removed.  And in this scenerio we do two pointless things which can
+be very expensive if the number of assigned interfaces is large:
+
+1) Address promotion.  We are deleting all addresses, so there is no
+   point in doing this.
+
+2) A full nf conntrack table purge for every address.  We only need to
+   do this once, as is already caught by the existing
+   masq_dev_notifier so masq_inet_event() can skip this.
+
+Reported-by: Solar Designer <solar@openwall.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Tested-by: Cyrill Gorcunov <gorcunov@openvz.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/devinet.c                          |    4 ++++
+ net/ipv4/fib_frontend.c                     |    4 ++++
+ net/ipv4/netfilter/nf_nat_masquerade_ipv4.c |   12 ++++++++++--
+ 3 files changed, 18 insertions(+), 2 deletions(-)
+
+--- a/net/ipv4/devinet.c
++++ b/net/ipv4/devinet.c
+@@ -334,6 +334,9 @@ static void __inet_del_ifa(struct in_dev
+       ASSERT_RTNL();
++      if (in_dev->dead)
++              goto no_promotions;
++
+       /* 1. Deleting primary ifaddr forces deletion all secondaries
+        * unless alias promotion is set
+        **/
+@@ -380,6 +383,7 @@ static void __inet_del_ifa(struct in_dev
+                       fib_del_ifaddr(ifa, ifa1);
+       }
++no_promotions:
+       /* 2. Unlink it */
+       *ifap = ifa1->ifa_next;
+--- a/net/ipv4/fib_frontend.c
++++ b/net/ipv4/fib_frontend.c
+@@ -922,6 +922,9 @@ void fib_del_ifaddr(struct in_ifaddr *if
+               subnet = 1;
+       }
++      if (in_dev->dead)
++              goto no_promotions;
++
+       /* Deletion is more complicated than add.
+        * We should take care of not to delete too much :-)
+        *
+@@ -997,6 +1000,7 @@ void fib_del_ifaddr(struct in_ifaddr *if
+               }
+       }
++no_promotions:
+       if (!(ok & BRD_OK))
+               fib_magic(RTM_DELROUTE, RTN_BROADCAST, ifa->ifa_broadcast, 32, prim);
+       if (subnet && ifa->ifa_prefixlen < 31) {
+--- a/net/ipv4/netfilter/nf_nat_masquerade_ipv4.c
++++ b/net/ipv4/netfilter/nf_nat_masquerade_ipv4.c
+@@ -108,10 +108,18 @@ static int masq_inet_event(struct notifi
+                          unsigned long event,
+                          void *ptr)
+ {
+-      struct net_device *dev = ((struct in_ifaddr *)ptr)->ifa_dev->dev;
++      struct in_device *idev = ((struct in_ifaddr *)ptr)->ifa_dev;
+       struct netdev_notifier_info info;
+-      netdev_notifier_info_init(&info, dev);
++      /* The masq_dev_notifier will catch the case of the device going
++       * down.  So if the inetdev is dead and being destroyed we have
++       * no work to do.  Otherwise this is an individual address removal
++       * and we have to perform the flush.
++       */
++      if (idev->dead)
++              return NOTIFY_DONE;
++
++      netdev_notifier_info_init(&info, idev->dev);
+       return masq_device_event(this, event, &info);
+ }
diff --git a/queue-4.4/ipv4-fix-broadcast-packets-reception.patch b/queue-4.4/ipv4-fix-broadcast-packets-reception.patch
new file mode 100644 (file)
index 0000000..c990427
--- /dev/null
@@ -0,0 +1,46 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Paolo Abeni <pabeni@redhat.com>
+Date: Tue, 22 Mar 2016 09:19:38 +0100
+Subject: ipv4: fix broadcast packets reception
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+[ Upstream commit ad0ea1989cc4d5905941d0a9e62c63ad6d859cef ]
+
+Currently, ingress ipv4 broadcast datagrams are dropped since,
+in udp_v4_early_demux(), ip_check_mc_rcu() is invoked even on
+bcast packets.
+
+This patch addresses the issue, invoking ip_check_mc_rcu()
+only for mcast packets.
+
+Fixes: 6e5403093261 ("ipv4/udp: Verify multicast group is ours in upd_v4_early_demux()")
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/udp.c |   12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -1990,10 +1990,14 @@ void udp_v4_early_demux(struct sk_buff *
+               if (!in_dev)
+                       return;
+-              ours = ip_check_mc_rcu(in_dev, iph->daddr, iph->saddr,
+-                                     iph->protocol);
+-              if (!ours)
+-                      return;
++              /* we are supposed to accept bcast packets */
++              if (skb->pkt_type == PACKET_MULTICAST) {
++                      ours = ip_check_mc_rcu(in_dev, iph->daddr, iph->saddr,
++                                             iph->protocol);
++                      if (!ours)
++                              return;
++              }
++
+               sk = __udp4_lib_mcast_demux_lookup(net, uh->dest, iph->daddr,
+                                                  uh->source, iph->saddr, dif);
+       } else if (skb->pkt_type == PACKET_HOST) {
diff --git a/queue-4.4/ipv4-initialize-flowi4_flags-before-calling-fib_lookup.patch b/queue-4.4/ipv4-initialize-flowi4_flags-before-calling-fib_lookup.patch
new file mode 100644 (file)
index 0000000..812cb7d
--- /dev/null
@@ -0,0 +1,62 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Lance Richardson <lrichard@redhat.com>
+Date: Tue, 22 Mar 2016 14:56:57 -0400
+Subject: ipv4: initialize flowi4_flags before calling fib_lookup()
+
+From: Lance Richardson <lrichard@redhat.com>
+
+[ Upstream commit 4cfc86f3dae6ca38ed49cdd78f458a03d4d87992 ]
+
+Field fl4.flowi4_flags is not initialized in fib_compute_spec_dst()
+before calling fib_lookup(), which means fib_table_lookup() is
+using non-deterministic data at this line:
+
+       if (!(flp->flowi4_flags & FLOWI_FLAG_SKIP_NH_OIF)) {
+
+Fix by initializing the entire fl4 structure, which will prevent
+similar issues as fields are added in the future by ensuring that
+all fields are initialized to zero unless explicitly initialized
+to another value.
+
+Fixes: 58189ca7b2741 ("net: Fix vti use case with oif in dst lookups")
+Suggested-by: David Ahern <dsa@cumulusnetworks.com>
+Signed-off-by: Lance Richardson <lrichard@redhat.com>
+Acked-by: David Ahern <dsa@cumulusnetworks.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/fib_frontend.c |   16 +++++++---------
+ 1 file changed, 7 insertions(+), 9 deletions(-)
+
+--- a/net/ipv4/fib_frontend.c
++++ b/net/ipv4/fib_frontend.c
+@@ -280,7 +280,6 @@ __be32 fib_compute_spec_dst(struct sk_bu
+       struct in_device *in_dev;
+       struct fib_result res;
+       struct rtable *rt;
+-      struct flowi4 fl4;
+       struct net *net;
+       int scope;
+@@ -296,14 +295,13 @@ __be32 fib_compute_spec_dst(struct sk_bu
+       scope = RT_SCOPE_UNIVERSE;
+       if (!ipv4_is_zeronet(ip_hdr(skb)->saddr)) {
+-              fl4.flowi4_oif = 0;
+-              fl4.flowi4_iif = LOOPBACK_IFINDEX;
+-              fl4.daddr = ip_hdr(skb)->saddr;
+-              fl4.saddr = 0;
+-              fl4.flowi4_tos = RT_TOS(ip_hdr(skb)->tos);
+-              fl4.flowi4_scope = scope;
+-              fl4.flowi4_mark = IN_DEV_SRC_VMARK(in_dev) ? skb->mark : 0;
+-              fl4.flowi4_tun_key.tun_id = 0;
++              struct flowi4 fl4 = {
++                      .flowi4_iif = LOOPBACK_IFINDEX,
++                      .daddr = ip_hdr(skb)->saddr,
++                      .flowi4_tos = RT_TOS(ip_hdr(skb)->tos),
++                      .flowi4_scope = scope,
++                      .flowi4_mark = IN_DEV_SRC_VMARK(in_dev) ? skb->mark : 0,
++              };
+               if (!fib_lookup(net, &fl4, &res, 0))
+                       return FIB_RES_PREFSRC(net, res);
+       } else {
diff --git a/queue-4.4/ipv4-l2tp-fix-a-potential-issue-in-l2tp_ip_recv.patch b/queue-4.4/ipv4-l2tp-fix-a-potential-issue-in-l2tp_ip_recv.patch
new file mode 100644 (file)
index 0000000..01f7819
--- /dev/null
@@ -0,0 +1,46 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
+Date: Sun, 3 Apr 2016 22:09:23 +0800
+Subject: ipv4: l2tp: fix a potential issue in l2tp_ip_recv
+
+From: Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
+
+[ Upstream commit 5745b8232e942abd5e16e85fa9b27cc21324acf0 ]
+
+pskb_may_pull() can change skb->data, so we have to load ptr/optr at the
+right place.
+
+Signed-off-by: Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/l2tp/l2tp_ip.c |    8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/net/l2tp/l2tp_ip.c
++++ b/net/l2tp/l2tp_ip.c
+@@ -123,12 +123,11 @@ static int l2tp_ip_recv(struct sk_buff *
+       struct l2tp_tunnel *tunnel = NULL;
+       int length;
+-      /* Point to L2TP header */
+-      optr = ptr = skb->data;
+-
+       if (!pskb_may_pull(skb, 4))
+               goto discard;
++      /* Point to L2TP header */
++      optr = ptr = skb->data;
+       session_id = ntohl(*((__be32 *) ptr));
+       ptr += 4;
+@@ -156,6 +155,9 @@ static int l2tp_ip_recv(struct sk_buff *
+               if (!pskb_may_pull(skb, length))
+                       goto discard;
++              /* Point to L2TP header */
++              optr = ptr = skb->data;
++              ptr += 4;
+               pr_debug("%s: ip recv\n", tunnel->name);
+               print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length);
+       }
diff --git a/queue-4.4/ipv4-only-create-late-gso-skb-if-skb-is-already-set-up-with-checksum_partial.patch b/queue-4.4/ipv4-only-create-late-gso-skb-if-skb-is-already-set-up-with-checksum_partial.patch
new file mode 100644 (file)
index 0000000..806e2b5
--- /dev/null
@@ -0,0 +1,51 @@
+From foo@baz Sat Apr 16 10:02:52 PDT 2016
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Date: Mon, 22 Feb 2016 18:43:25 +0100
+Subject: ipv4: only create late gso-skb if skb is already set up with CHECKSUM_PARTIAL
+
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+
+[ Upstream commit a8c4a2522a0808c5c2143612909717d1115c40cf ]
+
+Otherwise we break the contract with GSO to only pass CHECKSUM_PARTIAL
+skbs down. This can easily happen with UDP+IPv4 sockets with the first
+MSG_MORE write smaller than the MTU, second write is a sendfile.
+
+Returning -EOPNOTSUPP lets the callers fall back into normal sendmsg path,
+were we calculate the checksum manually during copying.
+
+Commit d749c9cbffd6 ("ipv4: no CHECKSUM_PARTIAL on MSG_MORE corked
+sockets") started to exposes this bug.
+
+Fixes: d749c9cbffd6 ("ipv4: no CHECKSUM_PARTIAL on MSG_MORE corked sockets")
+Reported-by: Jiri Benc <jbenc@redhat.com>
+Cc: Jiri Benc <jbenc@redhat.com>
+Reported-by: Wakko Warner <wakko@animx.eu.org>
+Cc: Wakko Warner <wakko@animx.eu.org>
+Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/ip_output.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/net/ipv4/ip_output.c
++++ b/net/ipv4/ip_output.c
+@@ -1237,13 +1237,16 @@ ssize_t        ip_append_page(struct sock *sk,
+       if (!skb)
+               return -EINVAL;
+-      cork->length += size;
+       if ((size + skb->len > mtu) &&
+           (sk->sk_protocol == IPPROTO_UDP) &&
+           (rt->dst.dev->features & NETIF_F_UFO)) {
++              if (skb->ip_summed != CHECKSUM_PARTIAL)
++                      return -EOPNOTSUPP;
++
+               skb_shinfo(skb)->gso_size = mtu - fragheaderlen;
+               skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
+       }
++      cork->length += size;
+       while (size > 0) {
+               if (skb_is_gso(skb)) {
diff --git a/queue-4.4/ipv6-count-in-extension-headers-in-skb-network_header.patch b/queue-4.4/ipv6-count-in-extension-headers-in-skb-network_header.patch
new file mode 100644 (file)
index 0000000..99722ef
--- /dev/null
@@ -0,0 +1,81 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Jakub Sitnicki <jkbs@redhat.com>
+Date: Tue, 5 Apr 2016 18:41:08 +0200
+Subject: ipv6: Count in extension headers in skb->network_header
+
+From: Jakub Sitnicki <jkbs@redhat.com>
+
+[ Upstream commit 3ba3458fb9c050718b95275a3310b74415e767e2 ]
+
+When sending a UDPv6 message longer than MTU, account for the length
+of fragmentable IPv6 extension headers in skb->network_header offset.
+Same as we do in alloc_new_skb path in __ip6_append_data().
+
+This ensures that later on __ip6_make_skb() will make space in
+headroom for fragmentable extension headers:
+
+       /* move skb->data to ip header from ext header */
+       if (skb->data < skb_network_header(skb))
+               __skb_pull(skb, skb_network_offset(skb));
+
+Prevents a splat due to skb_under_panic:
+
+skbuff: skb_under_panic: text:ffffffff8143397b len:2126 put:14 \
+head:ffff880005bacf50 data:ffff880005bacf4a tail:0x48 end:0xc0 dev:lo
+------------[ cut here ]------------
+kernel BUG at net/core/skbuff.c:104!
+invalid opcode: 0000 [#1] KASAN
+CPU: 0 PID: 160 Comm: reproducer Not tainted 4.6.0-rc2 #65
+[...]
+Call Trace:
+ [<ffffffff813eb7b9>] skb_push+0x79/0x80
+ [<ffffffff8143397b>] eth_header+0x2b/0x100
+ [<ffffffff8141e0d0>] neigh_resolve_output+0x210/0x310
+ [<ffffffff814eab77>] ip6_finish_output2+0x4a7/0x7c0
+ [<ffffffff814efe3a>] ip6_output+0x16a/0x280
+ [<ffffffff815440c1>] ip6_local_out+0xb1/0xf0
+ [<ffffffff814f1115>] ip6_send_skb+0x45/0xd0
+ [<ffffffff81518836>] udp_v6_send_skb+0x246/0x5d0
+ [<ffffffff8151985e>] udpv6_sendmsg+0xa6e/0x1090
+[...]
+
+Reported-by: Ji Jianwen <jiji@redhat.com>
+Signed-off-by: Jakub Sitnicki <jkbs@redhat.com>
+Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/ip6_output.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/net/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -1091,8 +1091,8 @@ static inline int ip6_ufo_append_data(st
+                       int getfrag(void *from, char *to, int offset, int len,
+                       int odd, struct sk_buff *skb),
+                       void *from, int length, int hh_len, int fragheaderlen,
+-                      int transhdrlen, int mtu, unsigned int flags,
+-                      const struct flowi6 *fl6)
++                      int exthdrlen, int transhdrlen, int mtu,
++                      unsigned int flags, const struct flowi6 *fl6)
+ {
+       struct sk_buff *skb;
+@@ -1117,7 +1117,7 @@ static inline int ip6_ufo_append_data(st
+               skb_put(skb, fragheaderlen + transhdrlen);
+               /* initialize network header pointer */
+-              skb_reset_network_header(skb);
++              skb_set_network_header(skb, exthdrlen);
+               /* initialize protocol header pointer */
+               skb->transport_header = skb->network_header + fragheaderlen;
+@@ -1359,7 +1359,7 @@ emsgsize:
+           (rt->dst.dev->features & NETIF_F_UFO) &&
+           (sk->sk_type == SOCK_DGRAM) && !udp_get_no_check6_tx(sk)) {
+               err = ip6_ufo_append_data(sk, queue, getfrag, from, length,
+-                                        hh_len, fragheaderlen,
++                                        hh_len, fragheaderlen, exthdrlen,
+                                         transhdrlen, mtu, flags, fl6);
+               if (err)
+                       goto error;
diff --git a/queue-4.4/ipv6-l2tp-fix-a-potential-issue-in-l2tp_ip6_recv.patch b/queue-4.4/ipv6-l2tp-fix-a-potential-issue-in-l2tp_ip6_recv.patch
new file mode 100644 (file)
index 0000000..5bb0584
--- /dev/null
@@ -0,0 +1,46 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
+Date: Sun, 3 Apr 2016 22:09:24 +0800
+Subject: ipv6: l2tp: fix a potential issue in l2tp_ip6_recv
+
+From: Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
+
+[ Upstream commit be447f305494e019dfc37ea4cdf3b0e4200b4eba ]
+
+pskb_may_pull() can change skb->data, so we have to load ptr/optr at the
+right place.
+
+Signed-off-by: Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/l2tp/l2tp_ip6.c |    8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/net/l2tp/l2tp_ip6.c
++++ b/net/l2tp/l2tp_ip6.c
+@@ -135,12 +135,11 @@ static int l2tp_ip6_recv(struct sk_buff
+       struct l2tp_tunnel *tunnel = NULL;
+       int length;
+-      /* Point to L2TP header */
+-      optr = ptr = skb->data;
+-
+       if (!pskb_may_pull(skb, 4))
+               goto discard;
++      /* Point to L2TP header */
++      optr = ptr = skb->data;
+       session_id = ntohl(*((__be32 *) ptr));
+       ptr += 4;
+@@ -168,6 +167,9 @@ static int l2tp_ip6_recv(struct sk_buff
+               if (!pskb_may_pull(skb, length))
+                       goto discard;
++              /* Point to L2TP header */
++              optr = ptr = skb->data;
++              ptr += 4;
+               pr_debug("%s: ip recv\n", tunnel->name);
+               print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length);
+       }
diff --git a/queue-4.4/ipv6-re-enable-fragment-header-matching-in-ipv6_find_hdr.patch b/queue-4.4/ipv6-re-enable-fragment-header-matching-in-ipv6_find_hdr.patch
new file mode 100644 (file)
index 0000000..13a65bd
--- /dev/null
@@ -0,0 +1,47 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Florian Westphal <fw@strlen.de>
+Date: Tue, 1 Mar 2016 16:15:16 +0100
+Subject: ipv6: re-enable fragment header matching in ipv6_find_hdr
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit 5d150a985520bbe3cb2aa1ceef24a7e32f20c15f ]
+
+When ipv6_find_hdr is used to find a fragment header
+(caller specifies target NEXTHDR_FRAGMENT) we erronously return
+-ENOENT for all fragments with nonzero offset.
+
+Before commit 9195bb8e381d, when target was specified, we did not
+enter the exthdr walk loop as nexthdr == target so this used to work.
+
+Now we do (so we can skip empty route headers). When we then stumble upon
+a frag with nonzero frag_off we must return -ENOENT ("header not found")
+only if the caller did not specifically request NEXTHDR_FRAGMENT.
+
+This allows nfables exthdr expression to match ipv6 fragments, e.g. via
+
+nft add rule ip6 filter input frag frag-off gt 0
+
+Fixes: 9195bb8e381d ("ipv6: improve ipv6_find_hdr() to skip empty routing headers")
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/exthdrs_core.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/net/ipv6/exthdrs_core.c
++++ b/net/ipv6/exthdrs_core.c
+@@ -257,7 +257,11 @@ int ipv6_find_hdr(const struct sk_buff *
+                                               *fragoff = _frag_off;
+                                       return hp->nexthdr;
+                               }
+-                              return -ENOENT;
++                              if (!found)
++                                      return -ENOENT;
++                              if (fragoff)
++                                      *fragoff = _frag_off;
++                              break;
+                       }
+                       hdrlen = 8;
+               } else if (nexthdr == NEXTHDR_AUTH) {
diff --git a/queue-4.4/ipv6-udp-fix-udp_mib_ignoredmulti-updates.patch b/queue-4.4/ipv6-udp-fix-udp_mib_ignoredmulti-updates.patch
new file mode 100644 (file)
index 0000000..5159f17
--- /dev/null
@@ -0,0 +1,34 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Eric Dumazet <edumazet@google.com>
+Date: Tue, 29 Mar 2016 08:43:41 -0700
+Subject: ipv6: udp: fix UDP_MIB_IGNOREDMULTI updates
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 2d4212261fdf13e29728ddb5ea9d60c342cc92b5 ]
+
+IPv6 counters updates use a different macro than IPv4.
+
+Fixes: 36cbb2452cbaf ("udp: Increment UDP_MIB_IGNOREDMULTI for arriving unmatched multicasts")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Rick Jones <rick.jones2@hp.com>
+Cc: Willem de Bruijn <willemb@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/udp.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -837,8 +837,8 @@ start_lookup:
+               flush_stack(stack, count, skb, count - 1);
+       } else {
+               if (!inner_flushed)
+-                      UDP_INC_STATS_BH(net, UDP_MIB_IGNOREDMULTI,
+-                                       proto == IPPROTO_UDPLITE);
++                      UDP6_INC_STATS_BH(net, UDP_MIB_IGNOREDMULTI,
++                                        proto == IPPROTO_UDPLITE);
+               consume_skb(skb);
+       }
+       return 0;
diff --git a/queue-4.4/macvtap-always-pass-ethernet-header-in-linear.patch b/queue-4.4/macvtap-always-pass-ethernet-header-in-linear.patch
new file mode 100644 (file)
index 0000000..1a499cf
--- /dev/null
@@ -0,0 +1,54 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Willem de Bruijn <willemb@google.com>
+Date: Tue, 8 Mar 2016 15:18:54 -0500
+Subject: macvtap: always pass ethernet header in linear
+
+From: Willem de Bruijn <willemb@google.com>
+
+[ Upstream commit 8e2ad4113ce4671686740f808ff2795395c39eef ]
+
+The stack expects link layer headers in the skb linear section.
+Macvtap can create skbs with llheader in frags in edge cases:
+when (IFF_VNET_HDR is off or vnet_hdr.hdr_len < ETH_HLEN) and
+prepad + len > PAGE_SIZE and vnet_hdr.flags has no or bad csum.
+
+Add checks to ensure linear is always at least ETH_HLEN.
+At this point, len is already ensured to be >= ETH_HLEN.
+
+For backwards compatiblity, rounds up short vnet_hdr.hdr_len.
+This differs from tap and packet, which return an error.
+
+Fixes b9fb9ee07e67 ("macvtap: add GSO/csum offload support")
+Signed-off-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/macvtap.c |    9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/macvtap.c
++++ b/drivers/net/macvtap.c
+@@ -760,6 +760,8 @@ static ssize_t macvtap_get_user(struct m
+                       macvtap16_to_cpu(q, vnet_hdr.hdr_len) : GOODCOPY_LEN;
+               if (copylen > good_linear)
+                       copylen = good_linear;
++              else if (copylen < ETH_HLEN)
++                      copylen = ETH_HLEN;
+               linear = copylen;
+               i = *from;
+               iov_iter_advance(&i, copylen);
+@@ -769,10 +771,11 @@ static ssize_t macvtap_get_user(struct m
+       if (!zerocopy) {
+               copylen = len;
+-              if (macvtap16_to_cpu(q, vnet_hdr.hdr_len) > good_linear)
++              linear = macvtap16_to_cpu(q, vnet_hdr.hdr_len);
++              if (linear > good_linear)
+                       linear = good_linear;
+-              else
+-                      linear = macvtap16_to_cpu(q, vnet_hdr.hdr_len);
++              else if (linear < ETH_HLEN)
++                      linear = ETH_HLEN;
+       }
+       skb = macvtap_alloc_skb(&q->sk, MACVTAP_RESERVE, copylen,
diff --git a/queue-4.4/mld-igmp-fix-reserved-tailroom-calculation.patch b/queue-4.4/mld-igmp-fix-reserved-tailroom-calculation.patch
new file mode 100644 (file)
index 0000000..ebf98f1
--- /dev/null
@@ -0,0 +1,118 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Benjamin Poirier <bpoirier@suse.com>
+Date: Mon, 29 Feb 2016 15:03:33 -0800
+Subject: mld, igmp: Fix reserved tailroom calculation
+
+From: Benjamin Poirier <bpoirier@suse.com>
+
+[ Upstream commit 1837b2e2bcd23137766555a63867e649c0b637f0 ]
+
+The current reserved_tailroom calculation fails to take hlen and tlen into
+account.
+
+skb:
+[__hlen__|__data____________|__tlen___|__extra__]
+^                                               ^
+head                                            skb_end_offset
+
+In this representation, hlen + data + tlen is the size passed to alloc_skb.
+"extra" is the extra space made available in __alloc_skb because of
+rounding up by kmalloc. We can reorder the representation like so:
+
+[__hlen__|__data____________|__extra__|__tlen___]
+^                                               ^
+head                                            skb_end_offset
+
+The maximum space available for ip headers and payload without
+fragmentation is min(mtu, data + extra). Therefore,
+reserved_tailroom
+= data + extra + tlen - min(mtu, data + extra)
+= skb_end_offset - hlen - min(mtu, skb_end_offset - hlen - tlen)
+= skb_tailroom - min(mtu, skb_tailroom - tlen) ; after skb_reserve(hlen)
+
+Compare the second line to the current expression:
+reserved_tailroom = skb_end_offset - min(mtu, skb_end_offset)
+and we can see that hlen and tlen are not taken into account.
+
+The min() in the third line can be expanded into:
+if mtu < skb_tailroom - tlen:
+       reserved_tailroom = skb_tailroom - mtu
+else:
+       reserved_tailroom = tlen
+
+Depending on hlen, tlen, mtu and the number of multicast address records,
+the current code may output skbs that have less tailroom than
+dev->needed_tailroom or it may output more skbs than needed because not all
+space available is used.
+
+Fixes: 4c672e4b ("ipv6: mld: fix add_grhead skb_over_panic for devs with large MTUs")
+Signed-off-by: Benjamin Poirier <bpoirier@suse.com>
+Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Acked-by: Daniel Borkmann <daniel@iogearbox.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/skbuff.h |   24 ++++++++++++++++++++++++
+ net/ipv4/igmp.c        |    3 +--
+ net/ipv6/mcast.c       |    3 +--
+ 3 files changed, 26 insertions(+), 4 deletions(-)
+
+--- a/include/linux/skbuff.h
++++ b/include/linux/skbuff.h
+@@ -1908,6 +1908,30 @@ static inline void skb_reserve(struct sk
+       skb->tail += len;
+ }
++/**
++ *    skb_tailroom_reserve - adjust reserved_tailroom
++ *    @skb: buffer to alter
++ *    @mtu: maximum amount of headlen permitted
++ *    @needed_tailroom: minimum amount of reserved_tailroom
++ *
++ *    Set reserved_tailroom so that headlen can be as large as possible but
++ *    not larger than mtu and tailroom cannot be smaller than
++ *    needed_tailroom.
++ *    The required headroom should already have been reserved before using
++ *    this function.
++ */
++static inline void skb_tailroom_reserve(struct sk_buff *skb, unsigned int mtu,
++                                      unsigned int needed_tailroom)
++{
++      SKB_LINEAR_ASSERT(skb);
++      if (mtu < skb_tailroom(skb) - needed_tailroom)
++              /* use at most mtu */
++              skb->reserved_tailroom = skb_tailroom(skb) - mtu;
++      else
++              /* use up to all available space */
++              skb->reserved_tailroom = needed_tailroom;
++}
++
+ #define ENCAP_TYPE_ETHER      0
+ #define ENCAP_TYPE_IPPROTO    1
+--- a/net/ipv4/igmp.c
++++ b/net/ipv4/igmp.c
+@@ -356,9 +356,8 @@ static struct sk_buff *igmpv3_newpack(st
+       skb_dst_set(skb, &rt->dst);
+       skb->dev = dev;
+-      skb->reserved_tailroom = skb_end_offset(skb) -
+-                               min(mtu, skb_end_offset(skb));
+       skb_reserve(skb, hlen);
++      skb_tailroom_reserve(skb, mtu, tlen);
+       skb_reset_network_header(skb);
+       pip = ip_hdr(skb);
+--- a/net/ipv6/mcast.c
++++ b/net/ipv6/mcast.c
+@@ -1574,9 +1574,8 @@ static struct sk_buff *mld_newpack(struc
+               return NULL;
+       skb->priority = TC_PRIO_CONTROL;
+-      skb->reserved_tailroom = skb_end_offset(skb) -
+-                               min(mtu, skb_end_offset(skb));
+       skb_reserve(skb, hlen);
++      skb_tailroom_reserve(skb, mtu, tlen);
+       if (__ipv6_get_lladdr(idev, &addr_buf, IFA_F_TENTATIVE)) {
+               /* <draft-ietf-magma-mld-source-05.txt>:
diff --git a/queue-4.4/mlx4-add-missing-braces-in-verify_qp_parameters.patch b/queue-4.4/mlx4-add-missing-braces-in-verify_qp_parameters.patch
new file mode 100644 (file)
index 0000000..feeddde
--- /dev/null
@@ -0,0 +1,51 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Mon, 14 Mar 2016 15:18:34 +0100
+Subject: mlx4: add missing braces in verify_qp_parameters
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit baefd7015cdb304ce6c94f9679d0486c71954766 ]
+
+The implementation of QP paravirtualization back in linux-3.7 included
+some code that looks very dubious, and gcc-6 has grown smart enough
+to warn about it:
+
+drivers/net/ethernet/mellanox/mlx4/resource_tracker.c: In function 'verify_qp_parameters':
+drivers/net/ethernet/mellanox/mlx4/resource_tracker.c:3154:5: error: statement is indented as if it were guarded by... [-Werror=misleading-indentation]
+     if (optpar & MLX4_QP_OPTPAR_ALT_ADDR_PATH) {
+     ^~
+drivers/net/ethernet/mellanox/mlx4/resource_tracker.c:3144:4: note: ...this 'if' clause, but it is not
+    if (slave != mlx4_master_func_num(dev))
+
+>From looking at the context, I'm reasonably sure that the indentation
+is correct but that it should have contained curly braces from the
+start, as the update_gid() function in the same patch correctly does.
+
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Fixes: 54679e148287 ("mlx4: Implement QP paravirtualization and maintain phys_pkey_cache for smp_snoop")
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/mellanox/mlx4/resource_tracker.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
++++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+@@ -3132,7 +3132,7 @@ static int verify_qp_parameters(struct m
+               case QP_TRANS_RTS2RTS:
+               case QP_TRANS_SQD2SQD:
+               case QP_TRANS_SQD2RTS:
+-                      if (slave != mlx4_master_func_num(dev))
++                      if (slave != mlx4_master_func_num(dev)) {
+                               if (optpar & MLX4_QP_OPTPAR_PRIMARY_ADDR_PATH) {
+                                       port = (qp_ctx->pri_path.sched_queue >> 6 & 1) + 1;
+                                       if (dev->caps.port_mask[port] != MLX4_PORT_TYPE_IB)
+@@ -3151,6 +3151,7 @@ static int verify_qp_parameters(struct m
+                                       if (qp_ctx->alt_path.mgid_index >= num_gids)
+                                               return -EINVAL;
+                               }
++                      }
+                       break;
+               default:
+                       break;
diff --git a/queue-4.4/mlxsw-spectrum-check-requested-ageing-time-is-valid.patch b/queue-4.4/mlxsw-spectrum-check-requested-ageing-time-is-valid.patch
new file mode 100644 (file)
index 0000000..8ef096b
--- /dev/null
@@ -0,0 +1,56 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Ido Schimmel <idosch@mellanox.com>
+Date: Tue, 8 Mar 2016 12:59:33 -0800
+Subject: mlxsw: spectrum: Check requested ageing time is valid
+
+From: Ido Schimmel <idosch@mellanox.com>
+
+[ Upstream commit 869f63a4d28144c03c8f4a4c0d1e8f31f8c11a10 ]
+
+Commit c62987bbd8a1 ("bridge: push bridge setting ageing_time down to
+switchdev") added a check for minimum and maximum ageing time, but this
+breaks existing behaviour where one can set ageing time to 0 for a
+non-learning bridge.
+
+Push this check down to the driver and allow the check in the bridge
+layer to be removed. Currently ageing time 0 is refused by the driver,
+but we can later add support for this functionality.
+
+Signed-off-by: Ido Schimmel <idosch@mellanox.com>
+Acked-by: Jiri Pirko <jiri@mellanox.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/mellanox/mlxsw/spectrum.h           |    2 ++
+ drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c |    9 +++++++--
+ 2 files changed, 9 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
+@@ -61,6 +61,8 @@ struct mlxsw_sp {
+ #define MLXSW_SP_DEFAULT_LEARNING_INTERVAL 100
+               unsigned int interval; /* ms */
+       } fdb_notify;
++#define MLXSW_SP_MIN_AGEING_TIME 10
++#define MLXSW_SP_MAX_AGEING_TIME 1000000
+ #define MLXSW_SP_DEFAULT_AGEING_TIME 300
+       u32 ageing_time;
+       struct {
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+@@ -232,8 +232,13 @@ static int mlxsw_sp_port_attr_br_ageing_
+       unsigned long ageing_jiffies = clock_t_to_jiffies(ageing_clock_t);
+       u32 ageing_time = jiffies_to_msecs(ageing_jiffies) / 1000;
+-      if (switchdev_trans_ph_prepare(trans))
+-              return 0;
++      if (switchdev_trans_ph_prepare(trans)) {
++              if (ageing_time < MLXSW_SP_MIN_AGEING_TIME ||
++                  ageing_time > MLXSW_SP_MAX_AGEING_TIME)
++                      return -ERANGE;
++              else
++                      return 0;
++      }
+       return mlxsw_sp_ageing_set(mlxsw_sp, ageing_time);
+ }
diff --git a/queue-4.4/mpls-find_outdev-check-for-err-ptr-in-addition-to-null-check.patch b/queue-4.4/mpls-find_outdev-check-for-err-ptr-in-addition-to-null-check.patch
new file mode 100644 (file)
index 0000000..c1d496c
--- /dev/null
@@ -0,0 +1,112 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Roopa Prabhu <roopa@cumulusnetworks.com>
+Date: Thu, 7 Apr 2016 21:28:38 -0700
+Subject: mpls: find_outdev: check for err ptr in addition to NULL check
+
+From: Roopa Prabhu <roopa@cumulusnetworks.com>
+
+[ Upstream commit 94a57f1f8a9de90ab4b0f8748361ff8be706c80c ]
+
+find_outdev calls inet{,6}_fib_lookup_dev() or dev_get_by_index() to
+find the output device. In case of an error, inet{,6}_fib_lookup_dev()
+returns error pointer and dev_get_by_index() returns NULL. But the function
+only checks for NULL and thus can end up calling dev_put on an ERR_PTR.
+This patch adds an additional check for err ptr after the NULL check.
+
+Before: Trying to add an mpls route with no oif from user, no available
+path to 10.1.1.8 and no default route:
+$ip -f mpls route add 100 as 200 via inet 10.1.1.8
+[  822.337195] BUG: unable to handle kernel NULL pointer dereference at
+00000000000003a3
+[  822.340033] IP: [<ffffffff8148781e>] mpls_nh_assign_dev+0x10b/0x182
+[  822.340033] PGD 1db38067 PUD 1de9e067 PMD 0
+[  822.340033] Oops: 0000 [#1] SMP
+[  822.340033] Modules linked in:
+[  822.340033] CPU: 0 PID: 11148 Comm: ip Not tainted 4.5.0-rc7+ #54
+[  822.340033] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996),
+BIOS rel-1.7.5.1-0-g8936dbb-20141113_115728-nilsson.home.kraxel.org
+04/01/2014
+[  822.340033] task: ffff88001db82580 ti: ffff88001dad4000 task.ti:
+ffff88001dad4000
+[  822.340033] RIP: 0010:[<ffffffff8148781e>]  [<ffffffff8148781e>]
+mpls_nh_assign_dev+0x10b/0x182
+[  822.340033] RSP: 0018:ffff88001dad7a88  EFLAGS: 00010282
+[  822.340033] RAX: ffffffffffffff9b RBX: ffffffffffffff9b RCX:
+0000000000000002
+[  822.340033] RDX: 00000000ffffff9b RSI: 0000000000000008 RDI:
+0000000000000000
+[  822.340033] RBP: ffff88001ddc9ea0 R08: ffff88001e9f1768 R09:
+0000000000000000
+[  822.340033] R10: ffff88001d9c1100 R11: ffff88001e3c89f0 R12:
+ffffffff8187e0c0
+[  822.340033] R13: ffffffff8187e0c0 R14: ffff88001ddc9e80 R15:
+0000000000000004
+[  822.340033] FS:  00007ff9ed798700(0000) GS:ffff88001fc00000(0000)
+knlGS:0000000000000000
+[  822.340033] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[  822.340033] CR2: 00000000000003a3 CR3: 000000001de89000 CR4:
+00000000000006f0
+[  822.340033] Stack:
+[  822.340033]  0000000000000000 0000000100000000 0000000000000000
+0000000000000000
+[  822.340033]  0000000000000000 0801010a00000000 0000000000000000
+0000000000000000
+[  822.340033]  0000000000000004 ffffffff8148749b ffffffff8187e0c0
+000000000000001c
+[  822.340033] Call Trace:
+[  822.340033]  [<ffffffff8148749b>] ? mpls_rt_alloc+0x2b/0x3e
+[  822.340033]  [<ffffffff81488e66>] ? mpls_rtm_newroute+0x358/0x3e2
+[  822.340033]  [<ffffffff810e7bbc>] ? get_page+0x5/0xa
+[  822.340033]  [<ffffffff813b7d94>] ? rtnetlink_rcv_msg+0x17e/0x191
+[  822.340033]  [<ffffffff8111794e>] ? __kmalloc_track_caller+0x8c/0x9e
+[  822.340033]  [<ffffffff813c9393>] ?
+rht_key_hashfn.isra.20.constprop.57+0x14/0x1f
+[  822.340033]  [<ffffffff813b7c16>] ? __rtnl_unlock+0xc/0xc
+[  822.340033]  [<ffffffff813cb794>] ? netlink_rcv_skb+0x36/0x82
+[  822.340033]  [<ffffffff813b4507>] ? rtnetlink_rcv+0x1f/0x28
+[  822.340033]  [<ffffffff813cb2b1>] ? netlink_unicast+0x106/0x189
+[  822.340033]  [<ffffffff813cb5b3>] ? netlink_sendmsg+0x27f/0x2c8
+[  822.340033]  [<ffffffff81392ede>] ? sock_sendmsg_nosec+0x10/0x1b
+[  822.340033]  [<ffffffff81393df1>] ? ___sys_sendmsg+0x182/0x1e3
+[  822.340033]  [<ffffffff810e4f35>] ?
+__alloc_pages_nodemask+0x11c/0x1e4
+[  822.340033]  [<ffffffff8110619c>] ? PageAnon+0x5/0xd
+[  822.340033]  [<ffffffff811062fe>] ? __page_set_anon_rmap+0x45/0x52
+[  822.340033]  [<ffffffff810e7bbc>] ? get_page+0x5/0xa
+[  822.340033]  [<ffffffff810e85ab>] ? __lru_cache_add+0x1a/0x3a
+[  822.340033]  [<ffffffff81087ea9>] ? current_kernel_time64+0x9/0x30
+[  822.340033]  [<ffffffff813940c4>] ? __sys_sendmsg+0x3c/0x5a
+[  822.340033]  [<ffffffff8148f597>] ?
+entry_SYSCALL_64_fastpath+0x12/0x6a
+[  822.340033] Code: 83 08 04 00 00 65 ff 00 48 8b 3c 24 e8 40 7c f2 ff
+eb 13 48 c7 c3 9f ff ff ff eb 0f 89 ce e8 f1 ae f1 ff 48 89 c3 48 85 db
+74 15 <48> 8b 83 08 04 00 00 65 ff 08 48 81 fb 00 f0 ff ff 76 0d eb 07
+[  822.340033] RIP  [<ffffffff8148781e>] mpls_nh_assign_dev+0x10b/0x182
+[  822.340033]  RSP <ffff88001dad7a88>
+[  822.340033] CR2: 00000000000003a3
+[  822.435363] ---[ end trace 98cc65e6f6b8bf11 ]---
+
+After patch:
+$ip -f mpls route add 100 as 200 via inet 10.1.1.8
+RTNETLINK answers: Network is unreachable
+
+Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
+Reported-by: David Miller <davem@davemloft.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mpls/af_mpls.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/net/mpls/af_mpls.c
++++ b/net/mpls/af_mpls.c
+@@ -518,6 +518,9 @@ static struct net_device *find_outdev(st
+       if (!dev)
+               return ERR_PTR(-ENODEV);
++      if (IS_ERR(dev))
++              return dev;
++
+       /* The caller is holding rtnl anyways, so release the dev reference */
+       dev_put(dev);
diff --git a/queue-4.4/net-bcmgenet-fix-dma-api-length-mismatch.patch b/queue-4.4/net-bcmgenet-fix-dma-api-length-mismatch.patch
new file mode 100644 (file)
index 0000000..9102a6e
--- /dev/null
@@ -0,0 +1,45 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Eric Dumazet <edumazet@google.com>
+Date: Thu, 17 Mar 2016 11:57:06 -0700
+Subject: net: bcmgenet: fix dma api length mismatch
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit eee577232203842b4dcadb7ab477a298479633ed ]
+
+When un-mapping skb->data in __bcmgenet_tx_reclaim(),
+we must use the length that was used in original dma_map_single(),
+instead of skb->len that might be bigger (includes the frags)
+
+We simply can store skb_len into tx_cb_ptr->dma_len and use it
+at unmap time.
+
+Fixes: 1c1008c793fa ("net: bcmgenet: add main driver file")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Acked-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/broadcom/genet/bcmgenet.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+@@ -1197,7 +1197,7 @@ static unsigned int __bcmgenet_tx_reclai
+                       dev->stats.tx_bytes += tx_cb_ptr->skb->len;
+                       dma_unmap_single(&dev->dev,
+                                        dma_unmap_addr(tx_cb_ptr, dma_addr),
+-                                       tx_cb_ptr->skb->len,
++                                       dma_unmap_len(tx_cb_ptr, dma_len),
+                                        DMA_TO_DEVICE);
+                       bcmgenet_free_cb(tx_cb_ptr);
+               } else if (dma_unmap_addr(tx_cb_ptr, dma_addr)) {
+@@ -1308,7 +1308,7 @@ static int bcmgenet_xmit_single(struct n
+       }
+       dma_unmap_addr_set(tx_cb_ptr, dma_addr, mapping);
+-      dma_unmap_len_set(tx_cb_ptr, dma_len, skb->len);
++      dma_unmap_len_set(tx_cb_ptr, dma_len, skb_len);
+       length_status = (skb_len << DMA_BUFLENGTH_SHIFT) | dma_desc_flags |
+                       (priv->hw_params->qtag_mask << DMA_TX_QTAG_SHIFT) |
+                       DMA_TX_APPEND_CRC;
diff --git a/queue-4.4/net-fix-bridge-multicast-packet-checksum-validation.patch b/queue-4.4/net-fix-bridge-multicast-packet-checksum-validation.patch
new file mode 100644 (file)
index 0000000..35876d0
--- /dev/null
@@ -0,0 +1,107 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: =?UTF-8?q?Linus=20L=C3=BCssing?= <linus.luessing@c0d3.blue>
+Date: Wed, 24 Feb 2016 04:21:42 +0100
+Subject: net: fix bridge multicast packet checksum validation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: =?UTF-8?q?Linus=20L=C3=BCssing?= <linus.luessing@c0d3.blue>
+
+[ Upstream commit 9b368814b336b0a1a479135eb2815edbc00efd3c ]
+
+We need to update the skb->csum after pulling the skb, otherwise
+an unnecessary checksum (re)computation can ocure for IGMP/MLD packets
+in the bridge code. Additionally this fixes the following splats for
+network devices / bridge ports with support for and enabled RX checksum
+offloading:
+
+[...]
+[   43.986968] eth0: hw csum failure
+[   43.990344] CPU: 3 PID: 0 Comm: swapper/3 Not tainted 4.4.0 #2
+[   43.996193] Hardware name: BCM2709
+[   43.999647] [<800204e0>] (unwind_backtrace) from [<8001cf14>] (show_stack+0x10/0x14)
+[   44.007432] [<8001cf14>] (show_stack) from [<801ab614>] (dump_stack+0x80/0x90)
+[   44.014695] [<801ab614>] (dump_stack) from [<802e4548>] (__skb_checksum_complete+0x6c/0xac)
+[   44.023090] [<802e4548>] (__skb_checksum_complete) from [<803a055c>] (ipv6_mc_validate_checksum+0x104/0x178)
+[   44.032959] [<803a055c>] (ipv6_mc_validate_checksum) from [<802e111c>] (skb_checksum_trimmed+0x130/0x188)
+[   44.042565] [<802e111c>] (skb_checksum_trimmed) from [<803a06e8>] (ipv6_mc_check_mld+0x118/0x338)
+[   44.051501] [<803a06e8>] (ipv6_mc_check_mld) from [<803b2c98>] (br_multicast_rcv+0x5dc/0xd00)
+[   44.060077] [<803b2c98>] (br_multicast_rcv) from [<803aa510>] (br_handle_frame_finish+0xac/0x51c)
+[...]
+
+Fixes: 9afd85c9e455 ("net: Export IGMP/MLD message validation code")
+Reported-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/skbuff.h |   17 +++++++++++++++++
+ net/core/skbuff.c      |   22 ++++++++++++++++++++--
+ 2 files changed, 37 insertions(+), 2 deletions(-)
+
+--- a/include/linux/skbuff.h
++++ b/include/linux/skbuff.h
+@@ -2724,6 +2724,23 @@ static inline void skb_postpull_rcsum(st
+ unsigned char *skb_pull_rcsum(struct sk_buff *skb, unsigned int len);
++static inline void skb_postpush_rcsum(struct sk_buff *skb,
++                                    const void *start, unsigned int len)
++{
++      /* For performing the reverse operation to skb_postpull_rcsum(),
++       * we can instead of ...
++       *
++       *   skb->csum = csum_add(skb->csum, csum_partial(start, len, 0));
++       *
++       * ... just use this equivalent version here to save a few
++       * instructions. Feeding csum of 0 in csum_partial() and later
++       * on adding skb->csum is equivalent to feed skb->csum in the
++       * first place.
++       */
++      if (skb->ip_summed == CHECKSUM_COMPLETE)
++              skb->csum = csum_partial(start, len, skb->csum);
++}
++
+ /**
+  *    pskb_trim_rcsum - trim received skb and update checksum
+  *    @skb: buffer to trim
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -2948,6 +2948,24 @@ int skb_append_pagefrags(struct sk_buff
+ EXPORT_SYMBOL_GPL(skb_append_pagefrags);
+ /**
++ *    skb_push_rcsum - push skb and update receive checksum
++ *    @skb: buffer to update
++ *    @len: length of data pulled
++ *
++ *    This function performs an skb_push on the packet and updates
++ *    the CHECKSUM_COMPLETE checksum.  It should be used on
++ *    receive path processing instead of skb_push unless you know
++ *    that the checksum difference is zero (e.g., a valid IP header)
++ *    or you are setting ip_summed to CHECKSUM_NONE.
++ */
++static unsigned char *skb_push_rcsum(struct sk_buff *skb, unsigned len)
++{
++      skb_push(skb, len);
++      skb_postpush_rcsum(skb, skb->data, len);
++      return skb->data;
++}
++
++/**
+  *    skb_pull_rcsum - pull skb and update receive checksum
+  *    @skb: buffer to update
+  *    @len: length of data pulled
+@@ -4084,9 +4102,9 @@ struct sk_buff *skb_checksum_trimmed(str
+       if (!pskb_may_pull(skb_chk, offset))
+               goto err;
+-      __skb_pull(skb_chk, offset);
++      skb_pull_rcsum(skb_chk, offset);
+       ret = skb_chkf(skb_chk);
+-      __skb_push(skb_chk, offset);
++      skb_push_rcsum(skb_chk, offset);
+       if (ret)
+               goto err;
diff --git a/queue-4.4/net-fix-use-after-free-in-the-recvmmsg-exit-path.patch b/queue-4.4/net-fix-use-after-free-in-the-recvmmsg-exit-path.patch
new file mode 100644 (file)
index 0000000..8e82e60
--- /dev/null
@@ -0,0 +1,91 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Arnaldo Carvalho de Melo <acme@redhat.com>
+Date: Mon, 14 Mar 2016 09:56:35 -0300
+Subject: net: Fix use after free in the recvmmsg exit path
+
+From: Arnaldo Carvalho de Melo <acme@redhat.com>
+
+[ Upstream commit 34b88a68f26a75e4fded796f1a49c40f82234b7d ]
+
+The syzkaller fuzzer hit the following use-after-free:
+
+  Call Trace:
+   [<ffffffff8175ea0e>] __asan_report_load8_noabort+0x3e/0x40 mm/kasan/report.c:295
+   [<ffffffff851cc31a>] __sys_recvmmsg+0x6fa/0x7f0 net/socket.c:2261
+   [<     inline     >] SYSC_recvmmsg net/socket.c:2281
+   [<ffffffff851cc57f>] SyS_recvmmsg+0x16f/0x180 net/socket.c:2270
+   [<ffffffff86332bb6>] entry_SYSCALL_64_fastpath+0x16/0x7a
+  arch/x86/entry/entry_64.S:185
+
+And, as Dmitry rightly assessed, that is because we can drop the
+reference and then touch it when the underlying recvmsg calls return
+some packets and then hit an error, which will make recvmmsg to set
+sock->sk->sk_err, oops, fix it.
+
+Reported-and-Tested-by: Dmitry Vyukov <dvyukov@google.com>
+Cc: Alexander Potapenko <glider@google.com>
+Cc: Eric Dumazet <edumazet@google.com>
+Cc: Kostya Serebryany <kcc@google.com>
+Cc: Sasha Levin <sasha.levin@oracle.com>
+Fixes: a2e2725541fa ("net: Introduce recvmmsg socket syscall")
+http://lkml.kernel.org/r/20160122211644.GC2470@redhat.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/socket.c |   38 +++++++++++++++++++-------------------
+ 1 file changed, 19 insertions(+), 19 deletions(-)
+
+--- a/net/socket.c
++++ b/net/socket.c
+@@ -2238,31 +2238,31 @@ int __sys_recvmmsg(int fd, struct mmsghd
+                       break;
+       }
+-out_put:
+-      fput_light(sock->file, fput_needed);
+-
+       if (err == 0)
+-              return datagrams;
++              goto out_put;
++
++      if (datagrams == 0) {
++              datagrams = err;
++              goto out_put;
++      }
+-      if (datagrams != 0) {
++      /*
++       * We may return less entries than requested (vlen) if the
++       * sock is non block and there aren't enough datagrams...
++       */
++      if (err != -EAGAIN) {
+               /*
+-               * We may return less entries than requested (vlen) if the
+-               * sock is non block and there aren't enough datagrams...
++               * ... or  if recvmsg returns an error after we
++               * received some datagrams, where we record the
++               * error to return on the next call or if the
++               * app asks about it using getsockopt(SO_ERROR).
+                */
+-              if (err != -EAGAIN) {
+-                      /*
+-                       * ... or  if recvmsg returns an error after we
+-                       * received some datagrams, where we record the
+-                       * error to return on the next call or if the
+-                       * app asks about it using getsockopt(SO_ERROR).
+-                       */
+-                      sock->sk->sk_err = -err;
+-              }
+-
+-              return datagrams;
++              sock->sk->sk_err = -err;
+       }
++out_put:
++      fput_light(sock->file, fput_needed);
+-      return err;
++      return datagrams;
+ }
+ SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg,
diff --git a/queue-4.4/net-jme-fix-suspend-resume-on-jmc260.patch b/queue-4.4/net-jme-fix-suspend-resume-on-jmc260.patch
new file mode 100644 (file)
index 0000000..565a741
--- /dev/null
@@ -0,0 +1,43 @@
+From foo@baz Sat Apr 16 10:02:52 PDT 2016
+From: Diego Viola <diego.viola@gmail.com>
+Date: Tue, 23 Feb 2016 12:04:04 -0300
+Subject: net: jme: fix suspend/resume on JMC260
+
+From: Diego Viola <diego.viola@gmail.com>
+
+[ Upstream commit ee50c130c82175eaa0820c96b6d3763928af2241 ]
+
+The JMC260 network card fails to suspend/resume because the call to
+jme_start_irq() was too early, moving the call to jme_start_irq() after
+the call to jme_reset_link() makes it work.
+
+Prior this change suspend/resume would fail unless /sys/power/pm_async=0
+was explicitly specified.
+
+Relevant bug report: https://bugzilla.kernel.org/show_bug.cgi?id=112351
+
+Signed-off-by: Diego Viola <diego.viola@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/jme.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/jme.c
++++ b/drivers/net/ethernet/jme.c
+@@ -3312,13 +3312,14 @@ jme_resume(struct device *dev)
+               jme_reset_phy_processor(jme);
+       jme_phy_calibration(jme);
+       jme_phy_setEA(jme);
+-      jme_start_irq(jme);
+       netif_device_attach(netdev);
+       atomic_inc(&jme->link_changing);
+       jme_reset_link(jme);
++      jme_start_irq(jme);
++
+       return 0;
+ }
diff --git a/queue-4.4/net-qca_spi-clear-iff_tx_skb_sharing.patch b/queue-4.4/net-qca_spi-clear-iff_tx_skb_sharing.patch
new file mode 100644 (file)
index 0000000..4a71c81
--- /dev/null
@@ -0,0 +1,30 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Stefan Wahren <stefan.wahren@i2se.com>
+Date: Tue, 23 Feb 2016 19:23:24 +0000
+Subject: net: qca_spi: clear IFF_TX_SKB_SHARING
+
+From: Stefan Wahren <stefan.wahren@i2se.com>
+
+[ Upstream commit a4690afeb0d2d7ba4d60dfa98a89f3bb1ce60ecd ]
+
+ether_setup sets IFF_TX_SKB_SHARING but this is not supported by
+qca_spi as it modifies the skb on xmit.
+
+Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
+Fixes: 291ab06ecf67 (net: qualcomm: new Ethernet over SPI driver for QCA7000)
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/qualcomm/qca_spi.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/ethernet/qualcomm/qca_spi.c
++++ b/drivers/net/ethernet/qualcomm/qca_spi.c
+@@ -811,6 +811,7 @@ qcaspi_netdev_setup(struct net_device *d
+       dev->netdev_ops = &qcaspi_netdev_ops;
+       qcaspi_set_ethtool_ops(dev);
+       dev->watchdog_timeo = QCASPI_TX_TIMEOUT;
++      dev->priv_flags &= ~IFF_TX_SKB_SHARING;
+       dev->tx_queue_len = 100;
+       qca = netdev_priv(dev);
diff --git a/queue-4.4/net-qca_spi-don-t-clear-iff_broadcast.patch b/queue-4.4/net-qca_spi-don-t-clear-iff_broadcast.patch
new file mode 100644 (file)
index 0000000..439864e
--- /dev/null
@@ -0,0 +1,31 @@
+From foo@baz Sat Apr 16 10:02:52 PDT 2016
+From: Stefan Wahren <stefan.wahren@i2se.com>
+Date: Tue, 23 Feb 2016 19:23:23 +0000
+Subject: net: qca_spi: Don't clear IFF_BROADCAST
+
+From: Stefan Wahren <stefan.wahren@i2se.com>
+
+[ Upstream commit 2b70bad23c89b121a3e4a00f8968d14ebb78887d ]
+
+Currently qcaspi_netdev_setup accidentally clears IFF_BROADCAST.
+So fix this by keeping the flags from ether_setup.
+
+Reported-by: Michael Heimpold <michael.heimpold@i2se.com>
+Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
+Fixes: 291ab06ecf67 (net: qualcomm: new Ethernet over SPI driver for QCA7000)
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/qualcomm/qca_spi.c |    1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/net/ethernet/qualcomm/qca_spi.c
++++ b/drivers/net/ethernet/qualcomm/qca_spi.c
+@@ -811,7 +811,6 @@ qcaspi_netdev_setup(struct net_device *d
+       dev->netdev_ops = &qcaspi_netdev_ops;
+       qcaspi_set_ethtool_ops(dev);
+       dev->watchdog_timeo = QCASPI_TX_TIMEOUT;
+-      dev->flags = IFF_MULTICAST;
+       dev->tx_queue_len = 100;
+       qca = netdev_priv(dev);
diff --git a/queue-4.4/net-validate-variable-length-ll-headers.patch b/queue-4.4/net-validate-variable-length-ll-headers.patch
new file mode 100644 (file)
index 0000000..a7bd1ac
--- /dev/null
@@ -0,0 +1,75 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Willem de Bruijn <willemb@google.com>
+Date: Wed, 9 Mar 2016 21:58:32 -0500
+Subject: net: validate variable length ll headers
+
+From: Willem de Bruijn <willemb@google.com>
+
+[ Upstream commit 2793a23aacbd754dbbb5cb75093deb7e4103bace ]
+
+Netdevice parameter hard_header_len is variously interpreted both as
+an upper and lower bound on link layer header length. The field is
+used as upper bound when reserving room at allocation, as lower bound
+when validating user input in PF_PACKET.
+
+Clarify the definition to be maximum header length. For validation
+of untrusted headers, add an optional validate member to header_ops.
+
+Allow bypassing of validation by passing CAP_SYS_RAWIO, for instance
+for deliberate testing of corrupt input. In this case, pad trailing
+bytes, as some device drivers expect completely initialized headers.
+
+See also http://comments.gmane.org/gmane.linux.network/401064
+
+Signed-off-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/netdevice.h |   22 ++++++++++++++++++++--
+ 1 file changed, 20 insertions(+), 2 deletions(-)
+
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -265,6 +265,7 @@ struct header_ops {
+       void    (*cache_update)(struct hh_cache *hh,
+                               const struct net_device *dev,
+                               const unsigned char *haddr);
++      bool    (*validate)(const char *ll_header, unsigned int len);
+ };
+ /* These flag bits are private to the generic network queueing
+@@ -1398,8 +1399,7 @@ enum netdev_priv_flags {
+  *    @dma:           DMA channel
+  *    @mtu:           Interface MTU value
+  *    @type:          Interface hardware type
+- *    @hard_header_len: Hardware header length, which means that this is the
+- *                      minimum size of a packet.
++ *    @hard_header_len: Maximum hardware header length.
+  *
+  *    @needed_headroom: Extra headroom the hardware may need, but not in all
+  *                      cases can this be guaranteed
+@@ -2493,6 +2493,24 @@ static inline int dev_parse_header(const
+       return dev->header_ops->parse(skb, haddr);
+ }
++/* ll_header must have at least hard_header_len allocated */
++static inline bool dev_validate_header(const struct net_device *dev,
++                                     char *ll_header, int len)
++{
++      if (likely(len >= dev->hard_header_len))
++              return true;
++
++      if (capable(CAP_SYS_RAWIO)) {
++              memset(ll_header + len, 0, dev->hard_header_len - len);
++              return true;
++      }
++
++      if (dev->header_ops && dev->header_ops->validate)
++              return dev->header_ops->validate(ll_header, len);
++
++      return false;
++}
++
+ typedef int gifconf_func_t(struct net_device * dev, char __user * bufptr, int len);
+ int register_gifconf(unsigned int family, gifconf_func_t *gifconf);
+ static inline int unregister_gifconf(unsigned int family)
diff --git a/queue-4.4/net-vrf-remove-direct-access-to-skb-data.patch b/queue-4.4/net-vrf-remove-direct-access-to-skb-data.patch
new file mode 100644 (file)
index 0000000..d16a423
--- /dev/null
@@ -0,0 +1,54 @@
+From foo@baz Sat Apr 16 10:02:52 PDT 2016
+From: David Ahern <dsa@cumulusnetworks.com>
+Date: Tue, 23 Feb 2016 10:10:26 -0800
+Subject: net: vrf: Remove direct access to skb->data
+
+From: David Ahern <dsa@cumulusnetworks.com>
+
+[ Upstream commit 65c38aa653c14df49e19faad74bd375f36e61c57 ]
+
+Nik pointed that the VRF driver should be using skb_header_pointer
+instead of accessing skb->data and bits beyond directly which can
+be garbage.
+
+Fixes: 35402e313663 ("net: Add IPv6 support to VRF device")
+Cc: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
+Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
+Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/vrf.c |   13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/vrf.c
++++ b/drivers/net/vrf.c
+@@ -114,20 +114,23 @@ static struct dst_ops vrf_dst_ops = {
+ #if IS_ENABLED(CONFIG_IPV6)
+ static bool check_ipv6_frame(const struct sk_buff *skb)
+ {
+-      const struct ipv6hdr *ipv6h = (struct ipv6hdr *)skb->data;
+-      size_t hlen = sizeof(*ipv6h);
++      const struct ipv6hdr *ipv6h;
++      struct ipv6hdr _ipv6h;
+       bool rc = true;
+-      if (skb->len < hlen)
++      ipv6h = skb_header_pointer(skb, 0, sizeof(_ipv6h), &_ipv6h);
++      if (!ipv6h)
+               goto out;
+       if (ipv6h->nexthdr == NEXTHDR_ICMP) {
+               const struct icmp6hdr *icmph;
++              struct icmp6hdr _icmph;
+-              if (skb->len < hlen + sizeof(*icmph))
++              icmph = skb_header_pointer(skb, sizeof(_ipv6h),
++                                         sizeof(_icmph), &_icmph);
++              if (!icmph)
+                       goto out;
+-              icmph = (struct icmp6hdr *)(skb->data + sizeof(*ipv6h));
+               switch (icmph->icmp6_type) {
+               case NDISC_ROUTER_SOLICITATION:
+               case NDISC_ROUTER_ADVERTISEMENT:
diff --git a/queue-4.4/packet-validate-variable-length-ll-headers.patch b/queue-4.4/packet-validate-variable-length-ll-headers.patch
new file mode 100644 (file)
index 0000000..fe54c08
--- /dev/null
@@ -0,0 +1,108 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Willem de Bruijn <willemb@google.com>
+Date: Wed, 9 Mar 2016 21:58:34 -0500
+Subject: packet: validate variable length ll headers
+
+From: Willem de Bruijn <willemb@google.com>
+
+[ Upstream commit 9ed988cd591500c040b2a6257bc68543e08ceeef ]
+
+Replace link layer header validation check ll_header_truncate with
+more generic dev_validate_header.
+
+Validation based on hard_header_len incorrectly drops valid packets
+in variable length protocols, such as AX25. dev_validate_header
+calls header_ops.validate for such protocols to ensure correctness
+below hard_header_len.
+
+See also http://comments.gmane.org/gmane.linux.network/401064
+
+Fixes 9c7077622dd9 ("packet: make packet_snd fail on len smaller than l2 header")
+Signed-off-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/packet/af_packet.c |   37 ++++++++++++++++---------------------
+ 1 file changed, 16 insertions(+), 21 deletions(-)
+
+--- a/net/packet/af_packet.c
++++ b/net/packet/af_packet.c
+@@ -1916,6 +1916,10 @@ retry:
+               goto retry;
+       }
++      if (!dev_validate_header(dev, skb->data, len)) {
++              err = -EINVAL;
++              goto out_unlock;
++      }
+       if (len > (dev->mtu + dev->hard_header_len + extra_len) &&
+           !packet_extra_vlan_len_allowed(dev, skb)) {
+               err = -EMSGSIZE;
+@@ -2326,18 +2330,6 @@ static void tpacket_destruct_skb(struct
+       sock_wfree(skb);
+ }
+-static bool ll_header_truncated(const struct net_device *dev, int len)
+-{
+-      /* net device doesn't like empty head */
+-      if (unlikely(len < dev->hard_header_len)) {
+-              net_warn_ratelimited("%s: packet size is too short (%d < %d)\n",
+-                                   current->comm, len, dev->hard_header_len);
+-              return true;
+-      }
+-
+-      return false;
+-}
+-
+ static void tpacket_set_protocol(const struct net_device *dev,
+                                struct sk_buff *skb)
+ {
+@@ -2420,19 +2412,19 @@ static int tpacket_fill_skb(struct packe
+               if (unlikely(err < 0))
+                       return -EINVAL;
+       } else if (dev->hard_header_len) {
+-              if (ll_header_truncated(dev, tp_len))
+-                      return -EINVAL;
++              int hdrlen = min_t(int, dev->hard_header_len, tp_len);
+               skb_push(skb, dev->hard_header_len);
+-              err = skb_store_bits(skb, 0, data,
+-                              dev->hard_header_len);
++              err = skb_store_bits(skb, 0, data, hdrlen);
+               if (unlikely(err))
+                       return err;
++              if (!dev_validate_header(dev, skb->data, hdrlen))
++                      return -EINVAL;
+               if (!skb->protocol)
+                       tpacket_set_protocol(dev, skb);
+-              data += dev->hard_header_len;
+-              to_write -= dev->hard_header_len;
++              data += hdrlen;
++              to_write -= hdrlen;
+       }
+       offset = offset_in_page(data);
+@@ -2763,9 +2755,6 @@ static int packet_snd(struct socket *soc
+               offset = dev_hard_header(skb, dev, ntohs(proto), addr, NULL, len);
+               if (unlikely(offset < 0))
+                       goto out_free;
+-      } else {
+-              if (ll_header_truncated(dev, len))
+-                      goto out_free;
+       }
+       /* Returns -EFAULT on error */
+@@ -2773,6 +2762,12 @@ static int packet_snd(struct socket *soc
+       if (err)
+               goto out_free;
++      if (sock->type == SOCK_RAW &&
++          !dev_validate_header(dev, skb->data, len)) {
++              err = -EINVAL;
++              goto out_free;
++      }
++
+       sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags);
+       if (!gso_type && (len > dev->mtu + reserve + extra_len) &&
diff --git a/queue-4.4/ppp-ensure-file-private_data-can-t-be-overridden.patch b/queue-4.4/ppp-ensure-file-private_data-can-t-be-overridden.patch
new file mode 100644 (file)
index 0000000..55fdc85
--- /dev/null
@@ -0,0 +1,128 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Guillaume Nault <g.nault@alphalink.fr>
+Date: Mon, 14 Mar 2016 21:17:16 +0100
+Subject: ppp: ensure file->private_data can't be overridden
+
+From: Guillaume Nault <g.nault@alphalink.fr>
+
+[ Upstream commit e8e56ffd9d2973398b60ece1f1bebb8d67b4d032 ]
+
+Locking ppp_mutex must be done before dereferencing file->private_data,
+otherwise it could be modified before ppp_unattached_ioctl() takes the
+lock. This could lead ppp_unattached_ioctl() to override ->private_data,
+thus leaking reference to the ppp_file previously pointed to.
+
+v2: lock all ppp_ioctl() instead of just checking private_data in
+    ppp_unattached_ioctl(), to avoid ambiguous behaviour.
+
+Fixes: f3ff8a4d80e8 ("ppp: push BKL down into the driver")
+Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ppp/ppp_generic.c |   31 +++++++++++++++++--------------
+ 1 file changed, 17 insertions(+), 14 deletions(-)
+
+--- a/drivers/net/ppp/ppp_generic.c
++++ b/drivers/net/ppp/ppp_generic.c
+@@ -567,7 +567,7 @@ static int get_filter(void __user *arg,
+ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+ {
+-      struct ppp_file *pf = file->private_data;
++      struct ppp_file *pf;
+       struct ppp *ppp;
+       int err = -EFAULT, val, val2, i;
+       struct ppp_idle idle;
+@@ -577,9 +577,14 @@ static long ppp_ioctl(struct file *file,
+       void __user *argp = (void __user *)arg;
+       int __user *p = argp;
+-      if (!pf)
+-              return ppp_unattached_ioctl(current->nsproxy->net_ns,
+-                                      pf, file, cmd, arg);
++      mutex_lock(&ppp_mutex);
++
++      pf = file->private_data;
++      if (!pf) {
++              err = ppp_unattached_ioctl(current->nsproxy->net_ns,
++                                         pf, file, cmd, arg);
++              goto out;
++      }
+       if (cmd == PPPIOCDETACH) {
+               /*
+@@ -594,7 +599,6 @@ static long ppp_ioctl(struct file *file,
+                * this fd and reopening /dev/ppp.
+                */
+               err = -EINVAL;
+-              mutex_lock(&ppp_mutex);
+               if (pf->kind == INTERFACE) {
+                       ppp = PF_TO_PPP(pf);
+                       rtnl_lock();
+@@ -608,15 +612,13 @@ static long ppp_ioctl(struct file *file,
+               } else
+                       pr_warn("PPPIOCDETACH file->f_count=%ld\n",
+                               atomic_long_read(&file->f_count));
+-              mutex_unlock(&ppp_mutex);
+-              return err;
++              goto out;
+       }
+       if (pf->kind == CHANNEL) {
+               struct channel *pch;
+               struct ppp_channel *chan;
+-              mutex_lock(&ppp_mutex);
+               pch = PF_TO_CHANNEL(pf);
+               switch (cmd) {
+@@ -638,17 +640,16 @@ static long ppp_ioctl(struct file *file,
+                               err = chan->ops->ioctl(chan, cmd, arg);
+                       up_read(&pch->chan_sem);
+               }
+-              mutex_unlock(&ppp_mutex);
+-              return err;
++              goto out;
+       }
+       if (pf->kind != INTERFACE) {
+               /* can't happen */
+               pr_err("PPP: not interface or channel??\n");
+-              return -EINVAL;
++              err = -EINVAL;
++              goto out;
+       }
+-      mutex_lock(&ppp_mutex);
+       ppp = PF_TO_PPP(pf);
+       switch (cmd) {
+       case PPPIOCSMRU:
+@@ -823,7 +824,10 @@ static long ppp_ioctl(struct file *file,
+       default:
+               err = -ENOTTY;
+       }
++
++out:
+       mutex_unlock(&ppp_mutex);
++
+       return err;
+ }
+@@ -836,7 +840,6 @@ static int ppp_unattached_ioctl(struct n
+       struct ppp_net *pn;
+       int __user *p = (int __user *)arg;
+-      mutex_lock(&ppp_mutex);
+       switch (cmd) {
+       case PPPIOCNEWUNIT:
+               /* Create a new ppp unit */
+@@ -886,7 +889,7 @@ static int ppp_unattached_ioctl(struct n
+       default:
+               err = -ENOTTY;
+       }
+-      mutex_unlock(&ppp_mutex);
++
+       return err;
+ }
diff --git a/queue-4.4/ppp-release-rtnl-mutex-when-interface-creation-fails.patch b/queue-4.4/ppp-release-rtnl-mutex-when-interface-creation-fails.patch
new file mode 100644 (file)
index 0000000..8a4f713
--- /dev/null
@@ -0,0 +1,29 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Guillaume Nault <g.nault@alphalink.fr>
+Date: Mon, 7 Mar 2016 19:36:44 +0100
+Subject: ppp: release rtnl mutex when interface creation fails
+
+From: Guillaume Nault <g.nault@alphalink.fr>
+
+[ Upstream commit 6faac63a6986f29ef39827f460edd3a5ba64ad5c ]
+
+Add missing rtnl_unlock() in the error path of ppp_create_interface().
+
+Fixes: 58a89ecaca53 ("ppp: fix lockdep splat in ppp_dev_uninit()")
+Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ppp/ppp_generic.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/ppp/ppp_generic.c
++++ b/drivers/net/ppp/ppp_generic.c
+@@ -2803,6 +2803,7 @@ static struct ppp *ppp_create_interface(
+ out2:
+       mutex_unlock(&pn->all_ppp_mutex);
++      rtnl_unlock();
+       free_netdev(dev);
+ out1:
+       *retp = ret;
diff --git a/queue-4.4/ppp-take-reference-on-channels-netns.patch b/queue-4.4/ppp-take-reference-on-channels-netns.patch
new file mode 100644 (file)
index 0000000..d3d3a1e
--- /dev/null
@@ -0,0 +1,149 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Guillaume Nault <g.nault@alphalink.fr>
+Date: Wed, 23 Mar 2016 16:38:55 +0100
+Subject: ppp: take reference on channels netns
+
+From: Guillaume Nault <g.nault@alphalink.fr>
+
+[ Upstream commit 1f461dcdd296eecedaffffc6bae2bfa90bd7eb89 ]
+
+Let channels hold a reference on their network namespace.
+Some channel types, like ppp_async and ppp_synctty, can have their
+userspace controller running in a different namespace. Therefore they
+can't rely on them to preclude their netns from being removed from
+under them.
+
+==================================================================
+BUG: KASAN: use-after-free in ppp_unregister_channel+0x372/0x3a0 at
+addr ffff880064e217e0
+Read of size 8 by task syz-executor/11581
+=============================================================================
+BUG net_namespace (Not tainted): kasan: bad access detected
+-----------------------------------------------------------------------------
+
+Disabling lock debugging due to kernel taint
+INFO: Allocated in copy_net_ns+0x6b/0x1a0 age=92569 cpu=3 pid=6906
+[<      none      >] ___slab_alloc+0x4c7/0x500 kernel/mm/slub.c:2440
+[<      none      >] __slab_alloc+0x4c/0x90 kernel/mm/slub.c:2469
+[<     inline     >] slab_alloc_node kernel/mm/slub.c:2532
+[<     inline     >] slab_alloc kernel/mm/slub.c:2574
+[<      none      >] kmem_cache_alloc+0x23a/0x2b0 kernel/mm/slub.c:2579
+[<     inline     >] kmem_cache_zalloc kernel/include/linux/slab.h:597
+[<     inline     >] net_alloc kernel/net/core/net_namespace.c:325
+[<      none      >] copy_net_ns+0x6b/0x1a0 kernel/net/core/net_namespace.c:360
+[<      none      >] create_new_namespaces+0x2f6/0x610 kernel/kernel/nsproxy.c:95
+[<      none      >] copy_namespaces+0x297/0x320 kernel/kernel/nsproxy.c:150
+[<      none      >] copy_process.part.35+0x1bf4/0x5760 kernel/kernel/fork.c:1451
+[<     inline     >] copy_process kernel/kernel/fork.c:1274
+[<      none      >] _do_fork+0x1bc/0xcb0 kernel/kernel/fork.c:1723
+[<     inline     >] SYSC_clone kernel/kernel/fork.c:1832
+[<      none      >] SyS_clone+0x37/0x50 kernel/kernel/fork.c:1826
+[<      none      >] entry_SYSCALL_64_fastpath+0x16/0x7a kernel/arch/x86/entry/entry_64.S:185
+
+INFO: Freed in net_drop_ns+0x67/0x80 age=575 cpu=2 pid=2631
+[<      none      >] __slab_free+0x1fc/0x320 kernel/mm/slub.c:2650
+[<     inline     >] slab_free kernel/mm/slub.c:2805
+[<      none      >] kmem_cache_free+0x2a0/0x330 kernel/mm/slub.c:2814
+[<     inline     >] net_free kernel/net/core/net_namespace.c:341
+[<      none      >] net_drop_ns+0x67/0x80 kernel/net/core/net_namespace.c:348
+[<      none      >] cleanup_net+0x4e5/0x600 kernel/net/core/net_namespace.c:448
+[<      none      >] process_one_work+0x794/0x1440 kernel/kernel/workqueue.c:2036
+[<      none      >] worker_thread+0xdb/0xfc0 kernel/kernel/workqueue.c:2170
+[<      none      >] kthread+0x23f/0x2d0 kernel/drivers/block/aoe/aoecmd.c:1303
+[<      none      >] ret_from_fork+0x3f/0x70 kernel/arch/x86/entry/entry_64.S:468
+INFO: Slab 0xffffea0001938800 objects=3 used=0 fp=0xffff880064e20000
+flags=0x5fffc0000004080
+INFO: Object 0xffff880064e20000 @offset=0 fp=0xffff880064e24200
+
+CPU: 1 PID: 11581 Comm: syz-executor Tainted: G    B           4.4.0+
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
+rel-1.8.2-0-g33fbe13 by qemu-project.org 04/01/2014
+ 00000000ffffffff ffff8800662c7790 ffffffff8292049d ffff88003e36a300
+ ffff880064e20000 ffff880064e20000 ffff8800662c77c0 ffffffff816f2054
+ ffff88003e36a300 ffffea0001938800 ffff880064e20000 0000000000000000
+Call Trace:
+ [<     inline     >] __dump_stack kernel/lib/dump_stack.c:15
+ [<ffffffff8292049d>] dump_stack+0x6f/0xa2 kernel/lib/dump_stack.c:50
+ [<ffffffff816f2054>] print_trailer+0xf4/0x150 kernel/mm/slub.c:654
+ [<ffffffff816f875f>] object_err+0x2f/0x40 kernel/mm/slub.c:661
+ [<     inline     >] print_address_description kernel/mm/kasan/report.c:138
+ [<ffffffff816fb0c5>] kasan_report_error+0x215/0x530 kernel/mm/kasan/report.c:236
+ [<     inline     >] kasan_report kernel/mm/kasan/report.c:259
+ [<ffffffff816fb4de>] __asan_report_load8_noabort+0x3e/0x40 kernel/mm/kasan/report.c:280
+ [<     inline     >] ? ppp_pernet kernel/include/linux/compiler.h:218
+ [<ffffffff83ad71b2>] ? ppp_unregister_channel+0x372/0x3a0 kernel/drivers/net/ppp/ppp_generic.c:2392
+ [<     inline     >] ppp_pernet kernel/include/linux/compiler.h:218
+ [<ffffffff83ad71b2>] ppp_unregister_channel+0x372/0x3a0 kernel/drivers/net/ppp/ppp_generic.c:2392
+ [<     inline     >] ? ppp_pernet kernel/drivers/net/ppp/ppp_generic.c:293
+ [<ffffffff83ad6f26>] ? ppp_unregister_channel+0xe6/0x3a0 kernel/drivers/net/ppp/ppp_generic.c:2392
+ [<ffffffff83ae18f3>] ppp_asynctty_close+0xa3/0x130 kernel/drivers/net/ppp/ppp_async.c:241
+ [<ffffffff83ae1850>] ? async_lcp_peek+0x5b0/0x5b0 kernel/drivers/net/ppp/ppp_async.c:1000
+ [<ffffffff82c33239>] tty_ldisc_close.isra.1+0x99/0xe0 kernel/drivers/tty/tty_ldisc.c:478
+ [<ffffffff82c332c0>] tty_ldisc_kill+0x40/0x170 kernel/drivers/tty/tty_ldisc.c:744
+ [<ffffffff82c34943>] tty_ldisc_release+0x1b3/0x260 kernel/drivers/tty/tty_ldisc.c:772
+ [<ffffffff82c1ef21>] tty_release+0xac1/0x13e0 kernel/drivers/tty/tty_io.c:1901
+ [<ffffffff82c1e460>] ? release_tty+0x320/0x320 kernel/drivers/tty/tty_io.c:1688
+ [<ffffffff8174de36>] __fput+0x236/0x780 kernel/fs/file_table.c:208
+ [<ffffffff8174e405>] ____fput+0x15/0x20 kernel/fs/file_table.c:244
+ [<ffffffff813595ab>] task_work_run+0x16b/0x200 kernel/kernel/task_work.c:115
+ [<     inline     >] exit_task_work kernel/include/linux/task_work.h:21
+ [<ffffffff81307105>] do_exit+0x8b5/0x2c60 kernel/kernel/exit.c:750
+ [<ffffffff813fdd20>] ? debug_check_no_locks_freed+0x290/0x290 kernel/kernel/locking/lockdep.c:4123
+ [<ffffffff81306850>] ? mm_update_next_owner+0x6f0/0x6f0 kernel/kernel/exit.c:357
+ [<ffffffff813215e6>] ? __dequeue_signal+0x136/0x470 kernel/kernel/signal.c:550
+ [<ffffffff8132067b>] ? recalc_sigpending_tsk+0x13b/0x180 kernel/kernel/signal.c:145
+ [<ffffffff81309628>] do_group_exit+0x108/0x330 kernel/kernel/exit.c:880
+ [<ffffffff8132b9d4>] get_signal+0x5e4/0x14f0 kernel/kernel/signal.c:2307
+ [<     inline     >] ? kretprobe_table_lock kernel/kernel/kprobes.c:1113
+ [<ffffffff8151d355>] ? kprobe_flush_task+0xb5/0x450 kernel/kernel/kprobes.c:1158
+ [<ffffffff8115f7d3>] do_signal+0x83/0x1c90 kernel/arch/x86/kernel/signal.c:712
+ [<ffffffff8151d2a0>] ? recycle_rp_inst+0x310/0x310 kernel/include/linux/list.h:655
+ [<ffffffff8115f750>] ? setup_sigcontext+0x780/0x780 kernel/arch/x86/kernel/signal.c:165
+ [<ffffffff81380864>] ? finish_task_switch+0x424/0x5f0 kernel/kernel/sched/core.c:2692
+ [<     inline     >] ? finish_lock_switch kernel/kernel/sched/sched.h:1099
+ [<ffffffff81380560>] ? finish_task_switch+0x120/0x5f0 kernel/kernel/sched/core.c:2678
+ [<     inline     >] ? context_switch kernel/kernel/sched/core.c:2807
+ [<ffffffff85d794e9>] ? __schedule+0x919/0x1bd0 kernel/kernel/sched/core.c:3283
+ [<ffffffff81003901>] exit_to_usermode_loop+0xf1/0x1a0 kernel/arch/x86/entry/common.c:247
+ [<     inline     >] prepare_exit_to_usermode kernel/arch/x86/entry/common.c:282
+ [<ffffffff810062ef>] syscall_return_slowpath+0x19f/0x210 kernel/arch/x86/entry/common.c:344
+ [<ffffffff85d88022>] int_ret_from_sys_call+0x25/0x9f kernel/arch/x86/entry/entry_64.S:281
+Memory state around the buggy address:
+ ffff880064e21680: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+ ffff880064e21700: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+>ffff880064e21780: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+                                                       ^
+ ffff880064e21800: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+ ffff880064e21880: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+==================================================================
+
+Fixes: 273ec51dd7ce ("net: ppp_generic - introduce net-namespace functionality v2")
+Reported-by: Baozeng Ding <sploving1@gmail.com>
+Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
+Reviewed-by: Cyrill Gorcunov <gorcunov@openvz.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ppp/ppp_generic.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ppp/ppp_generic.c
++++ b/drivers/net/ppp/ppp_generic.c
+@@ -2293,7 +2293,7 @@ int ppp_register_net_channel(struct net
+       pch->ppp = NULL;
+       pch->chan = chan;
+-      pch->chan_net = net;
++      pch->chan_net = get_net(net);
+       chan->ppp = pch;
+       init_ppp_file(&pch->file, CHANNEL);
+       pch->file.hdrlen = chan->hdrlen;
+@@ -2390,6 +2390,8 @@ ppp_unregister_channel(struct ppp_channe
+       spin_lock_bh(&pn->all_channels_lock);
+       list_del(&pch->list);
+       spin_unlock_bh(&pn->all_channels_lock);
++      put_net(pch->chan_net);
++      pch->chan_net = NULL;
+       pch->file.dead = 1;
+       wake_up_interruptible(&pch->file.rwait);
diff --git a/queue-4.4/qlcnic-fix-mailbox-completion-handling-during-spurious-interrupt.patch b/queue-4.4/qlcnic-fix-mailbox-completion-handling-during-spurious-interrupt.patch
new file mode 100644 (file)
index 0000000..82a1954
--- /dev/null
@@ -0,0 +1,96 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Rajesh Borundia <rajesh.borundia@qlogic.com>
+Date: Tue, 8 Mar 2016 02:39:58 -0500
+Subject: qlcnic: Fix mailbox completion handling during spurious interrupt
+
+From: Rajesh Borundia <rajesh.borundia@qlogic.com>
+
+[ Upstream commit 819bfe764dceec2f6b4551768453f374b4c60443 ]
+
+o While the driver is in the middle of a MB completion processing
+and it receives a spurious MB interrupt, it is mistaken as a good MB
+completion interrupt leading to premature completion of the next MB
+request. Fix the driver to guard against this by checking the current
+state of MB processing and ignore the spurious interrupt.
+Also added a stats counter to record this condition.
+
+Signed-off-by: Rajesh Borundia <rajesh.borundia@qlogic.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/qlogic/qlcnic/qlcnic.h         |    1 +
+ drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c |   15 +++++++++++----
+ drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c |    3 ++-
+ 3 files changed, 14 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+@@ -566,6 +566,7 @@ struct qlcnic_adapter_stats {
+       u64  tx_dma_map_error;
+       u64  spurious_intr;
+       u64  mac_filter_limit_overrun;
++      u64  mbx_spurious_intr;
+ };
+ /*
+--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+@@ -2338,9 +2338,9 @@ static void qlcnic_83xx_handle_link_aen(
+ static irqreturn_t qlcnic_83xx_handle_aen(int irq, void *data)
+ {
++      u32 mask, resp, event, rsp_status = QLC_83XX_MBX_RESPONSE_ARRIVED;
+       struct qlcnic_adapter *adapter = data;
+       struct qlcnic_mailbox *mbx;
+-      u32 mask, resp, event;
+       unsigned long flags;
+       mbx = adapter->ahw->mailbox;
+@@ -2350,10 +2350,14 @@ static irqreturn_t qlcnic_83xx_handle_ae
+               goto out;
+       event = readl(QLCNIC_MBX_FW(adapter->ahw, 0));
+-      if (event &  QLCNIC_MBX_ASYNC_EVENT)
++      if (event &  QLCNIC_MBX_ASYNC_EVENT) {
+               __qlcnic_83xx_process_aen(adapter);
+-      else
+-              qlcnic_83xx_notify_mbx_response(mbx);
++      } else {
++              if (mbx->rsp_status != rsp_status)
++                      qlcnic_83xx_notify_mbx_response(mbx);
++              else
++                      adapter->stats.mbx_spurious_intr++;
++      }
+ out:
+       mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
+@@ -4053,6 +4057,7 @@ static void qlcnic_83xx_mailbox_worker(s
+       struct list_head *head = &mbx->cmd_q;
+       struct qlcnic_hardware_context *ahw;
+       struct qlcnic_cmd_args *cmd = NULL;
++      unsigned long flags;
+       ahw = adapter->ahw;
+@@ -4062,7 +4067,9 @@ static void qlcnic_83xx_mailbox_worker(s
+                       return;
+               }
++              spin_lock_irqsave(&mbx->aen_lock, flags);
+               mbx->rsp_status = QLC_83XX_MBX_RESPONSE_WAIT;
++              spin_unlock_irqrestore(&mbx->aen_lock, flags);
+               spin_lock(&mbx->queue_lock);
+--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
+@@ -59,7 +59,8 @@ static const struct qlcnic_stats qlcnic_
+        QLC_OFF(stats.mac_filter_limit_overrun)},
+       {"spurious intr", QLC_SIZEOF(stats.spurious_intr),
+        QLC_OFF(stats.spurious_intr)},
+-
++      {"mbx spurious intr", QLC_SIZEOF(stats.mbx_spurious_intr),
++       QLC_OFF(stats.mbx_spurious_intr)},
+ };
+ static const char qlcnic_device_gstrings_stats[][ETH_GSTRING_LEN] = {
diff --git a/queue-4.4/qlcnic-remove-unnecessary-usage-of-atomic_t.patch b/queue-4.4/qlcnic-remove-unnecessary-usage-of-atomic_t.patch
new file mode 100644 (file)
index 0000000..01c5bb6
--- /dev/null
@@ -0,0 +1,77 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Rajesh Borundia <rajesh.borundia@qlogic.com>
+Date: Tue, 8 Mar 2016 02:39:57 -0500
+Subject: qlcnic: Remove unnecessary usage of atomic_t
+
+From: Rajesh Borundia <rajesh.borundia@qlogic.com>
+
+[ Upstream commit 5bf93251cee1fb66141d1d2eaff86e04a9397bdf ]
+
+o atomic_t usage is incorrect as we are not implementing
+any atomicity.
+
+Signed-off-by: Rajesh Borundia <rajesh.borundia@qlogic.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/qlogic/qlcnic/qlcnic.h         |    2 +-
+ drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c |    9 ++++-----
+ 2 files changed, 5 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+@@ -1099,7 +1099,7 @@ struct qlcnic_mailbox {
+       unsigned long           status;
+       spinlock_t              queue_lock;     /* Mailbox queue lock */
+       spinlock_t              aen_lock;       /* Mailbox response/AEN lock */
+-      atomic_t                rsp_status;
++      u32                     rsp_status;
+       u32                     num_cmds;
+ };
+--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+@@ -491,7 +491,7 @@ irqreturn_t qlcnic_83xx_clear_legacy_int
+ static inline void qlcnic_83xx_notify_mbx_response(struct qlcnic_mailbox *mbx)
+ {
+-      atomic_set(&mbx->rsp_status, QLC_83XX_MBX_RESPONSE_ARRIVED);
++      mbx->rsp_status = QLC_83XX_MBX_RESPONSE_ARRIVED;
+       complete(&mbx->completion);
+ }
+@@ -510,7 +510,7 @@ static void qlcnic_83xx_poll_process_aen
+       if (event &  QLCNIC_MBX_ASYNC_EVENT) {
+               __qlcnic_83xx_process_aen(adapter);
+       } else {
+-              if (atomic_read(&mbx->rsp_status) != rsp_status)
++              if (mbx->rsp_status != rsp_status)
+                       qlcnic_83xx_notify_mbx_response(mbx);
+       }
+ out:
+@@ -1023,7 +1023,7 @@ static void qlcnic_83xx_process_aen(stru
+               if (event &  QLCNIC_MBX_ASYNC_EVENT) {
+                       __qlcnic_83xx_process_aen(adapter);
+               } else {
+-                      if (atomic_read(&mbx->rsp_status) != rsp_status)
++                      if (mbx->rsp_status != rsp_status)
+                               qlcnic_83xx_notify_mbx_response(mbx);
+               }
+       }
+@@ -4050,7 +4050,6 @@ static void qlcnic_83xx_mailbox_worker(s
+       struct qlcnic_adapter *adapter = mbx->adapter;
+       const struct qlcnic_mbx_ops *mbx_ops = mbx->ops;
+       struct device *dev = &adapter->pdev->dev;
+-      atomic_t *rsp_status = &mbx->rsp_status;
+       struct list_head *head = &mbx->cmd_q;
+       struct qlcnic_hardware_context *ahw;
+       struct qlcnic_cmd_args *cmd = NULL;
+@@ -4063,7 +4062,7 @@ static void qlcnic_83xx_mailbox_worker(s
+                       return;
+               }
+-              atomic_set(rsp_status, QLC_83XX_MBX_RESPONSE_WAIT);
++              mbx->rsp_status = QLC_83XX_MBX_RESPONSE_WAIT;
+               spin_lock(&mbx->queue_lock);
diff --git a/queue-4.4/qlge-fix-receive-packets-drop.patch b/queue-4.4/qlge-fix-receive-packets-drop.patch
new file mode 100644 (file)
index 0000000..ca69192
--- /dev/null
@@ -0,0 +1,43 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Manish Chopra <manish.chopra@qlogic.com>
+Date: Tue, 15 Mar 2016 07:13:45 -0400
+Subject: qlge: Fix receive packets drop.
+
+From: Manish Chopra <manish.chopra@qlogic.com>
+
+[ Upstream commit 2c9a266afefe137bff06bbe0fc48b4d3b3cb348c ]
+
+When running small packets [length < 256 bytes] traffic, packets were
+being dropped due to invalid data in those packets which were
+delivered by the driver upto the stack. Using pci_dma_sync_single_for_cpu
+ensures copying latest and updated data into skb from the receive buffer.
+
+Signed-off-by: Sony Chacko <sony.chacko@qlogic.com>
+Signed-off-by: Manish Chopra <manish.chopra@qlogic.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/qlogic/qlge/qlge_main.c |   11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c
++++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c
+@@ -1648,7 +1648,18 @@ static void ql_process_mac_rx_skb(struct
+               return;
+       }
+       skb_reserve(new_skb, NET_IP_ALIGN);
++
++      pci_dma_sync_single_for_cpu(qdev->pdev,
++                                  dma_unmap_addr(sbq_desc, mapaddr),
++                                  dma_unmap_len(sbq_desc, maplen),
++                                  PCI_DMA_FROMDEVICE);
++
+       memcpy(skb_put(new_skb, length), skb->data, length);
++
++      pci_dma_sync_single_for_device(qdev->pdev,
++                                     dma_unmap_addr(sbq_desc, mapaddr),
++                                     dma_unmap_len(sbq_desc, maplen),
++                                     PCI_DMA_FROMDEVICE);
+       skb = new_skb;
+       /* Frame error, so drop the packet. */
diff --git a/queue-4.4/qmi_wwan-add-d-link-dwm-221-b1-device-id.patch b/queue-4.4/qmi_wwan-add-d-link-dwm-221-b1-device-id.patch
new file mode 100644 (file)
index 0000000..0ca72e1
--- /dev/null
@@ -0,0 +1,55 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bjorn@mork.no>
+Date: Mon, 28 Mar 2016 22:38:16 +0200
+Subject: qmi_wwan: add "D-Link DWM-221 B1" device id
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bjorn@mork.no>
+
+[ Upstream commit e84810c7b85a2d7897797b3ad3e879168a8e032a ]
+
+Thomas reports:
+"Windows:
+
+00 diagnostics
+01 modem
+02 at-port
+03 nmea
+04 nic
+
+Linux:
+
+T:  Bus=02 Lev=01 Prnt=01 Port=03 Cnt=01 Dev#=  4 Spd=480 MxCh= 0
+D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
+P:  Vendor=2001 ProdID=7e19 Rev=02.32
+S:  Manufacturer=Mobile Connect
+S:  Product=Mobile Connect
+S:  SerialNumber=0123456789ABCDEF
+C:  #Ifs= 6 Cfg#= 1 Atr=a0 MxPwr=500mA
+I:  If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
+I:  If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
+I:  If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
+I:  If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
+I:  If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan
+I:  If#= 5 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage"
+
+Reported-by: Thomas Schäfer <tschaefer@t-online.de>
+Signed-off-by: Bjørn Mork <bjorn@mork.no>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/usb/qmi_wwan.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/usb/qmi_wwan.c
++++ b/drivers/net/usb/qmi_wwan.c
+@@ -699,6 +699,7 @@ static const struct usb_device_id produc
+       {QMI_FIXED_INTF(0x19d2, 0x1426, 2)},    /* ZTE MF91 */
+       {QMI_FIXED_INTF(0x19d2, 0x1428, 2)},    /* Telewell TW-LTE 4G v2 */
+       {QMI_FIXED_INTF(0x19d2, 0x2002, 4)},    /* ZTE (Vodafone) K3765-Z */
++      {QMI_FIXED_INTF(0x2001, 0x7e19, 4)},    /* D-Link DWM-221 B1 */
+       {QMI_FIXED_INTF(0x0f3d, 0x68a2, 8)},    /* Sierra Wireless MC7700 */
+       {QMI_FIXED_INTF(0x114f, 0x68a2, 8)},    /* Sierra Wireless MC7750 */
+       {QMI_FIXED_INTF(0x1199, 0x68a2, 8)},    /* Sierra Wireless MC7710 in QMI mode */
diff --git a/queue-4.4/qmi_wwan-add-sierra-wireless-em74xx-device-id.patch b/queue-4.4/qmi_wwan-add-sierra-wireless-em74xx-device-id.patch
new file mode 100644 (file)
index 0000000..e553053
--- /dev/null
@@ -0,0 +1,37 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bjorn@mork.no>
+Date: Tue, 1 Mar 2016 14:31:02 +0100
+Subject: qmi_wwan: add Sierra Wireless EM74xx device ID
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bjorn@mork.no>
+
+[ Upstream commit bf13c94ccb33c3182efc92ce4989506a0f541243 ]
+
+The MC74xx and EM74xx modules use different IDs by default, according
+to the Lenovo EM7455 driver for Windows.
+
+Signed-off-by: Bjørn Mork <bjorn@mork.no>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/usb/qmi_wwan.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/usb/qmi_wwan.c
++++ b/drivers/net/usb/qmi_wwan.c
+@@ -718,8 +718,10 @@ static const struct usb_device_id produc
+       {QMI_FIXED_INTF(0x1199, 0x9061, 8)},    /* Sierra Wireless Modem */
+       {QMI_FIXED_INTF(0x1199, 0x9070, 8)},    /* Sierra Wireless MC74xx/EM74xx */
+       {QMI_FIXED_INTF(0x1199, 0x9070, 10)},   /* Sierra Wireless MC74xx/EM74xx */
+-      {QMI_FIXED_INTF(0x1199, 0x9071, 8)},    /* Sierra Wireless MC74xx/EM74xx */
+-      {QMI_FIXED_INTF(0x1199, 0x9071, 10)},   /* Sierra Wireless MC74xx/EM74xx */
++      {QMI_FIXED_INTF(0x1199, 0x9071, 8)},    /* Sierra Wireless MC74xx */
++      {QMI_FIXED_INTF(0x1199, 0x9071, 10)},   /* Sierra Wireless MC74xx */
++      {QMI_FIXED_INTF(0x1199, 0x9079, 8)},    /* Sierra Wireless EM74xx */
++      {QMI_FIXED_INTF(0x1199, 0x9079, 10)},   /* Sierra Wireless EM74xx */
+       {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)},    /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */
+       {QMI_FIXED_INTF(0x1bbb, 0x0203, 2)},    /* Alcatel L800MA */
+       {QMI_FIXED_INTF(0x2357, 0x0201, 4)},    /* TP-LINK HSUPA Modem MA180 */
diff --git a/queue-4.4/rocker-set-fdb-cleanup-timer-according-to-lowest-ageing-time.patch b/queue-4.4/rocker-set-fdb-cleanup-timer-according-to-lowest-ageing-time.patch
new file mode 100644 (file)
index 0000000..a1e5193
--- /dev/null
@@ -0,0 +1,70 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Ido Schimmel <idosch@mellanox.com>
+Date: Tue, 8 Mar 2016 12:59:34 -0800
+Subject: rocker: set FDB cleanup timer according to lowest ageing time
+
+From: Ido Schimmel <idosch@mellanox.com>
+
+[ Upstream commit 88de1cd457e5cb664d6d437e2ea4750d089165f5 ]
+
+In rocker, ageing time is a per-port attribute, so the next time the FDB
+cleanup timer fires should be set according to the lowest ageing time.
+
+This will later allow us to delete the BR_MIN_AGEING_TIME macro, which was
+added to guarantee minimum ageing time in the bridge layer, thereby breaking
+existing behavior.
+
+Signed-off-by: Ido Schimmel <idosch@mellanox.com>
+Acked-by: Jiri Pirko <jiri@mellanox.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/rocker/rocker.c |   10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/rocker/rocker.c
++++ b/drivers/net/ethernet/rocker/rocker.c
+@@ -239,6 +239,7 @@ struct rocker {
+       struct {
+               u64 id;
+       } hw;
++      unsigned long ageing_time;
+       spinlock_t cmd_ring_lock;               /* for cmd ring accesses */
+       struct rocker_dma_ring_info cmd_ring;
+       struct rocker_dma_ring_info event_ring;
+@@ -3704,7 +3705,7 @@ static void rocker_fdb_cleanup(unsigned
+       struct rocker_port *rocker_port;
+       struct rocker_fdb_tbl_entry *entry;
+       struct hlist_node *tmp;
+-      unsigned long next_timer = jiffies + BR_MIN_AGEING_TIME;
++      unsigned long next_timer = jiffies + rocker->ageing_time;
+       unsigned long expires;
+       unsigned long lock_flags;
+       int flags = ROCKER_OP_FLAG_NOWAIT | ROCKER_OP_FLAG_REMOVE |
+@@ -4367,8 +4368,12 @@ static int rocker_port_bridge_ageing_tim
+                                         struct switchdev_trans *trans,
+                                         u32 ageing_time)
+ {
++      struct rocker *rocker = rocker_port->rocker;
++
+       if (!switchdev_trans_ph_prepare(trans)) {
+               rocker_port->ageing_time = clock_t_to_jiffies(ageing_time);
++              if (rocker_port->ageing_time < rocker->ageing_time)
++                      rocker->ageing_time = rocker_port->ageing_time;
+               mod_timer(&rocker_port->rocker->fdb_cleanup_timer, jiffies);
+       }
+@@ -5206,10 +5211,13 @@ static int rocker_probe(struct pci_dev *
+               goto err_init_tbls;
+       }
++      rocker->ageing_time = BR_DEFAULT_AGEING_TIME;
+       setup_timer(&rocker->fdb_cleanup_timer, rocker_fdb_cleanup,
+                   (unsigned long) rocker);
+       mod_timer(&rocker->fdb_cleanup_timer, jiffies);
++      rocker->ageing_time = BR_DEFAULT_AGEING_TIME;
++
+       err = rocker_probe_ports(rocker);
+       if (err) {
+               dev_err(&pdev->dev, "failed to probe ports\n");
diff --git a/queue-4.4/rtnl-fix-msg-size-calculation-in-if_nlmsg_size.patch b/queue-4.4/rtnl-fix-msg-size-calculation-in-if_nlmsg_size.patch
new file mode 100644 (file)
index 0000000..3f5d344
--- /dev/null
@@ -0,0 +1,31 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Date: Thu, 31 Mar 2016 18:10:31 +0200
+Subject: rtnl: fix msg size calculation in if_nlmsg_size()
+
+From: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+
+[ Upstream commit c57c7a95da842807b475b823ed2e5435c42cb3b0 ]
+
+Size of the attribute IFLA_PHYS_PORT_NAME was missing.
+
+Fixes: db24a9044ee1 ("net: add support for phys_port_name")
+CC: David Ahern <dsahern@gmail.com>
+Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Acked-by: David Ahern <dsahern@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/core/rtnetlink.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/core/rtnetlink.c
++++ b/net/core/rtnetlink.c
+@@ -905,6 +905,7 @@ static noinline size_t if_nlmsg_size(con
+              + rtnl_link_get_af_size(dev, ext_filter_mask) /* IFLA_AF_SPEC */
+              + nla_total_size(MAX_PHYS_ITEM_ID_LEN) /* IFLA_PHYS_PORT_ID */
+              + nla_total_size(MAX_PHYS_ITEM_ID_LEN) /* IFLA_PHYS_SWITCH_ID */
++             + nla_total_size(IFNAMSIZ) /* IFLA_PHYS_PORT_NAME */
+              + nla_total_size(1); /* IFLA_PROTO_DOWN */
+ }
diff --git a/queue-4.4/sctp-lack-the-check-for-ports-in-sctp_v6_cmp_addr.patch b/queue-4.4/sctp-lack-the-check-for-ports-in-sctp_v6_cmp_addr.patch
new file mode 100644 (file)
index 0000000..798b489
--- /dev/null
@@ -0,0 +1,37 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Xin Long <lucien.xin@gmail.com>
+Date: Sun, 28 Feb 2016 10:03:51 +0800
+Subject: sctp: lack the check for ports in sctp_v6_cmp_addr
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ Upstream commit 40b4f0fd74e46c017814618d67ec9127ff20f157 ]
+
+As the member .cmp_addr of sctp_af_inet6, sctp_v6_cmp_addr should also check
+the port of addresses, just like sctp_v4_cmp_addr, cause it's invoked by
+sctp_cmp_addr_exact().
+
+Now sctp_v6_cmp_addr just check the port when two addresses have different
+family, and lack the port check for two ipv6 addresses. that will make
+sctp_hash_cmp() cannot work well.
+
+so fix it by adding ports comparison in sctp_v6_cmp_addr().
+
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sctp/ipv6.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/net/sctp/ipv6.c
++++ b/net/sctp/ipv6.c
+@@ -526,6 +526,8 @@ static int sctp_v6_cmp_addr(const union
+               }
+               return 0;
+       }
++      if (addr1->v6.sin6_port != addr2->v6.sin6_port)
++              return 0;
+       if (!ipv6_addr_equal(&addr1->v6.sin6_addr, &addr2->v6.sin6_addr))
+               return 0;
+       /* If this is a linklocal address, compare the scope_id. */
index 79c94cf550bac4b5298c428060df210e52e79d57..edc553188c7b92a5bf924365f29dd2ed964fe2d3 100644 (file)
@@ -21,3 +21,59 @@ drm-radeon-add-a-dpm-quirk-for-all-r7-370-parts.patch
 drm-amdgpu-gmc-move-vram-type-fetching-into-sw_init.patch
 drm-amdgpu-gmc-use-proper-register-for-vram-type-on-fiji.patch
 xen-events-mask-a-moving-irq.patch
+tcp-convert-cached-rtt-from-usec-to-jiffies-when-feeding-initial-rto.patch
+tunnel-clear-ipcb-skb-opt-before-dst_link_failure-called.patch
+ipv4-only-create-late-gso-skb-if-skb-is-already-set-up-with-checksum_partial.patch
+net-jme-fix-suspend-resume-on-jmc260.patch
+net-vrf-remove-direct-access-to-skb-data.patch
+net-qca_spi-don-t-clear-iff_broadcast.patch
+net-qca_spi-clear-iff_tx_skb_sharing.patch
+net-fix-bridge-multicast-packet-checksum-validation.patch
+sctp-lack-the-check-for-ports-in-sctp_v6_cmp_addr.patch
+mld-igmp-fix-reserved-tailroom-calculation.patch
+tipc-revert-tipc-use-existing-sk_write_queue-for-outgoing-packet-chain.patch
+qmi_wwan-add-sierra-wireless-em74xx-device-id.patch
+ipv6-re-enable-fragment-header-matching-in-ipv6_find_hdr.patch
+vxlan-fix-missing-options_len-update-on-rx-with-collect-metadata.patch
+cdc_ncm-toggle-altsetting-to-force-reset-before-setup.patch
+usbnet-cleanup-after-bind-in-probe.patch
+udp6-fix-udp-ipv6-encap-resubmit-path.patch
+tcp-fix-tcpi_segs_in-after-connection-establishment.patch
+ppp-release-rtnl-mutex-when-interface-creation-fails.patch
+net-validate-variable-length-ll-headers.patch
+ax25-add-link-layer-header-validation-function.patch
+packet-validate-variable-length-ll-headers.patch
+bpf-avoid-copying-junk-bytes-in-bpf_get_current_comm.patch
+sh_eth-fix-null-pointer-dereference-in-sh_eth_ring_format.patch
+sh_eth-advance-rxdesc-later-in-sh_eth_ring_format.patch
+qlcnic-remove-unnecessary-usage-of-atomic_t.patch
+qlcnic-fix-mailbox-completion-handling-during-spurious-interrupt.patch
+macvtap-always-pass-ethernet-header-in-linear.patch
+mlxsw-spectrum-check-requested-ageing-time-is-valid.patch
+rocker-set-fdb-cleanup-timer-according-to-lowest-ageing-time.patch
+bridge-allow-zero-ageing-time.patch
+ipv4-don-t-do-expensive-useless-work-during-inetdev-destroy.patch
+net-fix-use-after-free-in-the-recvmmsg-exit-path.patch
+mlx4-add-missing-braces-in-verify_qp_parameters.patch
+farsync-fix-off-by-one-bug-in-fst_add_one.patch
+ath9k-fix-buffer-overrun-for-ar9287.patch
+ppp-ensure-file-private_data-can-t-be-overridden.patch
+tcp-dccp-remove-obsolete-warn_on-in-icmp-handlers.patch
+qlge-fix-receive-packets-drop.patch
+net-bcmgenet-fix-dma-api-length-mismatch.patch
+bonding-fix-bond_get_stats.patch
+ipv4-fix-broadcast-packets-reception.patch
+ipv4-initialize-flowi4_flags-before-calling-fib_lookup.patch
+ppp-take-reference-on-channels-netns.patch
+xfrm-fix-crash-observed-during-device-unregistration-and-decryption.patch
+qmi_wwan-add-d-link-dwm-221-b1-device-id.patch
+ipv6-udp-fix-udp_mib_ignoredmulti-updates.patch
+bridge-allow-set-bridge-ageing-time-when-switchdev-disabled.patch
+rtnl-fix-msg-size-calculation-in-if_nlmsg_size.patch
+tun-bpf-fix-suspicious-rcu-usage-in-tun_-attach-detach-_filter.patch
+tuntap-restore-default-qdisc.patch
+ipv4-l2tp-fix-a-potential-issue-in-l2tp_ip_recv.patch
+ipv6-l2tp-fix-a-potential-issue-in-l2tp_ip6_recv.patch
+ip6_tunnel-set-rtnl_link_ops-before-calling-register_netdevice.patch
+ipv6-count-in-extension-headers-in-skb-network_header.patch
+mpls-find_outdev-check-for-err-ptr-in-addition-to-null-check.patch
diff --git a/queue-4.4/sh_eth-advance-rxdesc-later-in-sh_eth_ring_format.patch b/queue-4.4/sh_eth-advance-rxdesc-later-in-sh_eth_ring_format.patch
new file mode 100644 (file)
index 0000000..0428f81
--- /dev/null
@@ -0,0 +1,46 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Tue, 8 Mar 2016 01:37:09 +0300
+Subject: sh_eth: advance 'rxdesc' later in sh_eth_ring_format()
+
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+
+[ Upstream commit d0ba913488dc8c55d1880f5ed34f096dc45fb05d ]
+
+Iff dma_map_single() fails, 'rxdesc'  should point  to the last filled RX
+descriptor, so  that it can be marked as the last one, however the driver
+would have  already  advanced it by that time. In order to fix that, only
+fill  an RX descriptor  once all the data for it is ready.
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/renesas/sh_eth.c |    7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/ethernet/renesas/sh_eth.c
++++ b/drivers/net/ethernet/renesas/sh_eth.c
+@@ -1185,11 +1185,8 @@ static void sh_eth_ring_format(struct ne
+                       break;
+               sh_eth_set_receive_align(skb);
+-              /* RX descriptor */
+-              rxdesc = &mdp->rx_ring[i];
+               /* The size of the buffer is a multiple of 32 bytes. */
+               buf_len = ALIGN(mdp->rx_buf_sz, 32);
+-              rxdesc->len = cpu_to_edmac(mdp, buf_len << 16);
+               dma_addr = dma_map_single(&ndev->dev, skb->data, buf_len,
+                                         DMA_FROM_DEVICE);
+               if (dma_mapping_error(&ndev->dev, dma_addr)) {
+@@ -1197,6 +1194,10 @@ static void sh_eth_ring_format(struct ne
+                       break;
+               }
+               mdp->rx_skbuff[i] = skb;
++
++              /* RX descriptor */
++              rxdesc = &mdp->rx_ring[i];
++              rxdesc->len = cpu_to_edmac(mdp, buf_len << 16);
+               rxdesc->addr = cpu_to_edmac(mdp, dma_addr);
+               rxdesc->status = cpu_to_edmac(mdp, RD_RACT | RD_RFP);
diff --git a/queue-4.4/sh_eth-fix-null-pointer-dereference-in-sh_eth_ring_format.patch b/queue-4.4/sh_eth-fix-null-pointer-dereference-in-sh_eth_ring_format.patch
new file mode 100644 (file)
index 0000000..464a6bc
--- /dev/null
@@ -0,0 +1,33 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Tue, 8 Mar 2016 01:36:28 +0300
+Subject: sh_eth: fix NULL pointer dereference in sh_eth_ring_format()
+
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+
+[ Upstream commit c1b7fca65070bfadca94dd53a4e6b71cd4f69715 ]
+
+In a low memory situation, if netdev_alloc_skb() fails on a first RX ring
+loop iteration  in sh_eth_ring_format(), 'rxdesc' is still NULL.  Avoid
+kernel oops by adding the 'rxdesc' check after the loop.
+
+Reported-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/renesas/sh_eth.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/renesas/sh_eth.c
++++ b/drivers/net/ethernet/renesas/sh_eth.c
+@@ -1212,7 +1212,8 @@ static void sh_eth_ring_format(struct ne
+       mdp->dirty_rx = (u32) (i - mdp->num_rx_ring);
+       /* Mark the last entry as wrapping the ring. */
+-      rxdesc->status |= cpu_to_edmac(mdp, RD_RDLE);
++      if (rxdesc)
++              rxdesc->status |= cpu_to_edmac(mdp, RD_RDLE);
+       memset(mdp->tx_ring, 0, tx_ringsize);
diff --git a/queue-4.4/tcp-convert-cached-rtt-from-usec-to-jiffies-when-feeding-initial-rto.patch b/queue-4.4/tcp-convert-cached-rtt-from-usec-to-jiffies-when-feeding-initial-rto.patch
new file mode 100644 (file)
index 0000000..94b6849
--- /dev/null
@@ -0,0 +1,30 @@
+From foo@baz Sat Apr 16 10:02:52 PDT 2016
+From: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
+Date: Sun, 21 Feb 2016 10:12:39 +0300
+Subject: tcp: convert cached rtt from usec to jiffies when feeding initial rto
+
+From: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
+
+[ Upstream commit 9bdfb3b79e61c60e1a3e2dc05ad164528afa6b8a ]
+
+Currently it's converted into msecs, thus HZ=1000 intact.
+
+Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
+Fixes: 740b0f1841f6 ("tcp: switch rtt estimations to usec resolution")
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/tcp_metrics.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/ipv4/tcp_metrics.c
++++ b/net/ipv4/tcp_metrics.c
+@@ -550,7 +550,7 @@ reset:
+        */
+       if (crtt > tp->srtt_us) {
+               /* Set RTO like tcp_rtt_estimator(), but from cached RTT. */
+-              crtt /= 8 * USEC_PER_MSEC;
++              crtt /= 8 * USEC_PER_SEC / HZ;
+               inet_csk(sk)->icsk_rto = crtt + max(2 * crtt, tcp_rto_min(sk));
+       } else if (tp->srtt_us == 0) {
+               /* RFC6298: 5.7 We've failed to get a valid RTT sample from
diff --git a/queue-4.4/tcp-dccp-remove-obsolete-warn_on-in-icmp-handlers.patch b/queue-4.4/tcp-dccp-remove-obsolete-warn_on-in-icmp-handlers.patch
new file mode 100644 (file)
index 0000000..72f821c
--- /dev/null
@@ -0,0 +1,52 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Eric Dumazet <edumazet@google.com>
+Date: Wed, 16 Mar 2016 22:52:15 -0700
+Subject: tcp/dccp: remove obsolete WARN_ON() in icmp handlers
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit e316ea62e3203d524ff0239a40c56d3a39ad1b5c ]
+
+Now SYN_RECV request sockets are installed in ehash table, an ICMP
+handler can find a request socket while another cpu handles an incoming
+packet transforming this SYN_RECV request socket into an ESTABLISHED
+socket.
+
+We need to remove the now obsolete WARN_ON(req->sk), since req->sk
+is set when a new child is created and added into listener accept queue.
+
+If this race happens, the ICMP will do nothing special.
+
+Fixes: 079096f103fa ("tcp/dccp: install syn_recv requests into ehash table")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: Ben Lazarus <blazarus@google.com>
+Reported-by: Neal Cardwell <ncardwell@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/dccp/ipv4.c     |    2 --
+ net/ipv4/tcp_ipv4.c |    2 --
+ 2 files changed, 4 deletions(-)
+
+--- a/net/dccp/ipv4.c
++++ b/net/dccp/ipv4.c
+@@ -204,8 +204,6 @@ void dccp_req_err(struct sock *sk, u64 s
+        * ICMPs are not backlogged, hence we cannot get an established
+        * socket here.
+        */
+-      WARN_ON(req->sk);
+-
+       if (!between48(seq, dccp_rsk(req)->dreq_iss, dccp_rsk(req)->dreq_gss)) {
+               NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS);
+       } else {
+--- a/net/ipv4/tcp_ipv4.c
++++ b/net/ipv4/tcp_ipv4.c
+@@ -320,8 +320,6 @@ void tcp_req_err(struct sock *sk, u32 se
+       /* ICMPs are not backlogged, hence we cannot get
+        * an established socket here.
+        */
+-      WARN_ON(req->sk);
+-
+       if (seq != tcp_rsk(req)->snt_isn) {
+               NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS);
+       } else if (abort) {
diff --git a/queue-4.4/tcp-fix-tcpi_segs_in-after-connection-establishment.patch b/queue-4.4/tcp-fix-tcpi_segs_in-after-connection-establishment.patch
new file mode 100644 (file)
index 0000000..ab8956f
--- /dev/null
@@ -0,0 +1,60 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Eric Dumazet <edumazet@google.com>
+Date: Sun, 6 Mar 2016 09:29:21 -0800
+Subject: tcp: fix tcpi_segs_in after connection establishment
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit a9d99ce28ed359d68cf6f3c1a69038aefedf6d6a ]
+
+If final packet (ACK) of 3WHS is lost, it appears we do not properly
+account the following incoming segment into tcpi_segs_in
+
+While we are at it, starts segs_in with one, to count the SYN packet.
+
+We do not yet count number of SYN we received for a request sock, we
+might add this someday.
+
+packetdrill script showing proper behavior after fix :
+
+// Tests tcpi_segs_in when 3rd packet (ACK) of 3WHS is lost
+0.000 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+   +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+   +0 bind(3, ..., ...) = 0
+   +0 listen(3, 1) = 0
+
+   +0 < S 0:0(0) win 32792 <mss 1000,sackOK,nop,nop>
+   +0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK>
++.020 < P. 1:1001(1000) ack 1 win 32792
+
+   +0 accept(3, ..., ...) = 4
+
++.000 %{ assert tcpi_segs_in == 2, 'tcpi_segs_in=%d' % tcpi_segs_in }%
+
+Fixes: 2efd055c53c06 ("tcp: add tcpi_segs_in and tcpi_segs_out to tcp_info")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/tcp_minisocks.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/ipv4/tcp_minisocks.c
++++ b/net/ipv4/tcp_minisocks.c
+@@ -458,7 +458,7 @@ struct sock *tcp_create_openreq_child(co
+               newtp->rcv_wup = newtp->copied_seq =
+               newtp->rcv_nxt = treq->rcv_isn + 1;
+-              newtp->segs_in = 0;
++              newtp->segs_in = 1;
+               newtp->snd_sml = newtp->snd_una =
+               newtp->snd_nxt = newtp->snd_up = treq->snt_isn + 1;
+@@ -818,6 +818,7 @@ int tcp_child_process(struct sock *paren
+       int ret = 0;
+       int state = child->sk_state;
++      tcp_sk(child)->segs_in += max_t(u16, 1, skb_shinfo(skb)->gso_segs);
+       if (!sock_owned_by_user(child)) {
+               ret = tcp_rcv_state_process(child, skb);
+               /* Wakeup parent, send SIGIO */
diff --git a/queue-4.4/tipc-revert-tipc-use-existing-sk_write_queue-for-outgoing-packet-chain.patch b/queue-4.4/tipc-revert-tipc-use-existing-sk_write_queue-for-outgoing-packet-chain.patch
new file mode 100644 (file)
index 0000000..970efdc
--- /dev/null
@@ -0,0 +1,206 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
+Date: Tue, 1 Mar 2016 11:07:09 +0100
+Subject: tipc: Revert "tipc: use existing sk_write_queue for outgoing packet chain"
+
+From: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
+
+[ Upstream commit f214fc402967e1bc94ad7f39faa03db5813d6849 ]
+
+reverts commit 94153e36e709e ("tipc: use existing sk_write_queue for
+outgoing packet chain")
+
+In Commit 94153e36e709e, we assume that we fill & empty the socket's
+sk_write_queue within the same lock_sock() session.
+
+This is not true if the link is congested. During congestion, the
+socket lock is released while we wait for the congestion to cease.
+This implementation causes a nullptr exception, if the user space
+program has several threads accessing the same socket descriptor.
+
+Consider two threads of the same program performing the following:
+     Thread1                                  Thread2
+--------------------                    ----------------------
+Enter tipc_sendmsg()                    Enter tipc_sendmsg()
+lock_sock()                             lock_sock()
+Enter tipc_link_xmit(), ret=ELINKCONG   spin on socket lock..
+sk_wait_event()                             :
+release_sock()                          grab socket lock
+    :                                   Enter tipc_link_xmit(), ret=0
+    :                                   release_sock()
+Wakeup after congestion
+lock_sock()
+skb = skb_peek(pktchain);
+!! TIPC_SKB_CB(skb)->wakeup_pending = tsk->link_cong;
+
+In this case, the second thread transmits the buffers belonging to
+both thread1 and thread2 successfully. When the first thread wakeup
+after the congestion it assumes that the pktchain is intact and
+operates on the skb's in it, which leads to the following exception:
+
+[2102.439969] BUG: unable to handle kernel NULL pointer dereference at 00000000000000d0
+[2102.440074] IP: [<ffffffffa005f330>] __tipc_link_xmit+0x2b0/0x4d0 [tipc]
+[2102.440074] PGD 3fa3f067 PUD 3fa6b067 PMD 0
+[2102.440074] Oops: 0000 [#1] SMP
+[2102.440074] CPU: 2 PID: 244 Comm: sender Not tainted 3.12.28 #1
+[2102.440074] RIP: 0010:[<ffffffffa005f330>]  [<ffffffffa005f330>] __tipc_link_xmit+0x2b0/0x4d0 [tipc]
+[...]
+[2102.440074] Call Trace:
+[2102.440074]  [<ffffffff8163f0b9>] ? schedule+0x29/0x70
+[2102.440074]  [<ffffffffa006a756>] ? tipc_node_unlock+0x46/0x170 [tipc]
+[2102.440074]  [<ffffffffa005f761>] tipc_link_xmit+0x51/0xf0 [tipc]
+[2102.440074]  [<ffffffffa006d8ae>] tipc_send_stream+0x11e/0x4f0 [tipc]
+[2102.440074]  [<ffffffff8106b150>] ? __wake_up_sync+0x20/0x20
+[2102.440074]  [<ffffffffa006dc9c>] tipc_send_packet+0x1c/0x20 [tipc]
+[2102.440074]  [<ffffffff81502478>] sock_sendmsg+0xa8/0xd0
+[2102.440074]  [<ffffffff81507895>] ? release_sock+0x145/0x170
+[2102.440074]  [<ffffffff815030d8>] ___sys_sendmsg+0x3d8/0x3e0
+[2102.440074]  [<ffffffff816426ae>] ? _raw_spin_unlock+0xe/0x10
+[2102.440074]  [<ffffffff81115c2a>] ? handle_mm_fault+0x6ca/0x9d0
+[2102.440074]  [<ffffffff8107dd65>] ? set_next_entity+0x85/0xa0
+[2102.440074]  [<ffffffff816426de>] ? _raw_spin_unlock_irq+0xe/0x20
+[2102.440074]  [<ffffffff8107463c>] ? finish_task_switch+0x5c/0xc0
+[2102.440074]  [<ffffffff8163ea8c>] ? __schedule+0x34c/0x950
+[2102.440074]  [<ffffffff81504e12>] __sys_sendmsg+0x42/0x80
+[2102.440074]  [<ffffffff81504e62>] SyS_sendmsg+0x12/0x20
+[2102.440074]  [<ffffffff8164aed2>] system_call_fastpath+0x16/0x1b
+
+In this commit, we maintain the skb list always in the stack.
+
+Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
+Acked-by: Ying Xue <ying.xue@windriver.com>
+Acked-by: Jon Maloy <jon.maloy@ericsson.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/tipc/socket.c |   33 +++++++++++++++++++--------------
+ 1 file changed, 19 insertions(+), 14 deletions(-)
+
+--- a/net/tipc/socket.c
++++ b/net/tipc/socket.c
+@@ -673,7 +673,7 @@ static int tipc_sendmcast(struct  socket
+       struct tipc_sock *tsk = tipc_sk(sk);
+       struct net *net = sock_net(sk);
+       struct tipc_msg *mhdr = &tsk->phdr;
+-      struct sk_buff_head *pktchain = &sk->sk_write_queue;
++      struct sk_buff_head pktchain;
+       struct iov_iter save = msg->msg_iter;
+       uint mtu;
+       int rc;
+@@ -687,14 +687,16 @@ static int tipc_sendmcast(struct  socket
+       msg_set_nameupper(mhdr, seq->upper);
+       msg_set_hdr_sz(mhdr, MCAST_H_SIZE);
++      skb_queue_head_init(&pktchain);
++
+ new_mtu:
+       mtu = tipc_bcast_get_mtu(net);
+-      rc = tipc_msg_build(mhdr, msg, 0, dsz, mtu, pktchain);
++      rc = tipc_msg_build(mhdr, msg, 0, dsz, mtu, &pktchain);
+       if (unlikely(rc < 0))
+               return rc;
+       do {
+-              rc = tipc_bcast_xmit(net, pktchain);
++              rc = tipc_bcast_xmit(net, &pktchain);
+               if (likely(!rc))
+                       return dsz;
+@@ -704,7 +706,7 @@ new_mtu:
+                       if (!rc)
+                               continue;
+               }
+-              __skb_queue_purge(pktchain);
++              __skb_queue_purge(&pktchain);
+               if (rc == -EMSGSIZE) {
+                       msg->msg_iter = save;
+                       goto new_mtu;
+@@ -863,7 +865,7 @@ static int __tipc_sendmsg(struct socket
+       struct net *net = sock_net(sk);
+       struct tipc_msg *mhdr = &tsk->phdr;
+       u32 dnode, dport;
+-      struct sk_buff_head *pktchain = &sk->sk_write_queue;
++      struct sk_buff_head pktchain;
+       struct sk_buff *skb;
+       struct tipc_name_seq *seq;
+       struct iov_iter save;
+@@ -924,17 +926,18 @@ static int __tipc_sendmsg(struct socket
+               msg_set_hdr_sz(mhdr, BASIC_H_SIZE);
+       }
++      skb_queue_head_init(&pktchain);
+       save = m->msg_iter;
+ new_mtu:
+       mtu = tipc_node_get_mtu(net, dnode, tsk->portid);
+-      rc = tipc_msg_build(mhdr, m, 0, dsz, mtu, pktchain);
++      rc = tipc_msg_build(mhdr, m, 0, dsz, mtu, &pktchain);
+       if (rc < 0)
+               return rc;
+       do {
+-              skb = skb_peek(pktchain);
++              skb = skb_peek(&pktchain);
+               TIPC_SKB_CB(skb)->wakeup_pending = tsk->link_cong;
+-              rc = tipc_node_xmit(net, pktchain, dnode, tsk->portid);
++              rc = tipc_node_xmit(net, &pktchain, dnode, tsk->portid);
+               if (likely(!rc)) {
+                       if (sock->state != SS_READY)
+                               sock->state = SS_CONNECTING;
+@@ -946,7 +949,7 @@ new_mtu:
+                       if (!rc)
+                               continue;
+               }
+-              __skb_queue_purge(pktchain);
++              __skb_queue_purge(&pktchain);
+               if (rc == -EMSGSIZE) {
+                       m->msg_iter = save;
+                       goto new_mtu;
+@@ -1016,7 +1019,7 @@ static int __tipc_send_stream(struct soc
+       struct net *net = sock_net(sk);
+       struct tipc_sock *tsk = tipc_sk(sk);
+       struct tipc_msg *mhdr = &tsk->phdr;
+-      struct sk_buff_head *pktchain = &sk->sk_write_queue;
++      struct sk_buff_head pktchain;
+       DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name);
+       u32 portid = tsk->portid;
+       int rc = -EINVAL;
+@@ -1044,17 +1047,19 @@ static int __tipc_send_stream(struct soc
+       timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT);
+       dnode = tsk_peer_node(tsk);
++      skb_queue_head_init(&pktchain);
+ next:
+       save = m->msg_iter;
+       mtu = tsk->max_pkt;
+       send = min_t(uint, dsz - sent, TIPC_MAX_USER_MSG_SIZE);
+-      rc = tipc_msg_build(mhdr, m, sent, send, mtu, pktchain);
++      rc = tipc_msg_build(mhdr, m, sent, send, mtu, &pktchain);
+       if (unlikely(rc < 0))
+               return rc;
++
+       do {
+               if (likely(!tsk_conn_cong(tsk))) {
+-                      rc = tipc_node_xmit(net, pktchain, dnode, portid);
++                      rc = tipc_node_xmit(net, &pktchain, dnode, portid);
+                       if (likely(!rc)) {
+                               tsk->sent_unacked++;
+                               sent += send;
+@@ -1063,7 +1068,7 @@ next:
+                               goto next;
+                       }
+                       if (rc == -EMSGSIZE) {
+-                              __skb_queue_purge(pktchain);
++                              __skb_queue_purge(&pktchain);
+                               tsk->max_pkt = tipc_node_get_mtu(net, dnode,
+                                                                portid);
+                               m->msg_iter = save;
+@@ -1077,7 +1082,7 @@ next:
+               rc = tipc_wait_for_sndpkt(sock, &timeo);
+       } while (!rc);
+-      __skb_queue_purge(pktchain);
++      __skb_queue_purge(&pktchain);
+       return sent ? sent : rc;
+ }
diff --git a/queue-4.4/tun-bpf-fix-suspicious-rcu-usage-in-tun_-attach-detach-_filter.patch b/queue-4.4/tun-bpf-fix-suspicious-rcu-usage-in-tun_-attach-detach-_filter.patch
new file mode 100644 (file)
index 0000000..df5cbd6
--- /dev/null
@@ -0,0 +1,207 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Daniel Borkmann <daniel@iogearbox.net>
+Date: Thu, 31 Mar 2016 02:13:18 +0200
+Subject: tun, bpf: fix suspicious RCU usage in tun_{attach, detach}_filter
+
+From: Daniel Borkmann <daniel@iogearbox.net>
+
+[ Upstream commit 5a5abb1fa3b05dd6aa821525832644c1e7d2905f ]
+
+Sasha Levin reported a suspicious rcu_dereference_protected() warning
+found while fuzzing with trinity that is similar to this one:
+
+  [   52.765684] net/core/filter.c:2262 suspicious rcu_dereference_protected() usage!
+  [   52.765688] other info that might help us debug this:
+  [   52.765695] rcu_scheduler_active = 1, debug_locks = 1
+  [   52.765701] 1 lock held by a.out/1525:
+  [   52.765704]  #0:  (rtnl_mutex){+.+.+.}, at: [<ffffffff816a64b7>] rtnl_lock+0x17/0x20
+  [   52.765721] stack backtrace:
+  [   52.765728] CPU: 1 PID: 1525 Comm: a.out Not tainted 4.5.0+ #264
+  [...]
+  [   52.765768] Call Trace:
+  [   52.765775]  [<ffffffff813e488d>] dump_stack+0x85/0xc8
+  [   52.765784]  [<ffffffff810f2fa5>] lockdep_rcu_suspicious+0xd5/0x110
+  [   52.765792]  [<ffffffff816afdc2>] sk_detach_filter+0x82/0x90
+  [   52.765801]  [<ffffffffa0883425>] tun_detach_filter+0x35/0x90 [tun]
+  [   52.765810]  [<ffffffffa0884ed4>] __tun_chr_ioctl+0x354/0x1130 [tun]
+  [   52.765818]  [<ffffffff8136fed0>] ? selinux_file_ioctl+0x130/0x210
+  [   52.765827]  [<ffffffffa0885ce3>] tun_chr_ioctl+0x13/0x20 [tun]
+  [   52.765834]  [<ffffffff81260ea6>] do_vfs_ioctl+0x96/0x690
+  [   52.765843]  [<ffffffff81364af3>] ? security_file_ioctl+0x43/0x60
+  [   52.765850]  [<ffffffff81261519>] SyS_ioctl+0x79/0x90
+  [   52.765858]  [<ffffffff81003ba2>] do_syscall_64+0x62/0x140
+  [   52.765866]  [<ffffffff817d563f>] entry_SYSCALL64_slow_path+0x25/0x25
+
+Same can be triggered with PROVE_RCU (+ PROVE_RCU_REPEATEDLY) enabled
+from tun_attach_filter() when user space calls ioctl(tun_fd, TUN{ATTACH,
+DETACH}FILTER, ...) for adding/removing a BPF filter on tap devices.
+
+Since the fix in f91ff5b9ff52 ("net: sk_{detach|attach}_filter() rcu
+fixes") sk_attach_filter()/sk_detach_filter() now dereferences the
+filter with rcu_dereference_protected(), checking whether socket lock
+is held in control path.
+
+Since its introduction in 994051625981 ("tun: socket filter support"),
+tap filters are managed under RTNL lock from __tun_chr_ioctl(). Thus the
+sock_owned_by_user(sk) doesn't apply in this specific case and therefore
+triggers the false positive.
+
+Extend the BPF API with __sk_attach_filter()/__sk_detach_filter() pair
+that is used by tap filters and pass in lockdep_rtnl_is_held() for the
+rcu_dereference_protected() checks instead.
+
+Reported-by: Sasha Levin <sasha.levin@oracle.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/tun.c      |    8 +++++---
+ include/linux/filter.h |    4 ++++
+ net/core/filter.c      |   33 +++++++++++++++++++++------------
+ 3 files changed, 30 insertions(+), 15 deletions(-)
+
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -621,7 +621,8 @@ static int tun_attach(struct tun_struct
+       /* Re-attach the filter to persist device */
+       if (!skip_filter && (tun->filter_attached == true)) {
+-              err = sk_attach_filter(&tun->fprog, tfile->socket.sk);
++              err = __sk_attach_filter(&tun->fprog, tfile->socket.sk,
++                                       lockdep_rtnl_is_held());
+               if (!err)
+                       goto out;
+       }
+@@ -1804,7 +1805,7 @@ static void tun_detach_filter(struct tun
+       for (i = 0; i < n; i++) {
+               tfile = rtnl_dereference(tun->tfiles[i]);
+-              sk_detach_filter(tfile->socket.sk);
++              __sk_detach_filter(tfile->socket.sk, lockdep_rtnl_is_held());
+       }
+       tun->filter_attached = false;
+@@ -1817,7 +1818,8 @@ static int tun_attach_filter(struct tun_
+       for (i = 0; i < tun->numqueues; i++) {
+               tfile = rtnl_dereference(tun->tfiles[i]);
+-              ret = sk_attach_filter(&tun->fprog, tfile->socket.sk);
++              ret = __sk_attach_filter(&tun->fprog, tfile->socket.sk,
++                                       lockdep_rtnl_is_held());
+               if (ret) {
+                       tun_detach_filter(tun, i);
+                       return ret;
+--- a/include/linux/filter.h
++++ b/include/linux/filter.h
+@@ -446,8 +446,12 @@ int bpf_prog_create_from_user(struct bpf
+ void bpf_prog_destroy(struct bpf_prog *fp);
+ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk);
++int __sk_attach_filter(struct sock_fprog *fprog, struct sock *sk,
++                     bool locked);
+ int sk_attach_bpf(u32 ufd, struct sock *sk);
+ int sk_detach_filter(struct sock *sk);
++int __sk_detach_filter(struct sock *sk, bool locked);
++
+ int sk_get_filter(struct sock *sk, struct sock_filter __user *filter,
+                 unsigned int len);
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -1139,7 +1139,8 @@ void bpf_prog_destroy(struct bpf_prog *f
+ }
+ EXPORT_SYMBOL_GPL(bpf_prog_destroy);
+-static int __sk_attach_prog(struct bpf_prog *prog, struct sock *sk)
++static int __sk_attach_prog(struct bpf_prog *prog, struct sock *sk,
++                          bool locked)
+ {
+       struct sk_filter *fp, *old_fp;
+@@ -1155,10 +1156,8 @@ static int __sk_attach_prog(struct bpf_p
+               return -ENOMEM;
+       }
+-      old_fp = rcu_dereference_protected(sk->sk_filter,
+-                                         sock_owned_by_user(sk));
++      old_fp = rcu_dereference_protected(sk->sk_filter, locked);
+       rcu_assign_pointer(sk->sk_filter, fp);
+-
+       if (old_fp)
+               sk_filter_uncharge(sk, old_fp);
+@@ -1175,7 +1174,8 @@ static int __sk_attach_prog(struct bpf_p
+  * occurs or there is insufficient memory for the filter a negative
+  * errno code is returned. On success the return is zero.
+  */
+-int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
++int __sk_attach_filter(struct sock_fprog *fprog, struct sock *sk,
++                     bool locked)
+ {
+       unsigned int fsize = bpf_classic_proglen(fprog);
+       unsigned int bpf_fsize = bpf_prog_size(fprog->len);
+@@ -1213,7 +1213,7 @@ int sk_attach_filter(struct sock_fprog *
+       if (IS_ERR(prog))
+               return PTR_ERR(prog);
+-      err = __sk_attach_prog(prog, sk);
++      err = __sk_attach_prog(prog, sk, locked);
+       if (err < 0) {
+               __bpf_prog_release(prog);
+               return err;
+@@ -1221,7 +1221,12 @@ int sk_attach_filter(struct sock_fprog *
+       return 0;
+ }
+-EXPORT_SYMBOL_GPL(sk_attach_filter);
++EXPORT_SYMBOL_GPL(__sk_attach_filter);
++
++int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
++{
++      return __sk_attach_filter(fprog, sk, sock_owned_by_user(sk));
++}
+ int sk_attach_bpf(u32 ufd, struct sock *sk)
+ {
+@@ -1240,7 +1245,7 @@ int sk_attach_bpf(u32 ufd, struct sock *
+               return -EINVAL;
+       }
+-      err = __sk_attach_prog(prog, sk);
++      err = __sk_attach_prog(prog, sk, sock_owned_by_user(sk));
+       if (err < 0) {
+               bpf_prog_put(prog);
+               return err;
+@@ -1913,7 +1918,7 @@ static int __init register_sk_filter_ops
+ }
+ late_initcall(register_sk_filter_ops);
+-int sk_detach_filter(struct sock *sk)
++int __sk_detach_filter(struct sock *sk, bool locked)
+ {
+       int ret = -ENOENT;
+       struct sk_filter *filter;
+@@ -1921,8 +1926,7 @@ int sk_detach_filter(struct sock *sk)
+       if (sock_flag(sk, SOCK_FILTER_LOCKED))
+               return -EPERM;
+-      filter = rcu_dereference_protected(sk->sk_filter,
+-                                         sock_owned_by_user(sk));
++      filter = rcu_dereference_protected(sk->sk_filter, locked);
+       if (filter) {
+               RCU_INIT_POINTER(sk->sk_filter, NULL);
+               sk_filter_uncharge(sk, filter);
+@@ -1931,7 +1935,12 @@ int sk_detach_filter(struct sock *sk)
+       return ret;
+ }
+-EXPORT_SYMBOL_GPL(sk_detach_filter);
++EXPORT_SYMBOL_GPL(__sk_detach_filter);
++
++int sk_detach_filter(struct sock *sk)
++{
++      return __sk_detach_filter(sk, sock_owned_by_user(sk));
++}
+ int sk_get_filter(struct sock *sk, struct sock_filter __user *ubuf,
+                 unsigned int len)
diff --git a/queue-4.4/tunnel-clear-ipcb-skb-opt-before-dst_link_failure-called.patch b/queue-4.4/tunnel-clear-ipcb-skb-opt-before-dst_link_failure-called.patch
new file mode 100644 (file)
index 0000000..060a2ac
--- /dev/null
@@ -0,0 +1,89 @@
+From foo@baz Sat Apr 16 10:02:52 PDT 2016
+From: Bernie Harris <bernie.harris@alliedtelesis.co.nz>
+Date: Mon, 22 Feb 2016 12:58:05 +1300
+Subject: tunnel: Clear IPCB(skb)->opt before dst_link_failure called
+
+From: Bernie Harris <bernie.harris@alliedtelesis.co.nz>
+
+[ Upstream commit 5146d1f151122e868e594c7b45115d64825aee5f ]
+
+IPCB may contain data from previous layers (in the observed case the
+qdisc layer). In the observed scenario, the data was misinterpreted as
+ip header options, which later caused the ihl to be set to an invalid
+value (<5). This resulted in an infinite loop in the mips implementation
+of ip_fast_csum.
+
+This patch clears IPCB(skb)->opt before dst_link_failure can be called for
+various types of tunnels. This change only applies to encapsulated ipv4
+packets.
+
+The code introduced in 11c21a30 which clears all of IPCB has been removed
+to be consistent with these changes, and instead the opt field is cleared
+unconditionally in ip_tunnel_xmit. The change in ip_tunnel_xmit applies to
+SIT, GRE, and IPIP tunnels.
+
+The relevant vti, l2tp, and pptp functions already contain similar code for
+clearing the IPCB.
+
+Signed-off-by: Bernie Harris <bernie.harris@alliedtelesis.co.nz>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/ip_tunnel.c  |    3 ++-
+ net/ipv4/udp_tunnel.c |    2 ++
+ net/ipv6/ip6_gre.c    |    2 ++
+ net/ipv6/ip6_tunnel.c |    2 ++
+ 4 files changed, 8 insertions(+), 1 deletion(-)
+
+--- a/net/ipv4/ip_tunnel.c
++++ b/net/ipv4/ip_tunnel.c
+@@ -663,6 +663,8 @@ void ip_tunnel_xmit(struct sk_buff *skb,
+       inner_iph = (const struct iphdr *)skb_inner_network_header(skb);
+       connected = (tunnel->parms.iph.daddr != 0);
++      memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
++
+       dst = tnl_params->daddr;
+       if (dst == 0) {
+               /* NBMA tunnel */
+@@ -760,7 +762,6 @@ void ip_tunnel_xmit(struct sk_buff *skb,
+                               tunnel->err_time + IPTUNNEL_ERR_TIMEO)) {
+                       tunnel->err_count--;
+-                      memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
+                       dst_link_failure(skb);
+               } else
+                       tunnel->err_count = 0;
+--- a/net/ipv4/udp_tunnel.c
++++ b/net/ipv4/udp_tunnel.c
+@@ -89,6 +89,8 @@ int udp_tunnel_xmit_skb(struct rtable *r
+       uh->source = src_port;
+       uh->len = htons(skb->len);
++      memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
++
+       udp_set_csum(nocheck, skb, src, dst, skb->len);
+       return iptunnel_xmit(sk, rt, skb, src, dst, IPPROTO_UDP,
+--- a/net/ipv6/ip6_gre.c
++++ b/net/ipv6/ip6_gre.c
+@@ -778,6 +778,8 @@ static inline int ip6gre_xmit_ipv4(struc
+       __u32 mtu;
+       int err;
++      memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
++
+       if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
+               encap_limit = t->parms.encap_limit;
+--- a/net/ipv6/ip6_tunnel.c
++++ b/net/ipv6/ip6_tunnel.c
+@@ -1180,6 +1180,8 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, str
+       u8 tproto;
+       int err;
++      memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
++
+       tproto = ACCESS_ONCE(t->parms.proto);
+       if (tproto != IPPROTO_IPIP && tproto != 0)
+               return -1;
diff --git a/queue-4.4/tuntap-restore-default-qdisc.patch b/queue-4.4/tuntap-restore-default-qdisc.patch
new file mode 100644 (file)
index 0000000..166421f
--- /dev/null
@@ -0,0 +1,52 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Jason Wang <jasowang@redhat.com>
+Date: Fri, 8 Apr 2016 13:26:48 +0800
+Subject: tuntap: restore default qdisc
+
+From: Jason Wang <jasowang@redhat.com>
+
+[ Upstream commit 016adb7260f481168c03e09f785184d6d5278894 ]
+
+After commit f84bb1eac027 ("net: fix IFF_NO_QUEUE for drivers using
+alloc_netdev"), default qdisc was changed to noqueue because
+tuntap does not set tx_queue_len during .setup(). This patch restores
+default qdisc by setting tx_queue_len in tun_setup().
+
+Fixes: f84bb1eac027 ("net: fix IFF_NO_QUEUE for drivers using alloc_netdev")
+Cc: Phil Sutter <phil@nwl.cc>
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+Acked-by: Michael S. Tsirkin <mst@redhat.com>
+Acked-by: Phil Sutter <phil@nwl.cc>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/tun.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -1001,7 +1001,6 @@ static void tun_net_init(struct net_devi
+               /* Zero header length */
+               dev->type = ARPHRD_NONE;
+               dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
+-              dev->tx_queue_len = TUN_READQ_SIZE;  /* We prefer our own queue length */
+               break;
+       case IFF_TAP:
+@@ -1013,7 +1012,6 @@ static void tun_net_init(struct net_devi
+               eth_hw_addr_random(dev);
+-              dev->tx_queue_len = TUN_READQ_SIZE;  /* We prefer our own queue length */
+               break;
+       }
+ }
+@@ -1464,6 +1462,8 @@ static void tun_setup(struct net_device
+       dev->ethtool_ops = &tun_ethtool_ops;
+       dev->destructor = tun_free_netdev;
++      /* We prefer our own queue length */
++      dev->tx_queue_len = TUN_READQ_SIZE;
+ }
+ /* Trivial set of netlink ops to allow deleting tun or tap
diff --git a/queue-4.4/udp6-fix-udp-ipv6-encap-resubmit-path.patch b/queue-4.4/udp6-fix-udp-ipv6-encap-resubmit-path.patch
new file mode 100644 (file)
index 0000000..2dbee8e
--- /dev/null
@@ -0,0 +1,43 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Bill Sommerfeld <wsommerfeld@google.com>
+Date: Fri, 4 Mar 2016 14:47:21 -0800
+Subject: udp6: fix UDP/IPv6 encap resubmit path
+
+From: Bill Sommerfeld <wsommerfeld@google.com>
+
+[ Upstream commit 59dca1d8a6725a121dae6c452de0b2611d5865dc ]
+
+IPv4 interprets a negative return value from a protocol handler as a
+request to redispatch to a new protocol.  In contrast, IPv6 interprets a
+negative value as an error, and interprets a positive value as a request
+for redispatch.
+
+UDP for IPv6 was unaware of this difference.  Change __udp6_lib_rcv() to
+return a positive value for redispatch.  Note that the socket's
+encap_rcv hook still needs to return a negative value to request
+dispatch, and in the case of IPv6 packets, adjust IP6CB(skb)->nhoff to
+identify the byte containing the next protocol.
+
+Signed-off-by: Bill Sommerfeld <wsommerfeld@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/udp.c |    6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -916,11 +916,9 @@ int __udp6_lib_rcv(struct sk_buff *skb,
+               ret = udpv6_queue_rcv_skb(sk, skb);
+               sock_put(sk);
+-              /* a return value > 0 means to resubmit the input, but
+-               * it wants the return to be -protocol, or 0
+-               */
++              /* a return value > 0 means to resubmit the input */
+               if (ret > 0)
+-                      return -ret;
++                      return ret;
+               return 0;
+       }
diff --git a/queue-4.4/usbnet-cleanup-after-bind-in-probe.patch b/queue-4.4/usbnet-cleanup-after-bind-in-probe.patch
new file mode 100644 (file)
index 0000000..231880c
--- /dev/null
@@ -0,0 +1,39 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Oliver Neukum <oneukum@suse.com>
+Date: Mon, 7 Mar 2016 11:31:10 +0100
+Subject: usbnet: cleanup after bind() in probe()
+
+From: Oliver Neukum <oneukum@suse.com>
+
+[ Upstream commit 1666984c8625b3db19a9abc298931d35ab7bc64b ]
+
+In case bind() works, but a later error forces bailing
+in probe() in error cases work and a timer may be scheduled.
+They must be killed. This fixes an error case related to
+the double free reported in
+http://www.spinics.net/lists/netdev/msg367669.html
+and needs to go on top of Linus' fix to cdc-ncm.
+
+Signed-off-by: Oliver Neukum <ONeukum@suse.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/usb/usbnet.c |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/net/usb/usbnet.c
++++ b/drivers/net/usb/usbnet.c
+@@ -1766,6 +1766,13 @@ out3:
+       if (info->unbind)
+               info->unbind (dev, udev);
+ out1:
++      /* subdrivers must undo all they did in bind() if they
++       * fail it, but we may fail later and a deferred kevent
++       * may trigger an error resubmitting itself and, worse,
++       * schedule a timer. So we kill it all just in case.
++       */
++      cancel_work_sync(&dev->kevent);
++      del_timer_sync(&dev->delay);
+       free_netdev(net);
+ out:
+       return status;
diff --git a/queue-4.4/vxlan-fix-missing-options_len-update-on-rx-with-collect-metadata.patch b/queue-4.4/vxlan-fix-missing-options_len-update-on-rx-with-collect-metadata.patch
new file mode 100644 (file)
index 0000000..5e1a5be
--- /dev/null
@@ -0,0 +1,42 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: Daniel Borkmann <daniel@iogearbox.net>
+Date: Wed, 2 Mar 2016 02:32:08 +0100
+Subject: vxlan: fix missing options_len update on RX with collect metadata
+
+From: Daniel Borkmann <daniel@iogearbox.net>
+
+[ Upstream commit 4024fcf70556311521e7b6cf79fa50e16f31013a ]
+
+When signalling to metadata consumers that the metadata_dst entry
+carries additional GBP extension data for vxlan (TUNNEL_VXLAN_OPT),
+the dst's vxlan_metadata information is populated, but options_len
+is left to zero. F.e. in ovs, ovs_flow_key_extract() checks for
+options_len before extracting the data through ip_tunnel_info_opts_get().
+
+Geneve uses ip_tunnel_info_opts_set() helper in receive path, which
+sets options_len internally, vxlan however uses ip_tunnel_info_opts(),
+so when filling vxlan_metadata, we do need to update options_len.
+
+Fixes: 4c22279848c5 ("ip-tunnel: Use API to access tunnel metadata options.")
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Thomas Graf <tgraf@suug.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/vxlan.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/vxlan.c
++++ b/drivers/net/vxlan.c
+@@ -1306,8 +1306,10 @@ static int vxlan_udp_encap_recv(struct s
+               gbp = (struct vxlanhdr_gbp *)vxh;
+               md->gbp = ntohs(gbp->policy_id);
+-              if (tun_dst)
++              if (tun_dst) {
+                       tun_dst->u.tun_info.key.tun_flags |= TUNNEL_VXLAN_OPT;
++                      tun_dst->u.tun_info.options_len = sizeof(*md);
++              }
+               if (gbp->dont_learn)
+                       md->gbp |= VXLAN_GBP_DONT_LEARN;
diff --git a/queue-4.4/xfrm-fix-crash-observed-during-device-unregistration-and-decryption.patch b/queue-4.4/xfrm-fix-crash-observed-during-device-unregistration-and-decryption.patch
new file mode 100644 (file)
index 0000000..92f91a8
--- /dev/null
@@ -0,0 +1,77 @@
+From foo@baz Sat Apr 16 10:02:53 PDT 2016
+From: "subashab@codeaurora.org" <subashab@codeaurora.org>
+Date: Wed, 23 Mar 2016 22:39:50 -0600
+Subject: xfrm: Fix crash observed during device unregistration and decryption
+
+From: "subashab@codeaurora.org" <subashab@codeaurora.org>
+
+[ Upstream commit 071d36bf21bcc837be00cea55bcef8d129e7f609 ]
+
+A crash is observed when a decrypted packet is processed in receive
+path. get_rps_cpus() tries to dereference the skb->dev fields but it
+appears that the device is freed from the poison pattern.
+
+[<ffffffc000af58ec>] get_rps_cpu+0x94/0x2f0
+[<ffffffc000af5f94>] netif_rx_internal+0x140/0x1cc
+[<ffffffc000af6094>] netif_rx+0x74/0x94
+[<ffffffc000bc0b6c>] xfrm_input+0x754/0x7d0
+[<ffffffc000bc0bf8>] xfrm_input_resume+0x10/0x1c
+[<ffffffc000ba6eb8>] esp_input_done+0x20/0x30
+[<ffffffc0000b64c8>] process_one_work+0x244/0x3fc
+[<ffffffc0000b7324>] worker_thread+0x2f8/0x418
+[<ffffffc0000bb40c>] kthread+0xe0/0xec
+
+-013|get_rps_cpu(
+     |    dev = 0xFFFFFFC08B688000,
+     |    skb = 0xFFFFFFC0C76AAC00 -> (
+     |      dev = 0xFFFFFFC08B688000 -> (
+     |        name =
+"......................................................
+     |        name_hlist = (next = 0xAAAAAAAAAAAAAAAA, pprev =
+0xAAAAAAAAAAA
+
+Following are the sequence of events observed -
+
+- Encrypted packet in receive path from netdevice is queued
+- Encrypted packet queued for decryption (asynchronous)
+- Netdevice brought down and freed
+- Packet is decrypted and returned through callback in esp_input_done
+- Packet is queued again for process in network stack using netif_rx
+
+Since the device appears to have been freed, the dereference of
+skb->dev in get_rps_cpus() leads to an unhandled page fault
+exception.
+
+Fix this by holding on to device reference when queueing packets
+asynchronously and releasing the reference on call back return.
+
+v2: Make the change generic to xfrm as mentioned by Steffen and
+update the title to xfrm
+
+Suggested-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Jerome Stanislaus <jeromes@codeaurora.org>
+Signed-off-by: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/xfrm/xfrm_input.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/net/xfrm/xfrm_input.c
++++ b/net/xfrm/xfrm_input.c
+@@ -292,12 +292,15 @@ int xfrm_input(struct sk_buff *skb, int
+               XFRM_SKB_CB(skb)->seq.input.hi = seq_hi;
+               skb_dst_force(skb);
++              dev_hold(skb->dev);
+               nexthdr = x->type->input(x, skb);
+               if (nexthdr == -EINPROGRESS)
+                       return 0;
+ resume:
++              dev_put(skb->dev);
++
+               spin_lock(&x->lock);
+               if (nexthdr <= 0) {
+                       if (nexthdr == -EBADMSG) {