summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlice Ferrazzi <alicef@gentoo.org>2017-11-18 20:04:21 +0000
committerAlice Ferrazzi <alicef@gentoo.org>2017-11-18 20:04:21 +0000
commitb52e47c0c5ad60eb4e5ca0ad9658e41efe03911a (patch)
treefad5e7ee543385cc0e1365ac8c7e025db6f56564
parentLinux patch 4.13.13 (diff)
downloadlinux-patches-b52e47c0c5ad60eb4e5ca0ad9658e41efe03911a.tar.gz
linux-patches-b52e47c0c5ad60eb4e5ca0ad9658e41efe03911a.tar.bz2
linux-patches-b52e47c0c5ad60eb4e5ca0ad9658e41efe03911a.zip
linux kernel 4.13.144.13-174.13-16
-rw-r--r--0000_README4
-rw-r--r--1013_linux-4.13.14.patch1678
2 files changed, 1682 insertions, 0 deletions
diff --git a/0000_README b/0000_README
index 5edbdf0a..8777a913 100644
--- a/0000_README
+++ b/0000_README
@@ -95,6 +95,10 @@ Patch: 1012_linux-4.13.13.patch
From: http://www.kernel.org
Desc: Linux 4.13.13
+Patch: 1013_linux-4.13.14.patch
+From: http://www.kernel.org
+Desc: Linux 4.13.14
+
Patch: 1500_XATTR_USER_PREFIX.patch
From: https://bugs.gentoo.org/show_bug.cgi?id=470644
Desc: Support for namespace user.pax.* on tmpfs.
diff --git a/1013_linux-4.13.14.patch b/1013_linux-4.13.14.patch
new file mode 100644
index 00000000..c5443f71
--- /dev/null
+++ b/1013_linux-4.13.14.patch
@@ -0,0 +1,1678 @@
+diff --git a/Makefile b/Makefile
+index 1608a9b71381..4aabae365a6c 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 13
+-SUBLEVEL = 13
++SUBLEVEL = 14
+ EXTRAVERSION =
+ NAME = Fearless Coyote
+
+diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c
+index a07ef3d6b3ec..2b478224532e 100644
+--- a/drivers/dma/dmatest.c
++++ b/drivers/dma/dmatest.c
+@@ -696,6 +696,7 @@ static int dmatest_func(void *data)
+ * free it this time?" dancing. For now, just
+ * leave it dangling.
+ */
++ WARN(1, "dmatest: Kernel stack may be corrupted!!\n");
+ dmaengine_unmap_put(um);
+ result("test timed out", total_tests, src_off, dst_off,
+ len, 0);
+diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c
+index 80d860cb0746..7a3b201d51df 100644
+--- a/drivers/edac/sb_edac.c
++++ b/drivers/edac/sb_edac.c
+@@ -455,6 +455,7 @@ static const struct pci_id_table pci_dev_descr_sbridge_table[] = {
+ static const struct pci_id_descr pci_dev_descr_ibridge[] = {
+ /* Processor Home Agent */
+ { PCI_DESCR(PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0, 0, IMC0) },
++ { PCI_DESCR(PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA1, 1, IMC1) },
+
+ /* Memory controller */
+ { PCI_DESCR(PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0_TA, 0, IMC0) },
+@@ -465,7 +466,6 @@ static const struct pci_id_descr pci_dev_descr_ibridge[] = {
+ { PCI_DESCR(PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0_TAD3, 0, IMC0) },
+
+ /* Optional, mode 2HA */
+- { PCI_DESCR(PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA1, 1, IMC1) },
+ { PCI_DESCR(PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA1_TA, 1, IMC1) },
+ { PCI_DESCR(PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA1_RAS, 1, IMC1) },
+ { PCI_DESCR(PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA1_TAD0, 1, IMC1) },
+@@ -2260,6 +2260,13 @@ static int sbridge_get_onedevice(struct pci_dev **prev,
+ next_imc:
+ sbridge_dev = get_sbridge_dev(bus, dev_descr->dom, multi_bus, sbridge_dev);
+ if (!sbridge_dev) {
++ /* If the HA1 wasn't found, don't create EDAC second memory controller */
++ if (dev_descr->dom == IMC1 && devno != 1) {
++ edac_dbg(0, "Skip IMC1: %04x:%04x (since HA1 was absent)\n",
++ PCI_VENDOR_ID_INTEL, dev_descr->dev_id);
++ pci_dev_put(pdev);
++ return 0;
++ }
+
+ if (dev_descr->dom == SOCK)
+ goto out_imc;
+diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c
+index f4e8fbec6a94..b5304e264881 100644
+--- a/drivers/input/misc/ims-pcu.c
++++ b/drivers/input/misc/ims-pcu.c
+@@ -1635,13 +1635,25 @@ ims_pcu_get_cdc_union_desc(struct usb_interface *intf)
+ return NULL;
+ }
+
+- while (buflen > 0) {
++ while (buflen >= sizeof(*union_desc)) {
+ union_desc = (struct usb_cdc_union_desc *)buf;
+
++ if (union_desc->bLength > buflen) {
++ dev_err(&intf->dev, "Too large descriptor\n");
++ return NULL;
++ }
++
+ if (union_desc->bDescriptorType == USB_DT_CS_INTERFACE &&
+ union_desc->bDescriptorSubType == USB_CDC_UNION_TYPE) {
+ dev_dbg(&intf->dev, "Found union header\n");
+- return union_desc;
++
++ if (union_desc->bLength >= sizeof(*union_desc))
++ return union_desc;
++
++ dev_err(&intf->dev,
++ "Union descriptor to short (%d vs %zd\n)",
++ union_desc->bLength, sizeof(*union_desc));
++ return NULL;
+ }
+
+ buflen -= union_desc->bLength;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+index 7f282e8f4e7f..dc7f952e341f 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+@@ -78,9 +78,11 @@ struct mlx5e_tc_flow {
+ };
+
+ struct mlx5e_tc_flow_parse_attr {
++ struct ip_tunnel_info tun_info;
+ struct mlx5_flow_spec spec;
+ int num_mod_hdr_actions;
+ void *mod_hdr_actions;
++ int mirred_ifindex;
+ };
+
+ enum {
+@@ -322,6 +324,12 @@ static void mlx5e_tc_del_nic_flow(struct mlx5e_priv *priv,
+ static void mlx5e_detach_encap(struct mlx5e_priv *priv,
+ struct mlx5e_tc_flow *flow);
+
++static int mlx5e_attach_encap(struct mlx5e_priv *priv,
++ struct ip_tunnel_info *tun_info,
++ struct net_device *mirred_dev,
++ struct net_device **encap_dev,
++ struct mlx5e_tc_flow *flow);
++
+ static struct mlx5_flow_handle *
+ mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
+ struct mlx5e_tc_flow_parse_attr *parse_attr,
+@@ -329,9 +337,27 @@ mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
+ {
+ struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
+ struct mlx5_esw_flow_attr *attr = flow->esw_attr;
+- struct mlx5_flow_handle *rule;
++ struct net_device *out_dev, *encap_dev = NULL;
++ struct mlx5_flow_handle *rule = NULL;
++ struct mlx5e_rep_priv *rpriv;
++ struct mlx5e_priv *out_priv;
+ int err;
+
++ if (attr->action & MLX5_FLOW_CONTEXT_ACTION_ENCAP) {
++ out_dev = __dev_get_by_index(dev_net(priv->netdev),
++ attr->parse_attr->mirred_ifindex);
++ err = mlx5e_attach_encap(priv, &parse_attr->tun_info,
++ out_dev, &encap_dev, flow);
++ if (err) {
++ rule = ERR_PTR(err);
++ if (err != -EAGAIN)
++ goto err_attach_encap;
++ }
++ out_priv = netdev_priv(encap_dev);
++ rpriv = out_priv->ppriv;
++ attr->out_rep = rpriv->rep;
++ }
++
+ err = mlx5_eswitch_add_vlan_action(esw, attr);
+ if (err) {
+ rule = ERR_PTR(err);
+@@ -347,10 +373,14 @@ mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
+ }
+ }
+
+- rule = mlx5_eswitch_add_offloaded_rule(esw, &parse_attr->spec, attr);
+- if (IS_ERR(rule))
+- goto err_add_rule;
+-
++ /* we get here if (1) there's no error (rule being null) or when
++ * (2) there's an encap action and we're on -EAGAIN (no valid neigh)
++ */
++ if (rule != ERR_PTR(-EAGAIN)) {
++ rule = mlx5_eswitch_add_offloaded_rule(esw, &parse_attr->spec, attr);
++ if (IS_ERR(rule))
++ goto err_add_rule;
++ }
+ return rule;
+
+ err_add_rule:
+@@ -361,6 +391,7 @@ mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
+ err_add_vlan:
+ if (attr->action & MLX5_FLOW_CONTEXT_ACTION_ENCAP)
+ mlx5e_detach_encap(priv, flow);
++err_attach_encap:
+ return rule;
+ }
+
+@@ -389,6 +420,8 @@ static void mlx5e_tc_del_fdb_flow(struct mlx5e_priv *priv,
+ void mlx5e_tc_encap_flows_add(struct mlx5e_priv *priv,
+ struct mlx5e_encap_entry *e)
+ {
++ struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
++ struct mlx5_esw_flow_attr *esw_attr;
+ struct mlx5e_tc_flow *flow;
+ int err;
+
+@@ -404,10 +437,9 @@ void mlx5e_tc_encap_flows_add(struct mlx5e_priv *priv,
+ mlx5e_rep_queue_neigh_stats_work(priv);
+
+ list_for_each_entry(flow, &e->flows, encap) {
+- flow->esw_attr->encap_id = e->encap_id;
+- flow->rule = mlx5e_tc_add_fdb_flow(priv,
+- flow->esw_attr->parse_attr,
+- flow);
++ esw_attr = flow->esw_attr;
++ esw_attr->encap_id = e->encap_id;
++ flow->rule = mlx5_eswitch_add_offloaded_rule(esw, &esw_attr->parse_attr->spec, esw_attr);
+ if (IS_ERR(flow->rule)) {
+ err = PTR_ERR(flow->rule);
+ mlx5_core_warn(priv->mdev, "Failed to update cached encapsulation flow, %d\n",
+@@ -421,15 +453,13 @@ void mlx5e_tc_encap_flows_add(struct mlx5e_priv *priv,
+ void mlx5e_tc_encap_flows_del(struct mlx5e_priv *priv,
+ struct mlx5e_encap_entry *e)
+ {
++ struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
+ struct mlx5e_tc_flow *flow;
+- struct mlx5_fc *counter;
+
+ list_for_each_entry(flow, &e->flows, encap) {
+ if (flow->flags & MLX5E_TC_FLOW_OFFLOADED) {
+ flow->flags &= ~MLX5E_TC_FLOW_OFFLOADED;
+- counter = mlx5_flow_rule_counter(flow->rule);
+- mlx5_del_flow_rules(flow->rule);
+- mlx5_fc_destroy(priv->mdev, counter);
++ mlx5_eswitch_del_offloaded_rule(esw, flow->rule, flow->esw_attr);
+ }
+ }
+
+@@ -1871,7 +1901,7 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
+
+ if (is_tcf_mirred_egress_redirect(a)) {
+ int ifindex = tcf_mirred_ifindex(a);
+- struct net_device *out_dev, *encap_dev = NULL;
++ struct net_device *out_dev;
+ struct mlx5e_priv *out_priv;
+
+ out_dev = __dev_get_by_index(dev_net(priv->netdev), ifindex);
+@@ -1884,17 +1914,13 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
+ rpriv = out_priv->ppriv;
+ attr->out_rep = rpriv->rep;
+ } else if (encap) {
+- err = mlx5e_attach_encap(priv, info,
+- out_dev, &encap_dev, flow);
+- if (err && err != -EAGAIN)
+- return err;
++ parse_attr->mirred_ifindex = ifindex;
++ parse_attr->tun_info = *info;
++ attr->parse_attr = parse_attr;
+ attr->action |= MLX5_FLOW_CONTEXT_ACTION_ENCAP |
+ MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |
+ MLX5_FLOW_CONTEXT_ACTION_COUNT;
+- out_priv = netdev_priv(encap_dev);
+- rpriv = out_priv->ppriv;
+- attr->out_rep = rpriv->rep;
+- attr->parse_attr = parse_attr;
++ /* attr->out_rep is resolved when we handle encap */
+ } else {
+ pr_err("devices %s %s not on same switch HW, can't offload forwarding\n",
+ priv->netdev->name, out_dev->name);
+@@ -1972,7 +1998,7 @@ int mlx5e_configure_flower(struct mlx5e_priv *priv, __be16 protocol,
+ if (flow->flags & MLX5E_TC_FLOW_ESWITCH) {
+ err = parse_tc_fdb_actions(priv, f->exts, parse_attr, flow);
+ if (err < 0)
+- goto err_handle_encap_flow;
++ goto err_free;
+ flow->rule = mlx5e_tc_add_fdb_flow(priv, parse_attr, flow);
+ } else {
+ err = parse_tc_nic_actions(priv, f->exts, parse_attr, flow);
+@@ -1983,10 +2009,13 @@ int mlx5e_configure_flower(struct mlx5e_priv *priv, __be16 protocol,
+
+ if (IS_ERR(flow->rule)) {
+ err = PTR_ERR(flow->rule);
+- goto err_free;
++ if (err != -EAGAIN)
++ goto err_free;
+ }
+
+- flow->flags |= MLX5E_TC_FLOW_OFFLOADED;
++ if (err != -EAGAIN)
++ flow->flags |= MLX5E_TC_FLOW_OFFLOADED;
++
+ err = rhashtable_insert_fast(&tc->ht, &flow->node,
+ tc->ht_params);
+ if (err)
+@@ -2000,16 +2029,6 @@ int mlx5e_configure_flower(struct mlx5e_priv *priv, __be16 protocol,
+ err_del_rule:
+ mlx5e_tc_del_flow(priv, flow);
+
+-err_handle_encap_flow:
+- if (err == -EAGAIN) {
+- err = rhashtable_insert_fast(&tc->ht, &flow->node,
+- tc->ht_params);
+- if (err)
+- mlx5e_tc_del_flow(priv, flow);
+- else
+- return 0;
+- }
+-
+ err_free:
+ kvfree(parse_attr);
+ kfree(flow);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/health.c b/drivers/net/ethernet/mellanox/mlx5/core/health.c
+index 4b6b03d6297f..8ccb68a49c65 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/health.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/health.c
+@@ -356,10 +356,11 @@ void mlx5_drain_health_wq(struct mlx5_core_dev *dev)
+ void mlx5_drain_health_recovery(struct mlx5_core_dev *dev)
+ {
+ struct mlx5_core_health *health = &dev->priv.health;
++ unsigned long flags;
+
+- spin_lock(&health->wq_lock);
++ spin_lock_irqsave(&health->wq_lock, flags);
+ set_bit(MLX5_DROP_NEW_RECOVERY_WORK, &health->flags);
+- spin_unlock(&health->wq_lock);
++ spin_unlock_irqrestore(&health->wq_lock, flags);
+ cancel_delayed_work_sync(&dev->priv.health.recover_work);
+ }
+
+diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
+index 2bbda71818ad..e0a7176e1d39 100644
+--- a/drivers/net/geneve.c
++++ b/drivers/net/geneve.c
+@@ -113,13 +113,7 @@ static void tunnel_id_to_vni(__be64 tun_id, __u8 *vni)
+
+ static bool eq_tun_id_and_vni(u8 *tun_id, u8 *vni)
+ {
+-#ifdef __BIG_ENDIAN
+- return (vni[0] == tun_id[2]) &&
+- (vni[1] == tun_id[1]) &&
+- (vni[2] == tun_id[0]);
+-#else
+ return !memcmp(vni, &tun_id[5], 3);
+-#endif
+ }
+
+ static sa_family_t geneve_get_sk_family(struct geneve_sock *gs)
+diff --git a/drivers/net/ipvlan/ipvtap.c b/drivers/net/ipvlan/ipvtap.c
+index 22f133ea8d7b..2bdd71c4fcd1 100644
+--- a/drivers/net/ipvlan/ipvtap.c
++++ b/drivers/net/ipvlan/ipvtap.c
+@@ -197,8 +197,8 @@ static int ipvtap_init(void)
+ {
+ int err;
+
+- err = tap_create_cdev(&ipvtap_cdev, &ipvtap_major, "ipvtap");
+-
++ err = tap_create_cdev(&ipvtap_cdev, &ipvtap_major, "ipvtap",
++ THIS_MODULE);
+ if (err)
+ goto out1;
+
+diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
+index 98e4deaa3a6a..5ab1b8849c30 100644
+--- a/drivers/net/macsec.c
++++ b/drivers/net/macsec.c
+@@ -742,6 +742,7 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb,
+ sg_init_table(sg, ret);
+ ret = skb_to_sgvec(skb, sg, 0, skb->len);
+ if (unlikely(ret < 0)) {
++ aead_request_free(req);
+ macsec_txsa_put(tx_sa);
+ kfree_skb(skb);
+ return ERR_PTR(ret);
+@@ -954,6 +955,7 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb,
+ sg_init_table(sg, ret);
+ ret = skb_to_sgvec(skb, sg, 0, skb->len);
+ if (unlikely(ret < 0)) {
++ aead_request_free(req);
+ kfree_skb(skb);
+ return ERR_PTR(ret);
+ }
+diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
+index 91e7b19bbf86..a84691bd75a7 100644
+--- a/drivers/net/macvtap.c
++++ b/drivers/net/macvtap.c
+@@ -204,8 +204,8 @@ static int macvtap_init(void)
+ {
+ int err;
+
+- err = tap_create_cdev(&macvtap_cdev, &macvtap_major, "macvtap");
+-
++ err = tap_create_cdev(&macvtap_cdev, &macvtap_major, "macvtap",
++ THIS_MODULE);
+ if (err)
+ goto out1;
+
+diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
+index a404552555d4..6722b8354618 100644
+--- a/drivers/net/ppp/ppp_generic.c
++++ b/drivers/net/ppp/ppp_generic.c
+@@ -1339,7 +1339,17 @@ ppp_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats64)
+
+ static int ppp_dev_init(struct net_device *dev)
+ {
++ struct ppp *ppp;
++
+ netdev_lockdep_set_classes(dev);
++
++ ppp = netdev_priv(dev);
++ /* Let the netdevice take a reference on the ppp file. This ensures
++ * that ppp_destroy_interface() won't run before the device gets
++ * unregistered.
++ */
++ atomic_inc(&ppp->file.refcnt);
++
+ return 0;
+ }
+
+@@ -1362,6 +1372,15 @@ static void ppp_dev_uninit(struct net_device *dev)
+ wake_up_interruptible(&ppp->file.rwait);
+ }
+
++static void ppp_dev_priv_destructor(struct net_device *dev)
++{
++ struct ppp *ppp;
++
++ ppp = netdev_priv(dev);
++ if (atomic_dec_and_test(&ppp->file.refcnt))
++ ppp_destroy_interface(ppp);
++}
++
+ static const struct net_device_ops ppp_netdev_ops = {
+ .ndo_init = ppp_dev_init,
+ .ndo_uninit = ppp_dev_uninit,
+@@ -1387,6 +1406,7 @@ static void ppp_setup(struct net_device *dev)
+ dev->tx_queue_len = 3;
+ dev->type = ARPHRD_PPP;
+ dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
++ dev->priv_destructor = ppp_dev_priv_destructor;
+ netif_keep_dst(dev);
+ }
+
+diff --git a/drivers/net/tap.c b/drivers/net/tap.c
+index 3570c7576993..38edfcfd3c3a 100644
+--- a/drivers/net/tap.c
++++ b/drivers/net/tap.c
+@@ -517,6 +517,10 @@ static int tap_open(struct inode *inode, struct file *file)
+ &tap_proto, 0);
+ if (!q)
+ goto err;
++ if (skb_array_init(&q->skb_array, tap->dev->tx_queue_len, GFP_KERNEL)) {
++ sk_free(&q->sk);
++ goto err;
++ }
+
+ RCU_INIT_POINTER(q->sock.wq, &q->wq);
+ init_waitqueue_head(&q->wq.wait);
+@@ -540,22 +544,18 @@ static int tap_open(struct inode *inode, struct file *file)
+ if ((tap->dev->features & NETIF_F_HIGHDMA) && (tap->dev->features & NETIF_F_SG))
+ sock_set_flag(&q->sk, SOCK_ZEROCOPY);
+
+- err = -ENOMEM;
+- if (skb_array_init(&q->skb_array, tap->dev->tx_queue_len, GFP_KERNEL))
+- goto err_array;
+-
+ err = tap_set_queue(tap, file, q);
+- if (err)
+- goto err_queue;
++ if (err) {
++ /* tap_sock_destruct() will take care of freeing skb_array */
++ goto err_put;
++ }
+
+ dev_put(tap->dev);
+
+ rtnl_unlock();
+ return err;
+
+-err_queue:
+- skb_array_cleanup(&q->skb_array);
+-err_array:
++err_put:
+ sock_put(&q->sk);
+ err:
+ if (tap)
+@@ -1035,6 +1035,8 @@ static long tap_ioctl(struct file *file, unsigned int cmd,
+ case TUNSETSNDBUF:
+ if (get_user(s, sp))
+ return -EFAULT;
++ if (s <= 0)
++ return -EINVAL;
+
+ q->sk.sk_sndbuf = s;
+ return 0;
+@@ -1252,8 +1254,8 @@ static int tap_list_add(dev_t major, const char *device_name)
+ return 0;
+ }
+
+-int tap_create_cdev(struct cdev *tap_cdev,
+- dev_t *tap_major, const char *device_name)
++int tap_create_cdev(struct cdev *tap_cdev, dev_t *tap_major,
++ const char *device_name, struct module *module)
+ {
+ int err;
+
+@@ -1262,6 +1264,7 @@ int tap_create_cdev(struct cdev *tap_cdev,
+ goto out1;
+
+ cdev_init(tap_cdev, &tap_fops);
++ tap_cdev->owner = module;
+ err = cdev_add(tap_cdev, *tap_major, TAP_NUM_DEVS);
+ if (err)
+ goto out2;
+diff --git a/drivers/net/tun.c b/drivers/net/tun.c
+index cb1f7747adad..d1cb1ff83251 100644
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -1813,6 +1813,9 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
+
+ if (!dev)
+ return -ENOMEM;
++ err = dev_get_valid_name(net, dev, name);
++ if (err < 0)
++ goto err_free_dev;
+
+ dev_net_set(dev, net);
+ dev->rtnl_link_ops = &tun_link_ops;
+@@ -2216,6 +2219,10 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
+ ret = -EFAULT;
+ break;
+ }
++ if (sndbuf <= 0) {
++ ret = -EINVAL;
++ break;
++ }
+
+ tun->sndbuf = sndbuf;
+ tun_set_sndbuf(tun);
+diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
+index eee82ca55b7b..cf4f5fff3e50 100644
+--- a/drivers/usb/misc/usbtest.c
++++ b/drivers/usb/misc/usbtest.c
+@@ -202,12 +202,13 @@ get_endpoints(struct usbtest_dev *dev, struct usb_interface *intf)
+ return tmp;
+ }
+
+- if (in) {
++ if (in)
+ dev->in_pipe = usb_rcvbulkpipe(udev,
+ in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
++ if (out)
+ dev->out_pipe = usb_sndbulkpipe(udev,
+ out->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+- }
++
+ if (iso_in) {
+ dev->iso_in = &iso_in->desc;
+ dev->in_iso_pipe = usb_rcvisocpipe(udev,
+diff --git a/include/linux/if_tap.h b/include/linux/if_tap.h
+index 4837157da0dc..9ae41cdd0d4c 100644
+--- a/include/linux/if_tap.h
++++ b/include/linux/if_tap.h
+@@ -73,8 +73,8 @@ void tap_del_queues(struct tap_dev *tap);
+ int tap_get_minor(dev_t major, struct tap_dev *tap);
+ void tap_free_minor(dev_t major, struct tap_dev *tap);
+ int tap_queue_resize(struct tap_dev *tap);
+-int tap_create_cdev(struct cdev *tap_cdev,
+- dev_t *tap_major, const char *device_name);
++int tap_create_cdev(struct cdev *tap_cdev, dev_t *tap_major,
++ const char *device_name, struct module *module);
+ void tap_destroy_cdev(dev_t major, struct cdev *tap_cdev);
+
+ #endif /*_LINUX_IF_TAP_H_*/
+diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
+index c99ba7914c0a..a6d3c8b6cb93 100644
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -3702,6 +3702,9 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
+ unsigned char name_assign_type,
+ void (*setup)(struct net_device *),
+ unsigned int txqs, unsigned int rxqs);
++int dev_get_valid_name(struct net *net, struct net_device *dev,
++ const char *name);
++
+ #define alloc_netdev(sizeof_priv, name, name_assign_type, setup) \
+ alloc_netdev_mqs(sizeof_priv, name, name_assign_type, setup, 1, 1)
+
+diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
+index aa95053dfc78..db8162dd8c0b 100644
+--- a/include/net/inet_sock.h
++++ b/include/net/inet_sock.h
+@@ -96,7 +96,7 @@ struct inet_request_sock {
+ kmemcheck_bitfield_end(flags);
+ u32 ir_mark;
+ union {
+- struct ip_options_rcu *opt;
++ struct ip_options_rcu __rcu *ireq_opt;
+ #if IS_ENABLED(CONFIG_IPV6)
+ struct {
+ struct ipv6_txoptions *ipv6_opt;
+@@ -132,6 +132,12 @@ static inline int inet_request_bound_dev_if(const struct sock *sk,
+ return sk->sk_bound_dev_if;
+ }
+
++static inline struct ip_options_rcu *ireq_opt_deref(const struct inet_request_sock *ireq)
++{
++ return rcu_dereference_check(ireq->ireq_opt,
++ refcount_read(&ireq->req.rsk_refcnt) > 0);
++}
++
+ struct inet_cork {
+ unsigned int flags;
+ __be32 addr;
+diff --git a/include/net/tcp.h b/include/net/tcp.h
+index 48978125947b..150c2c66897a 100644
+--- a/include/net/tcp.h
++++ b/include/net/tcp.h
+@@ -1750,12 +1750,12 @@ static inline void tcp_highest_sack_reset(struct sock *sk)
+ tcp_sk(sk)->highest_sack = tcp_write_queue_head(sk);
+ }
+
+-/* Called when old skb is about to be deleted (to be combined with new skb) */
+-static inline void tcp_highest_sack_combine(struct sock *sk,
++/* Called when old skb is about to be deleted and replaced by new skb */
++static inline void tcp_highest_sack_replace(struct sock *sk,
+ struct sk_buff *old,
+ struct sk_buff *new)
+ {
+- if (tcp_sk(sk)->sacked_out && (old == tcp_sk(sk)->highest_sack))
++ if (old == tcp_highest_sack(sk))
+ tcp_sk(sk)->highest_sack = new;
+ }
+
+diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
+index 3bc890716c89..de2152730809 100644
+--- a/net/bridge/br_netlink.c
++++ b/net/bridge/br_netlink.c
+@@ -573,7 +573,7 @@ static int br_process_vlan_info(struct net_bridge *br,
+ }
+ *vinfo_last = NULL;
+
+- return 0;
++ return err;
+ }
+
+ return br_vlan_info(br, p, cmd, vinfo_curr);
+diff --git a/net/core/dev.c b/net/core/dev.c
+index 6fa30a4c60ef..4f9ec923d21b 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -1146,9 +1146,8 @@ static int dev_alloc_name_ns(struct net *net,
+ return ret;
+ }
+
+-static int dev_get_valid_name(struct net *net,
+- struct net_device *dev,
+- const char *name)
++int dev_get_valid_name(struct net *net, struct net_device *dev,
++ const char *name)
+ {
+ BUG_ON(!net);
+
+@@ -1164,6 +1163,7 @@ static int dev_get_valid_name(struct net *net,
+
+ return 0;
+ }
++EXPORT_SYMBOL(dev_get_valid_name);
+
+ /**
+ * dev_change_name - change name of a device
+diff --git a/net/core/sock.c b/net/core/sock.c
+index 0967da925022..e48424ddbc6b 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -1674,6 +1674,7 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
+ newsk->sk_userlocks = sk->sk_userlocks & ~SOCK_BINDPORT_LOCK;
+
+ sock_reset_flag(newsk, SOCK_DONE);
++ cgroup_sk_alloc(&newsk->sk_cgrp_data);
+
+ rcu_read_lock();
+ filter = rcu_dereference(sk->sk_filter);
+@@ -1706,8 +1707,6 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
+ atomic64_set(&newsk->sk_cookie, 0);
+
+ mem_cgroup_sk_alloc(newsk);
+- cgroup_sk_alloc(&newsk->sk_cgrp_data);
+-
+ /*
+ * Before updating sk_refcnt, we must commit prior changes to memory
+ * (Documentation/RCU/rculist_nulls.txt for details)
+diff --git a/net/core/sock_reuseport.c b/net/core/sock_reuseport.c
+index eed1ebf7f29d..b1e0dbea1e8c 100644
+--- a/net/core/sock_reuseport.c
++++ b/net/core/sock_reuseport.c
+@@ -36,9 +36,14 @@ int reuseport_alloc(struct sock *sk)
+ * soft irq of receive path or setsockopt from process context
+ */
+ spin_lock_bh(&reuseport_lock);
+- WARN_ONCE(rcu_dereference_protected(sk->sk_reuseport_cb,
+- lockdep_is_held(&reuseport_lock)),
+- "multiple allocations for the same socket");
++
++ /* Allocation attempts can occur concurrently via the setsockopt path
++ * and the bind/hash path. Nothing to do when we lose the race.
++ */
++ if (rcu_dereference_protected(sk->sk_reuseport_cb,
++ lockdep_is_held(&reuseport_lock)))
++ goto out;
++
+ reuse = __reuseport_alloc(INIT_SOCKS);
+ if (!reuse) {
+ spin_unlock_bh(&reuseport_lock);
+@@ -49,6 +54,7 @@ int reuseport_alloc(struct sock *sk)
+ reuse->num_socks = 1;
+ rcu_assign_pointer(sk->sk_reuseport_cb, reuse);
+
++out:
+ spin_unlock_bh(&reuseport_lock);
+
+ return 0;
+diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
+index 1b202f16531f..bc70d96d762a 100644
+--- a/net/dccp/ipv4.c
++++ b/net/dccp/ipv4.c
+@@ -414,8 +414,7 @@ struct sock *dccp_v4_request_recv_sock(const struct sock *sk,
+ sk_daddr_set(newsk, ireq->ir_rmt_addr);
+ sk_rcv_saddr_set(newsk, ireq->ir_loc_addr);
+ newinet->inet_saddr = ireq->ir_loc_addr;
+- newinet->inet_opt = ireq->opt;
+- ireq->opt = NULL;
++ RCU_INIT_POINTER(newinet->inet_opt, rcu_dereference(ireq->ireq_opt));
+ newinet->mc_index = inet_iif(skb);
+ newinet->mc_ttl = ip_hdr(skb)->ttl;
+ newinet->inet_id = jiffies;
+@@ -430,7 +429,10 @@ struct sock *dccp_v4_request_recv_sock(const struct sock *sk,
+ if (__inet_inherit_port(sk, newsk) < 0)
+ goto put_and_exit;
+ *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash));
+-
++ if (*own_req)
++ ireq->ireq_opt = NULL;
++ else
++ newinet->inet_opt = NULL;
+ return newsk;
+
+ exit_overflow:
+@@ -441,6 +443,7 @@ struct sock *dccp_v4_request_recv_sock(const struct sock *sk,
+ __NET_INC_STATS(sock_net(sk), LINUX_MIB_LISTENDROPS);
+ return NULL;
+ put_and_exit:
++ newinet->inet_opt = NULL;
+ inet_csk_prepare_forced_close(newsk);
+ dccp_done(newsk);
+ goto exit;
+@@ -492,7 +495,7 @@ static int dccp_v4_send_response(const struct sock *sk, struct request_sock *req
+ ireq->ir_rmt_addr);
+ err = ip_build_and_send_pkt(skb, sk, ireq->ir_loc_addr,
+ ireq->ir_rmt_addr,
+- ireq->opt);
++ ireq_opt_deref(ireq));
+ err = net_xmit_eval(err);
+ }
+
+@@ -548,7 +551,7 @@ static void dccp_v4_ctl_send_reset(const struct sock *sk, struct sk_buff *rxskb)
+ static void dccp_v4_reqsk_destructor(struct request_sock *req)
+ {
+ dccp_feat_list_purge(&dccp_rsk(req)->dreq_featneg);
+- kfree(inet_rsk(req)->opt);
++ kfree(rcu_dereference_protected(inet_rsk(req)->ireq_opt, 1));
+ }
+
+ void dccp_syn_ack_timeout(const struct request_sock *req)
+diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
+index 20bc9c56fca0..278b48d70bd9 100644
+--- a/net/dsa/dsa2.c
++++ b/net/dsa/dsa2.c
+@@ -496,14 +496,15 @@ static int dsa_cpu_parse(struct dsa_port *port, u32 index,
+ if (!ethernet)
+ return -EINVAL;
+ ethernet_dev = of_find_net_device_by_node(ethernet);
++ if (!ethernet_dev)
++ return -EPROBE_DEFER;
+ } else {
+ ethernet_dev = dsa_dev_to_net_device(ds->cd->netdev[index]);
++ if (!ethernet_dev)
++ return -EPROBE_DEFER;
+ dev_put(ethernet_dev);
+ }
+
+- if (!ethernet_dev)
+- return -EPROBE_DEFER;
+-
+ if (!dst->cpu_dp) {
+ dst->cpu_dp = port;
+ dst->cpu_dp->netdev = ethernet_dev;
+diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
+index 2ae8f54cb321..82178cc69c96 100644
+--- a/net/ipv4/cipso_ipv4.c
++++ b/net/ipv4/cipso_ipv4.c
+@@ -1951,7 +1951,7 @@ int cipso_v4_req_setattr(struct request_sock *req,
+ buf = NULL;
+
+ req_inet = inet_rsk(req);
+- opt = xchg(&req_inet->opt, opt);
++ opt = xchg((__force struct ip_options_rcu **)&req_inet->ireq_opt, opt);
+ if (opt)
+ kfree_rcu(opt, rcu);
+
+@@ -1973,11 +1973,13 @@ int cipso_v4_req_setattr(struct request_sock *req,
+ * values on failure.
+ *
+ */
+-static int cipso_v4_delopt(struct ip_options_rcu **opt_ptr)
++static int cipso_v4_delopt(struct ip_options_rcu __rcu **opt_ptr)
+ {
++ struct ip_options_rcu *opt = rcu_dereference_protected(*opt_ptr, 1);
+ int hdr_delta = 0;
+- struct ip_options_rcu *opt = *opt_ptr;
+
++ if (!opt || opt->opt.cipso == 0)
++ return 0;
+ if (opt->opt.srr || opt->opt.rr || opt->opt.ts || opt->opt.router_alert) {
+ u8 cipso_len;
+ u8 cipso_off;
+@@ -2039,14 +2041,10 @@ static int cipso_v4_delopt(struct ip_options_rcu **opt_ptr)
+ */
+ void cipso_v4_sock_delattr(struct sock *sk)
+ {
+- int hdr_delta;
+- struct ip_options_rcu *opt;
+ struct inet_sock *sk_inet;
++ int hdr_delta;
+
+ sk_inet = inet_sk(sk);
+- opt = rcu_dereference_protected(sk_inet->inet_opt, 1);
+- if (!opt || opt->opt.cipso == 0)
+- return;
+
+ hdr_delta = cipso_v4_delopt(&sk_inet->inet_opt);
+ if (sk_inet->is_icsk && hdr_delta > 0) {
+@@ -2066,15 +2064,7 @@ void cipso_v4_sock_delattr(struct sock *sk)
+ */
+ void cipso_v4_req_delattr(struct request_sock *req)
+ {
+- struct ip_options_rcu *opt;
+- struct inet_request_sock *req_inet;
+-
+- req_inet = inet_rsk(req);
+- opt = req_inet->opt;
+- if (!opt || opt->opt.cipso == 0)
+- return;
+-
+- cipso_v4_delopt(&req_inet->opt);
++ cipso_v4_delopt(&inet_rsk(req)->ireq_opt);
+ }
+
+ /**
+diff --git a/net/ipv4/gre_offload.c b/net/ipv4/gre_offload.c
+index d5cac99170b1..8c72034df28e 100644
+--- a/net/ipv4/gre_offload.c
++++ b/net/ipv4/gre_offload.c
+@@ -98,7 +98,7 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb,
+ greh = (struct gre_base_hdr *)skb_transport_header(skb);
+ pcsum = (__sum16 *)(greh + 1);
+
+- if (gso_partial) {
++ if (gso_partial && skb_is_gso(skb)) {
+ unsigned int partial_adj;
+
+ /* Adjust checksum to account for the fact that
+diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
+index 4089c013cb03..4438990cf65e 100644
+--- a/net/ipv4/inet_connection_sock.c
++++ b/net/ipv4/inet_connection_sock.c
+@@ -537,9 +537,11 @@ struct dst_entry *inet_csk_route_req(const struct sock *sk,
+ {
+ const struct inet_request_sock *ireq = inet_rsk(req);
+ struct net *net = read_pnet(&ireq->ireq_net);
+- struct ip_options_rcu *opt = ireq->opt;
++ struct ip_options_rcu *opt;
+ struct rtable *rt;
+
++ opt = ireq_opt_deref(ireq);
++
+ flowi4_init_output(fl4, ireq->ir_iif, ireq->ir_mark,
+ RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE,
+ sk->sk_protocol, inet_sk_flowi_flags(sk),
+@@ -573,10 +575,9 @@ struct dst_entry *inet_csk_route_child_sock(const struct sock *sk,
+ struct flowi4 *fl4;
+ struct rtable *rt;
+
++ opt = rcu_dereference(ireq->ireq_opt);
+ fl4 = &newinet->cork.fl.u.ip4;
+
+- rcu_read_lock();
+- opt = rcu_dereference(newinet->inet_opt);
+ flowi4_init_output(fl4, ireq->ir_iif, ireq->ir_mark,
+ RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE,
+ sk->sk_protocol, inet_sk_flowi_flags(sk),
+@@ -589,13 +590,11 @@ struct dst_entry *inet_csk_route_child_sock(const struct sock *sk,
+ goto no_route;
+ if (opt && opt->opt.is_strictroute && rt->rt_uses_gateway)
+ goto route_err;
+- rcu_read_unlock();
+ return &rt->dst;
+
+ route_err:
+ ip_rt_put(rt);
+ no_route:
+- rcu_read_unlock();
+ __IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES);
+ return NULL;
+ }
+diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
+index 2e3389d614d1..3eeecee0b21f 100644
+--- a/net/ipv4/inet_hashtables.c
++++ b/net/ipv4/inet_hashtables.c
+@@ -449,10 +449,7 @@ static int inet_reuseport_add_sock(struct sock *sk,
+ return reuseport_add_sock(sk, sk2);
+ }
+
+- /* Initial allocation may have already happened via setsockopt */
+- if (!rcu_access_pointer(sk->sk_reuseport_cb))
+- return reuseport_alloc(sk);
+- return 0;
++ return reuseport_alloc(sk);
+ }
+
+ int __inet_hash(struct sock *sk, struct sock *osk)
+diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
+index fb1ad22b5e29..cdd627355ed1 100644
+--- a/net/ipv4/ipip.c
++++ b/net/ipv4/ipip.c
+@@ -128,43 +128,68 @@ static struct rtnl_link_ops ipip_link_ops __read_mostly;
+
+ static int ipip_err(struct sk_buff *skb, u32 info)
+ {
+-
+-/* All the routers (except for Linux) return only
+- 8 bytes of packet payload. It means, that precise relaying of
+- ICMP in the real Internet is absolutely infeasible.
+- */
++ /* All the routers (except for Linux) return only
++ * 8 bytes of packet payload. It means, that precise relaying of
++ * ICMP in the real Internet is absolutely infeasible.
++ */
+ struct net *net = dev_net(skb->dev);
+ struct ip_tunnel_net *itn = net_generic(net, ipip_net_id);
+ const struct iphdr *iph = (const struct iphdr *)skb->data;
+- struct ip_tunnel *t;
+- int err;
+ const int type = icmp_hdr(skb)->type;
+ const int code = icmp_hdr(skb)->code;
++ struct ip_tunnel *t;
++ int err = 0;
++
++ switch (type) {
++ case ICMP_DEST_UNREACH:
++ switch (code) {
++ case ICMP_SR_FAILED:
++ /* Impossible event. */
++ goto out;
++ default:
++ /* All others are translated to HOST_UNREACH.
++ * rfc2003 contains "deep thoughts" about NET_UNREACH,
++ * I believe they are just ether pollution. --ANK
++ */
++ break;
++ }
++ break;
++
++ case ICMP_TIME_EXCEEDED:
++ if (code != ICMP_EXC_TTL)
++ goto out;
++ break;
++
++ case ICMP_REDIRECT:
++ break;
++
++ default:
++ goto out;
++ }
+
+- err = -ENOENT;
+ t = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY,
+ iph->daddr, iph->saddr, 0);
+- if (!t)
++ if (!t) {
++ err = -ENOENT;
+ goto out;
++ }
+
+ if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) {
+- ipv4_update_pmtu(skb, dev_net(skb->dev), info,
+- t->parms.link, 0, iph->protocol, 0);
+- err = 0;
++ ipv4_update_pmtu(skb, net, info, t->parms.link, 0,
++ iph->protocol, 0);
+ goto out;
+ }
+
+ if (type == ICMP_REDIRECT) {
+- ipv4_redirect(skb, dev_net(skb->dev), t->parms.link, 0,
+- iph->protocol, 0);
+- err = 0;
++ ipv4_redirect(skb, net, t->parms.link, 0, iph->protocol, 0);
+ goto out;
+ }
+
+- if (t->parms.iph.daddr == 0)
++ if (t->parms.iph.daddr == 0) {
++ err = -ENOENT;
+ goto out;
++ }
+
+- err = 0;
+ if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
+ goto out;
+
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index c5aa25be7108..72afa4cfb022 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -2507,7 +2507,7 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or
+ struct rtable *ort = (struct rtable *) dst_orig;
+ struct rtable *rt;
+
+- rt = dst_alloc(&ipv4_dst_blackhole_ops, NULL, 1, DST_OBSOLETE_NONE, 0);
++ rt = dst_alloc(&ipv4_dst_blackhole_ops, NULL, 1, DST_OBSOLETE_DEAD, 0);
+ if (rt) {
+ struct dst_entry *new = &rt->dst;
+
+diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
+index 03ad8778c395..0f914fda5bf3 100644
+--- a/net/ipv4/syncookies.c
++++ b/net/ipv4/syncookies.c
+@@ -355,7 +355,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
+ /* We throwed the options of the initial SYN away, so we hope
+ * the ACK carries the same options again (see RFC1122 4.2.3.8)
+ */
+- ireq->opt = tcp_v4_save_options(skb);
++ RCU_INIT_POINTER(ireq->ireq_opt, tcp_v4_save_options(skb));
+
+ if (security_inet_conn_request(sk, skb, req)) {
+ reqsk_free(req);
+diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
+index bab7f0493098..e92e5dbcb3d6 100644
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -6235,7 +6235,7 @@ struct request_sock *inet_reqsk_alloc(const struct request_sock_ops *ops,
+ struct inet_request_sock *ireq = inet_rsk(req);
+
+ kmemcheck_annotate_bitfield(ireq, flags);
+- ireq->opt = NULL;
++ ireq->ireq_opt = NULL;
+ #if IS_ENABLED(CONFIG_IPV6)
+ ireq->pktopts = NULL;
+ #endif
+diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
+index b1441bc8192f..78835f681538 100644
+--- a/net/ipv4/tcp_ipv4.c
++++ b/net/ipv4/tcp_ipv4.c
+@@ -878,7 +878,7 @@ static int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst,
+
+ err = ip_build_and_send_pkt(skb, sk, ireq->ir_loc_addr,
+ ireq->ir_rmt_addr,
+- ireq->opt);
++ ireq_opt_deref(ireq));
+ err = net_xmit_eval(err);
+ }
+
+@@ -890,7 +890,7 @@ static int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst,
+ */
+ static void tcp_v4_reqsk_destructor(struct request_sock *req)
+ {
+- kfree(inet_rsk(req)->opt);
++ kfree(rcu_dereference_protected(inet_rsk(req)->ireq_opt, 1));
+ }
+
+ #ifdef CONFIG_TCP_MD5SIG
+@@ -1269,7 +1269,7 @@ static void tcp_v4_init_req(struct request_sock *req,
+
+ sk_rcv_saddr_set(req_to_sk(req), ip_hdr(skb)->daddr);
+ sk_daddr_set(req_to_sk(req), ip_hdr(skb)->saddr);
+- ireq->opt = tcp_v4_save_options(skb);
++ RCU_INIT_POINTER(ireq->ireq_opt, tcp_v4_save_options(skb));
+ }
+
+ static struct dst_entry *tcp_v4_route_req(const struct sock *sk,
+@@ -1356,10 +1356,9 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
+ sk_daddr_set(newsk, ireq->ir_rmt_addr);
+ sk_rcv_saddr_set(newsk, ireq->ir_loc_addr);
+ newsk->sk_bound_dev_if = ireq->ir_iif;
+- newinet->inet_saddr = ireq->ir_loc_addr;
+- inet_opt = ireq->opt;
+- rcu_assign_pointer(newinet->inet_opt, inet_opt);
+- ireq->opt = NULL;
++ newinet->inet_saddr = ireq->ir_loc_addr;
++ inet_opt = rcu_dereference(ireq->ireq_opt);
++ RCU_INIT_POINTER(newinet->inet_opt, inet_opt);
+ newinet->mc_index = inet_iif(skb);
+ newinet->mc_ttl = ip_hdr(skb)->ttl;
+ newinet->rcv_tos = ip_hdr(skb)->tos;
+@@ -1404,9 +1403,12 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
+ if (__inet_inherit_port(sk, newsk) < 0)
+ goto put_and_exit;
+ *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash));
+- if (*own_req)
++ if (likely(*own_req)) {
+ tcp_move_syn(newtp, req);
+-
++ ireq->ireq_opt = NULL;
++ } else {
++ newinet->inet_opt = NULL;
++ }
+ return newsk;
+
+ exit_overflow:
+@@ -1417,6 +1419,7 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
+ tcp_listendrop(sk);
+ return NULL;
+ put_and_exit:
++ newinet->inet_opt = NULL;
+ inet_csk_prepare_forced_close(newsk);
+ tcp_done(newsk);
+ goto exit;
+diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
+index 40f7c8ee9ba6..58587b0e2b5d 100644
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -2094,6 +2094,7 @@ static int tcp_mtu_probe(struct sock *sk)
+ nskb->ip_summed = skb->ip_summed;
+
+ tcp_insert_write_queue_before(nskb, skb, sk);
++ tcp_highest_sack_replace(sk, skb, nskb);
+
+ len = 0;
+ tcp_for_write_queue_from_safe(skb, next, sk) {
+@@ -2271,6 +2272,7 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
+
+ sent_pkts = 0;
+
++ tcp_mstamp_refresh(tp);
+ if (!push_one) {
+ /* Do MTU probing. */
+ result = tcp_mtu_probe(sk);
+@@ -2282,7 +2284,6 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
+ }
+
+ max_segs = tcp_tso_segs(sk, mss_now);
+- tcp_mstamp_refresh(tp);
+ while ((skb = tcp_send_head(sk))) {
+ unsigned int limit;
+
+@@ -2694,7 +2695,7 @@ static bool tcp_collapse_retrans(struct sock *sk, struct sk_buff *skb)
+ else if (!skb_shift(skb, next_skb, next_skb_size))
+ return false;
+ }
+- tcp_highest_sack_combine(sk, next_skb, skb);
++ tcp_highest_sack_replace(sk, next_skb, skb);
+
+ tcp_unlink_write_queue(next_skb, sk);
+
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index 84861d71face..f9e1bcfb6e2d 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -231,10 +231,7 @@ static int udp_reuseport_add_sock(struct sock *sk, struct udp_hslot *hslot)
+ }
+ }
+
+- /* Initial allocation may have already happened via setsockopt */
+- if (!rcu_access_pointer(sk->sk_reuseport_cb))
+- return reuseport_alloc(sk);
+- return 0;
++ return reuseport_alloc(sk);
+ }
+
+ /**
+diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
+index 0932c85b42af..6401574cd638 100644
+--- a/net/ipv4/udp_offload.c
++++ b/net/ipv4/udp_offload.c
+@@ -122,7 +122,7 @@ static struct sk_buff *__skb_udp_tunnel_segment(struct sk_buff *skb,
+ * will be using a length value equal to only one MSS sized
+ * segment instead of the entire frame.
+ */
+- if (gso_partial) {
++ if (gso_partial && skb_is_gso(skb)) {
+ uh->len = htons(skb_shinfo(skb)->gso_size +
+ SKB_GSO_CB(skb)->data_offset +
+ skb->head - (unsigned char *)uh);
+diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
+index ba757c28a301..bdc93e51427d 100644
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -3367,6 +3367,7 @@ static void addrconf_permanent_addr(struct net_device *dev)
+ if ((ifp->flags & IFA_F_PERMANENT) &&
+ fixup_permanent_addr(idev, ifp) < 0) {
+ write_unlock_bh(&idev->lock);
++ in6_ifa_hold(ifp);
+ ipv6_del_addr(ifp);
+ write_lock_bh(&idev->lock);
+
+diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
+index 8081bafe441b..15535ee327c5 100644
+--- a/net/ipv6/ip6_flowlabel.c
++++ b/net/ipv6/ip6_flowlabel.c
+@@ -315,6 +315,7 @@ struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions *opt_space,
+ }
+ opt_space->dst1opt = fopt->dst1opt;
+ opt_space->opt_flen = fopt->opt_flen;
++ opt_space->tot_len = fopt->tot_len;
+ return opt_space;
+ }
+ EXPORT_SYMBOL_GPL(fl6_merge_options);
+diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
+index 1602b491b281..59c121b932ac 100644
+--- a/net/ipv6/ip6_gre.c
++++ b/net/ipv6/ip6_gre.c
+@@ -408,13 +408,16 @@ static void ip6gre_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
+ case ICMPV6_DEST_UNREACH:
+ net_dbg_ratelimited("%s: Path to destination invalid or inactive!\n",
+ t->parms.name);
+- break;
++ if (code != ICMPV6_PORT_UNREACH)
++ break;
++ return;
+ case ICMPV6_TIME_EXCEED:
+ if (code == ICMPV6_EXC_HOPLIMIT) {
+ net_dbg_ratelimited("%s: Too small hop limit or routing loop in tunnel!\n",
+ t->parms.name);
++ break;
+ }
+- break;
++ return;
+ case ICMPV6_PARAMPROB:
+ teli = 0;
+ if (code == ICMPV6_HDR_FIELD)
+@@ -430,7 +433,7 @@ static void ip6gre_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
+ net_dbg_ratelimited("%s: Recipient unable to parse tunneled packet!\n",
+ t->parms.name);
+ }
+- break;
++ return;
+ case ICMPV6_PKT_TOOBIG:
+ mtu = be32_to_cpu(info) - offset - t->tun_hlen;
+ if (t->dev->type == ARPHRD_ETHER)
+@@ -438,7 +441,7 @@ static void ip6gre_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
+ if (mtu < IPV6_MIN_MTU)
+ mtu = IPV6_MIN_MTU;
+ t->dev->mtu = mtu;
+- break;
++ return;
+ }
+
+ if (time_before(jiffies, t->err_time + IP6TUNNEL_ERR_TIMEO))
+@@ -500,8 +503,8 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb,
+ __u32 *pmtu, __be16 proto)
+ {
+ struct ip6_tnl *tunnel = netdev_priv(dev);
+- __be16 protocol = (dev->type == ARPHRD_ETHER) ?
+- htons(ETH_P_TEB) : proto;
++ struct dst_entry *dst = skb_dst(skb);
++ __be16 protocol;
+
+ if (dev->type == ARPHRD_ETHER)
+ IPCB(skb)->flags = 0;
+@@ -515,9 +518,14 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb,
+ tunnel->o_seqno++;
+
+ /* Push GRE header. */
++ protocol = (dev->type == ARPHRD_ETHER) ? htons(ETH_P_TEB) : proto;
+ gre_build_header(skb, tunnel->tun_hlen, tunnel->parms.o_flags,
+ protocol, tunnel->parms.o_key, htonl(tunnel->o_seqno));
+
++ /* TooBig packet may have updated dst->dev's mtu */
++ if (dst && dst_mtu(dst) > dst->dev->mtu)
++ dst->ops->update_pmtu(dst, NULL, skb, dst->dev->mtu);
++
+ return ip6_tnl_xmit(skb, dev, dsfield, fl6, encap_limit, pmtu,
+ NEXTHDR_GRE);
+ }
+diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c
+index cdb3728faca7..4a87f9428ca5 100644
+--- a/net/ipv6/ip6_offload.c
++++ b/net/ipv6/ip6_offload.c
+@@ -105,7 +105,7 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb,
+
+ for (skb = segs; skb; skb = skb->next) {
+ ipv6h = (struct ipv6hdr *)(skb_mac_header(skb) + nhoff);
+- if (gso_partial)
++ if (gso_partial && skb_is_gso(skb))
+ payload_len = skb_shinfo(skb)->gso_size +
+ SKB_GSO_CB(skb)->data_offset +
+ skb->head - (unsigned char *)(ipv6h + 1);
+diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
+index 2dfe50d8d609..3ce9ab29bd37 100644
+--- a/net/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -1224,11 +1224,11 @@ static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork,
+ if (WARN_ON(v6_cork->opt))
+ return -EINVAL;
+
+- v6_cork->opt = kzalloc(opt->tot_len, sk->sk_allocation);
++ v6_cork->opt = kzalloc(sizeof(*opt), sk->sk_allocation);
+ if (unlikely(!v6_cork->opt))
+ return -ENOBUFS;
+
+- v6_cork->opt->tot_len = opt->tot_len;
++ v6_cork->opt->tot_len = sizeof(*opt);
+ v6_cork->opt->opt_flen = opt->opt_flen;
+ v6_cork->opt->opt_nflen = opt->opt_nflen;
+
+diff --git a/net/ipv6/route.c b/net/ipv6/route.c
+index 2d0e7798c793..44eebe738c09 100644
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -1251,7 +1251,7 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori
+ struct dst_entry *new = NULL;
+
+ rt = dst_alloc(&ip6_dst_blackhole_ops, loopback_dev, 1,
+- DST_OBSOLETE_NONE, 0);
++ DST_OBSOLETE_DEAD, 0);
+ if (rt) {
+ rt6_info_init(rt);
+
+diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
+index f0edb7209079..412c513d69b3 100644
+--- a/net/l2tp/l2tp_ppp.c
++++ b/net/l2tp/l2tp_ppp.c
+@@ -584,6 +584,7 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
+ u32 tunnel_id, peer_tunnel_id;
+ u32 session_id, peer_session_id;
+ bool drop_refcnt = false;
++ bool drop_tunnel = false;
+ int ver = 2;
+ int fd;
+
+@@ -652,7 +653,9 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
+ if (tunnel_id == 0)
+ goto end;
+
+- tunnel = l2tp_tunnel_find(sock_net(sk), tunnel_id);
++ tunnel = l2tp_tunnel_get(sock_net(sk), tunnel_id);
++ if (tunnel)
++ drop_tunnel = true;
+
+ /* Special case: create tunnel context if session_id and
+ * peer_session_id is 0. Otherwise look up tunnel using supplied
+@@ -781,6 +784,8 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
+ end:
+ if (drop_refcnt)
+ l2tp_session_dec_refcount(session);
++ if (drop_tunnel)
++ l2tp_tunnel_dec_refcount(tunnel);
+ release_sock(sk);
+
+ return error;
+@@ -993,6 +998,9 @@ static int pppol2tp_session_ioctl(struct l2tp_session *session,
+ session->name, cmd, arg);
+
+ sk = ps->sock;
++ if (!sk)
++ return -EBADR;
++
+ sock_hold(sk);
+
+ switch (cmd) {
+diff --git a/net/mac80211/key.c b/net/mac80211/key.c
+index a98fc2b5e0dc..938049395f90 100644
+--- a/net/mac80211/key.c
++++ b/net/mac80211/key.c
+@@ -4,7 +4,7 @@
+ * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
+ * Copyright 2007-2008 Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2013-2014 Intel Mobile Communications GmbH
+- * Copyright 2015 Intel Deutschland GmbH
++ * Copyright 2015-2017 Intel Deutschland GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+@@ -19,6 +19,7 @@
+ #include <linux/slab.h>
+ #include <linux/export.h>
+ #include <net/mac80211.h>
++#include <crypto/algapi.h>
+ #include <asm/unaligned.h>
+ #include "ieee80211_i.h"
+ #include "driver-ops.h"
+@@ -609,6 +610,39 @@ void ieee80211_key_free_unused(struct ieee80211_key *key)
+ ieee80211_key_free_common(key);
+ }
+
++static bool ieee80211_key_identical(struct ieee80211_sub_if_data *sdata,
++ struct ieee80211_key *old,
++ struct ieee80211_key *new)
++{
++ u8 tkip_old[WLAN_KEY_LEN_TKIP], tkip_new[WLAN_KEY_LEN_TKIP];
++ u8 *tk_old, *tk_new;
++
++ if (!old || new->conf.keylen != old->conf.keylen)
++ return false;
++
++ tk_old = old->conf.key;
++ tk_new = new->conf.key;
++
++ /*
++ * In station mode, don't compare the TX MIC key, as it's never used
++ * and offloaded rekeying may not care to send it to the host. This
++ * is the case in iwlwifi, for example.
++ */
++ if (sdata->vif.type == NL80211_IFTYPE_STATION &&
++ new->conf.cipher == WLAN_CIPHER_SUITE_TKIP &&
++ new->conf.keylen == WLAN_KEY_LEN_TKIP &&
++ !(new->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
++ memcpy(tkip_old, tk_old, WLAN_KEY_LEN_TKIP);
++ memcpy(tkip_new, tk_new, WLAN_KEY_LEN_TKIP);
++ memset(tkip_old + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY, 0, 8);
++ memset(tkip_new + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY, 0, 8);
++ tk_old = tkip_old;
++ tk_new = tkip_new;
++ }
++
++ return !crypto_memneq(tk_old, tk_new, new->conf.keylen);
++}
++
+ int ieee80211_key_link(struct ieee80211_key *key,
+ struct ieee80211_sub_if_data *sdata,
+ struct sta_info *sta)
+@@ -620,9 +654,6 @@ int ieee80211_key_link(struct ieee80211_key *key,
+
+ pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE;
+ idx = key->conf.keyidx;
+- key->local = sdata->local;
+- key->sdata = sdata;
+- key->sta = sta;
+
+ mutex_lock(&sdata->local->key_mtx);
+
+@@ -633,6 +664,20 @@ int ieee80211_key_link(struct ieee80211_key *key,
+ else
+ old_key = key_mtx_dereference(sdata->local, sdata->keys[idx]);
+
++ /*
++ * Silently accept key re-installation without really installing the
++ * new version of the key to avoid nonce reuse or replay issues.
++ */
++ if (ieee80211_key_identical(sdata, old_key, key)) {
++ ieee80211_key_free_unused(key);
++ ret = 0;
++ goto out;
++ }
++
++ key->local = sdata->local;
++ key->sdata = sdata;
++ key->sta = sta;
++
+ increment_tailroom_need_count(sdata);
+
+ ieee80211_key_replace(sdata, sta, pairwise, old_key, key);
+@@ -648,6 +693,7 @@ int ieee80211_key_link(struct ieee80211_key *key,
+ ret = 0;
+ }
+
++ out:
+ mutex_unlock(&sdata->local->key_mtx);
+
+ return ret;
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index 7e794ad50cb0..09c8dbbd2d70 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -2258,16 +2258,17 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
+ cb->min_dump_alloc = control->min_dump_alloc;
+ cb->skb = skb;
+
++ if (cb->start) {
++ ret = cb->start(cb);
++ if (ret)
++ goto error_unlock;
++ }
++
+ nlk->cb_running = true;
+
+ mutex_unlock(nlk->cb_mutex);
+
+- ret = 0;
+- if (cb->start)
+- ret = cb->start(cb);
+-
+- if (!ret)
+- ret = netlink_dump(sk);
++ ret = netlink_dump(sk);
+
+ sock_put(sk);
+
+@@ -2298,6 +2299,7 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err,
+ size_t tlvlen = 0;
+ struct netlink_sock *nlk = nlk_sk(NETLINK_CB(in_skb).sk);
+ unsigned int flags = 0;
++ bool nlk_has_extack = nlk->flags & NETLINK_F_EXT_ACK;
+
+ /* Error messages get the original request appened, unless the user
+ * requests to cap the error message, and get extra error data if
+@@ -2308,7 +2310,7 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err,
+ payload += nlmsg_len(nlh);
+ else
+ flags |= NLM_F_CAPPED;
+- if (nlk->flags & NETLINK_F_EXT_ACK && extack) {
++ if (nlk_has_extack && extack) {
+ if (extack->_msg)
+ tlvlen += nla_total_size(strlen(extack->_msg) + 1);
+ if (extack->bad_attr)
+@@ -2317,8 +2319,7 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err,
+ } else {
+ flags |= NLM_F_CAPPED;
+
+- if (nlk->flags & NETLINK_F_EXT_ACK &&
+- extack && extack->cookie_len)
++ if (nlk_has_extack && extack && extack->cookie_len)
+ tlvlen += nla_total_size(extack->cookie_len);
+ }
+
+@@ -2346,7 +2347,7 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err,
+ errmsg->error = err;
+ memcpy(&errmsg->msg, nlh, payload > sizeof(*errmsg) ? nlh->nlmsg_len : sizeof(*nlh));
+
+- if (nlk->flags & NETLINK_F_EXT_ACK && extack) {
++ if (nlk_has_extack && extack) {
+ if (err) {
+ if (extack->_msg)
+ WARN_ON(nla_put_string(skb, NLMSGERR_ATTR_MSG,
+diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
+index 29d7b7e5b128..b0c8fee3d53d 100644
+--- a/net/packet/af_packet.c
++++ b/net/packet/af_packet.c
+@@ -1771,7 +1771,7 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags)
+
+ out:
+ if (err && rollover) {
+- kfree(rollover);
++ kfree_rcu(rollover, rcu);
+ po->rollover = NULL;
+ }
+ mutex_unlock(&fanout_mutex);
+@@ -1798,8 +1798,10 @@ static struct packet_fanout *fanout_release(struct sock *sk)
+ else
+ f = NULL;
+
+- if (po->rollover)
++ if (po->rollover) {
+ kfree_rcu(po->rollover, rcu);
++ po->rollover = NULL;
++ }
+ }
+ mutex_unlock(&fanout_mutex);
+
+@@ -3853,6 +3855,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
+ void *data = &val;
+ union tpacket_stats_u st;
+ struct tpacket_rollover_stats rstats;
++ struct packet_rollover *rollover;
+
+ if (level != SOL_PACKET)
+ return -ENOPROTOOPT;
+@@ -3931,13 +3934,18 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
+ 0);
+ break;
+ case PACKET_ROLLOVER_STATS:
+- if (!po->rollover)
++ rcu_read_lock();
++ rollover = rcu_dereference(po->rollover);
++ if (rollover) {
++ rstats.tp_all = atomic_long_read(&rollover->num);
++ rstats.tp_huge = atomic_long_read(&rollover->num_huge);
++ rstats.tp_failed = atomic_long_read(&rollover->num_failed);
++ data = &rstats;
++ lv = sizeof(rstats);
++ }
++ rcu_read_unlock();
++ if (!rollover)
+ return -EINVAL;
+- rstats.tp_all = atomic_long_read(&po->rollover->num);
+- rstats.tp_huge = atomic_long_read(&po->rollover->num_huge);
+- rstats.tp_failed = atomic_long_read(&po->rollover->num_failed);
+- data = &rstats;
+- lv = sizeof(rstats);
+ break;
+ case PACKET_TX_HAS_OFF:
+ val = po->tp_tx_has_off;
+diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
+index 4fb5a3222d0d..7935db0d787c 100644
+--- a/net/sched/sch_api.c
++++ b/net/sched/sch_api.c
+@@ -307,6 +307,8 @@ struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle)
+ {
+ struct Qdisc *q;
+
++ if (!handle)
++ return NULL;
+ q = qdisc_match_from_root(dev->qdisc, handle);
+ if (q)
+ goto out;
+diff --git a/net/sctp/input.c b/net/sctp/input.c
+index 41eb2ec10460..1678d9ea7740 100644
+--- a/net/sctp/input.c
++++ b/net/sctp/input.c
+@@ -421,7 +421,7 @@ void sctp_icmp_redirect(struct sock *sk, struct sctp_transport *t,
+ {
+ struct dst_entry *dst;
+
+- if (!t)
++ if (sock_owned_by_user(sk) || !t)
+ return;
+ dst = sctp_transport_dst_check(t);
+ if (dst)
+diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
+index a4b6ffb61495..1344e3a411ae 100644
+--- a/net/sctp/ipv6.c
++++ b/net/sctp/ipv6.c
+@@ -882,8 +882,10 @@ static int sctp_inet6_bind_verify(struct sctp_sock *opt, union sctp_addr *addr)
+ net = sock_net(&opt->inet.sk);
+ rcu_read_lock();
+ dev = dev_get_by_index_rcu(net, addr->v6.sin6_scope_id);
+- if (!dev ||
+- !ipv6_chk_addr(net, &addr->v6.sin6_addr, dev, 0)) {
++ if (!dev || !(opt->inet.freebind ||
++ net->ipv6.sysctl.ip_nonlocal_bind ||
++ ipv6_chk_addr(net, &addr->v6.sin6_addr,
++ dev, 0))) {
+ rcu_read_unlock();
+ return 0;
+ }
+diff --git a/net/sctp/socket.c b/net/sctp/socket.c
+index 8d760863bc41..3d79085eb4e0 100644
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -169,6 +169,36 @@ static inline void sctp_set_owner_w(struct sctp_chunk *chunk)
+ sk_mem_charge(sk, chunk->skb->truesize);
+ }
+
++static void sctp_clear_owner_w(struct sctp_chunk *chunk)
++{
++ skb_orphan(chunk->skb);
++}
++
++static void sctp_for_each_tx_datachunk(struct sctp_association *asoc,
++ void (*cb)(struct sctp_chunk *))
++
++{
++ struct sctp_outq *q = &asoc->outqueue;
++ struct sctp_transport *t;
++ struct sctp_chunk *chunk;
++
++ list_for_each_entry(t, &asoc->peer.transport_addr_list, transports)
++ list_for_each_entry(chunk, &t->transmitted, transmitted_list)
++ cb(chunk);
++
++ list_for_each_entry(chunk, &q->retransmit, list)
++ cb(chunk);
++
++ list_for_each_entry(chunk, &q->sacked, list)
++ cb(chunk);
++
++ list_for_each_entry(chunk, &q->abandoned, list)
++ cb(chunk);
++
++ list_for_each_entry(chunk, &q->out_chunk_list, list)
++ cb(chunk);
++}
++
+ /* Verify that this is a valid address. */
+ static inline int sctp_verify_addr(struct sock *sk, union sctp_addr *addr,
+ int len)
+@@ -8196,7 +8226,9 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
+ * paths won't try to lock it and then oldsk.
+ */
+ lock_sock_nested(newsk, SINGLE_DEPTH_NESTING);
++ sctp_for_each_tx_datachunk(assoc, sctp_clear_owner_w);
+ sctp_assoc_migrate(assoc, newsk);
++ sctp_for_each_tx_datachunk(assoc, sctp_set_owner_w);
+
+ /* If the association on the newsk is already closed before accept()
+ * is called, set RCV_SHUTDOWN flag.
+diff --git a/net/unix/diag.c b/net/unix/diag.c
+index 4d9679701a6d..384c84e83462 100644
+--- a/net/unix/diag.c
++++ b/net/unix/diag.c
+@@ -257,6 +257,8 @@ static int unix_diag_get_exact(struct sk_buff *in_skb,
+ err = -ENOENT;
+ if (sk == NULL)
+ goto out_nosk;
++ if (!net_eq(sock_net(sk), net))
++ goto out;
+
+ err = sock_diag_check_cookie(sk, req->udiag_cookie);
+ if (err)