From c6be62a5ac77b9b392799f903ade32089da0edec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ertu=C4=9Frul=20Erata?= Date: Sat, 12 Dec 2015 19:13:36 +0200 Subject: [PATCH] works for kernel-4.3.2 --- .../kernel/files/patches/linux/patch-4.3.2.xz | Bin 0 -> 39640 bytes ...nore-to-stop-git-nagging-about-x509_.patch | 49 + ...ix-an-unwanted-master-inheritance-v2.patch | 163 + ...from-wait_ioctl-to-i915_wait_request.patch | 35 + .../files/patches/mageia/net_43.mbox.patch | 4174 +++++++++++++++++ ...-1-fix-bug-in-vdsomunge-swab32-macro.patch | 35 - ...-on-non-arphrd_ether-enslave-failure.patch | 44 - ..._inc_stats_bh-in-preemptible-context.patch | 75 - ...bh-when-changing-ip-local-port-range.patch | 66 - ...-not-remove-local-route-on-link-down.patch | 120 - ...ate-rtnh_f_linkdown-flag-on-up-event.patch | 62 - ...when-we-fail-to-initialize-inet6_dev.patch | 32 - ...-null-deref-in-inet_ctl_sock_destroy.patch | 33 - ...t-software-reset-ephy-after-power-on.patch | 91 - ...stable-net-fix-a-race-in-dst_release.patch | 34 - .../stable-net-fix-prefsrc-lookups.patch | 55 - ...packet-race-condition-in-packet_bind.patch | 231 - ...or-hp-lt4112-lte-hspa-gobi-4g-module.patch | 55 - ...push-partner-queue-for-skb-xmit_more.patch | 137 - ...t-fix-sit0-percpu-double-allocations.patch | 96 - ...ac-correctly-report-ptp-capabilities.patch | 39 - ...ng-name_distr-and-link_proto-buffers.patch | 51 - ...n_dst-fix-potential-null-dereference.patch | 41 - ...al-add-sierra-wireless-mc74xx-em74xx.patch | 34 - ...op-in-microcode-when-AC-is-delivered.patch | 93 - kernel/kernel/pspec.xml | 41 +- 26 files changed, 4439 insertions(+), 1447 deletions(-) create mode 100644 kernel/kernel/files/patches/linux/patch-4.3.2.xz create mode 100644 kernel/kernel/files/patches/mageia/certs-add-.gitignore-to-stop-git-nagging-about-x509_.patch create mode 100644 kernel/kernel/files/patches/mageia/gpu-drm-Fix-an-unwanted-master-inheritance-v2.patch create mode 100644 kernel/kernel/files/patches/mageia/gpu-drm-i915-Fix-RPS-pointer-passed-from-wait_ioctl-to-i915_wait_request.patch create mode 100644 kernel/kernel/files/patches/mageia/net_43.mbox.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-arm-8449-1-fix-bug-in-vdsomunge-swab32-macro.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-bonding-fix-panic-on-non-arphrd_ether-enslave-failure.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-ipmr-fix-possible-race-resulting-from-improper-usage-of-ip_inc_stats_bh-in-preemptible-context.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-ipv4-disable-bh-when-changing-ip-local-port-range.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-ipv4-fix-to-not-remove-local-route-on-link-down.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-ipv4-update-rtnh_f_linkdown-flag-on-up-event.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-ipv6-clean-up-dev_snmp6-proc-entry-when-we-fail-to-initialize-inet6_dev.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-net-avoid-null-deref-in-inet_ctl_sock_destroy.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-net-bcmgenet-software-reset-ephy-after-power-on.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-net-fix-a-race-in-dst_release.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-net-fix-prefsrc-lookups.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-packet-race-condition-in-packet_bind.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-qmi_wwan-fix-entry-for-hp-lt4112-lte-hspa-gobi-4g-module.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-sfc-push-partner-queue-for-skb-xmit_more.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-sit-fix-sit0-percpu-double-allocations.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-stmmac-correctly-report-ptp-capabilities.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-tipc-linearize-arriving-name_distr-and-link_proto-buffers.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-tun_dst-fix-potential-null-dereference.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-usb-qcserial-add-sierra-wireless-mc74xx-em74xx.patch delete mode 100644 kernel/kernel/files/patches/mageia/x86-KVM-x86-work-around-infinite-loop-in-microcode-when-AC-is-delivered.patch diff --git a/kernel/kernel/files/patches/linux/patch-4.3.2.xz b/kernel/kernel/files/patches/linux/patch-4.3.2.xz new file mode 100644 index 0000000000000000000000000000000000000000..32f9f186341e8c23e9fe2fb4ff56772fa9f3b1a9 GIT binary patch literal 39640 zcmV(fK>EM^H+ooF000E$*0e?f03iV!0000G&sfajMYWojT>vr~NeROI5q(hJ3QtGS z!4;|pXZW)T&B<2$p4y*yrKEu+nE=5mrU8s@oT4;ZCWV>l=eF;2yjHfQ1}E%XAFHF| zYE#Vu$6gs4az`Hz^q8^jT?2J0P##?wZxxUvrnkRU>9XSP|GwDLKj=@ZQjzd;F=t45 zR$?#UER8y^)XTfYyhTO%=wYnwy2;(maHg{S`4Bb*7kI_;3^2o)rk?fjSiO7D?r<5ClR*#3x_CTbNT-d;0LD3fovX|CK+v$(lK$%96Y^s$Txtqvgn5t&Ud`8z92=?h5pvizD$~C)8C$Tzu=N;y|6@LxmeSnLULc+ z)J7%u#$#KlGNezarSP!lBxY3+ev-UpIk{f{8*7AYF}K5?+BMaRS3H zvyRuqFSP5anD@m>|9AW#_orsqKX9KazcsGt7|*AeT&#G6TF(Er2KQ(&X0FFp=sp

x@YzJ+AJq3S;;%;Iy*27j$$bw-xB1 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 literal 0 HcmV?d00001 diff --git a/kernel/kernel/files/patches/mageia/certs-add-.gitignore-to-stop-git-nagging-about-x509_.patch b/kernel/kernel/files/patches/mageia/certs-add-.gitignore-to-stop-git-nagging-about-x509_.patch new file mode 100644 index 00000000..8070e3b7 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/certs-add-.gitignore-to-stop-git-nagging-about-x509_.patch @@ -0,0 +1,49 @@ +From 48dbc164b40dd9195dea8cd966e394819e420b64 Mon Sep 17 00:00:00 2001 +From: Paul Gortmaker +Date: Wed, 21 Oct 2015 14:04:47 +0100 +Subject: [PATCH] certs: add .gitignore to stop git nagging about + x509_certificate_list + +Currently we see this in "git status" if we build in the source dir: + +Untracked files: + (use "git add ..." to include in what will be committed) + + certs/x509_certificate_list + +It looks like it used to live in kernel/ so we squash that .gitignore +entry at the same time. I didn't bother to dig through git history to +see when it moved, since it is just a minor annoyance at most. + +Cc: David Woodhouse +Cc: keyrings@linux-nfs.org +Signed-off-by: Paul Gortmaker +Signed-off-by: David Howells +--- + certs/.gitignore | 4 ++++ + kernel/.gitignore | 1 - + 2 files changed, 4 insertions(+), 1 deletion(-) + create mode 100644 certs/.gitignore + +diff --git a/certs/.gitignore b/certs/.gitignore +new file mode 100644 +index 0000000..f51aea4 +--- /dev/null ++++ b/certs/.gitignore +@@ -0,0 +1,4 @@ ++# ++# Generated files ++# ++x509_certificate_list +diff --git a/kernel/.gitignore b/kernel/.gitignore +index 790d83c..b3097bd 100644 +--- a/kernel/.gitignore ++++ b/kernel/.gitignore +@@ -5,4 +5,3 @@ config_data.h + config_data.gz + timeconst.h + hz.bc +-x509_certificate_list +-- +2.6.4 + diff --git a/kernel/kernel/files/patches/mageia/gpu-drm-Fix-an-unwanted-master-inheritance-v2.patch b/kernel/kernel/files/patches/mageia/gpu-drm-Fix-an-unwanted-master-inheritance-v2.patch new file mode 100644 index 00000000..a4036782 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/gpu-drm-Fix-an-unwanted-master-inheritance-v2.patch @@ -0,0 +1,163 @@ +From a0af2e538c80f3e47f1d6ddf120a153ad909e8ad Mon Sep 17 00:00:00 2001 +From: Thomas Hellstrom +Date: Wed, 2 Dec 2015 09:24:46 -0800 +Subject: drm: Fix an unwanted master inheritance v2 + +A client calling drmSetMaster() using a file descriptor that was opened +when another client was master would inherit the latter client's master +object and all its authenticated clients. + +This is unwanted behaviour, and when this happens, instead allocate a +brand new master object for the client calling drmSetMaster(). + +Fixes a BUG() throw in vmw_master_set(). + +Cc: +Signed-off-by: Thomas Hellstrom +Signed-off-by: Dave Airlie + +diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c +index 9362609..7dd6728 100644 +--- a/drivers/gpu/drm/drm_drv.c ++++ b/drivers/gpu/drm/drm_drv.c +@@ -160,6 +160,11 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data, + goto out_unlock; + } + ++ if (!file_priv->allowed_master) { ++ ret = drm_new_set_master(dev, file_priv); ++ goto out_unlock; ++ } ++ + file_priv->minor->master = drm_master_get(file_priv->master); + file_priv->is_master = 1; + if (dev->driver->master_set) { +diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c +index c59ce4d..6b5625e 100644 +--- a/drivers/gpu/drm/drm_fops.c ++++ b/drivers/gpu/drm/drm_fops.c +@@ -126,6 +126,60 @@ static int drm_cpu_valid(void) + } + + /** ++ * drm_new_set_master - Allocate a new master object and become master for the ++ * associated master realm. ++ * ++ * @dev: The associated device. ++ * @fpriv: File private identifying the client. ++ * ++ * This function must be called with dev::struct_mutex held. ++ * Returns negative error code on failure. Zero on success. ++ */ ++int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv) ++{ ++ struct drm_master *old_master; ++ int ret; ++ ++ lockdep_assert_held_once(&dev->master_mutex); ++ ++ /* create a new master */ ++ fpriv->minor->master = drm_master_create(fpriv->minor); ++ if (!fpriv->minor->master) ++ return -ENOMEM; ++ ++ /* take another reference for the copy in the local file priv */ ++ old_master = fpriv->master; ++ fpriv->master = drm_master_get(fpriv->minor->master); ++ ++ if (dev->driver->master_create) { ++ ret = dev->driver->master_create(dev, fpriv->master); ++ if (ret) ++ goto out_err; ++ } ++ if (dev->driver->master_set) { ++ ret = dev->driver->master_set(dev, fpriv, true); ++ if (ret) ++ goto out_err; ++ } ++ ++ fpriv->is_master = 1; ++ fpriv->allowed_master = 1; ++ fpriv->authenticated = 1; ++ if (old_master) ++ drm_master_put(&old_master); ++ ++ return 0; ++ ++out_err: ++ /* drop both references and restore old master on failure */ ++ drm_master_put(&fpriv->minor->master); ++ drm_master_put(&fpriv->master); ++ fpriv->master = old_master; ++ ++ return ret; ++} ++ ++/** + * Called whenever a process opens /dev/drm. + * + * \param filp file pointer. +@@ -189,35 +243,9 @@ static int drm_open_helper(struct file *filp, struct drm_minor *minor) + mutex_lock(&dev->master_mutex); + if (drm_is_primary_client(priv) && !priv->minor->master) { + /* create a new master */ +- priv->minor->master = drm_master_create(priv->minor); +- if (!priv->minor->master) { +- ret = -ENOMEM; ++ ret = drm_new_set_master(dev, priv); ++ if (ret) + goto out_close; +- } +- +- priv->is_master = 1; +- /* take another reference for the copy in the local file priv */ +- priv->master = drm_master_get(priv->minor->master); +- priv->authenticated = 1; +- +- if (dev->driver->master_create) { +- ret = dev->driver->master_create(dev, priv->master); +- if (ret) { +- /* drop both references if this fails */ +- drm_master_put(&priv->minor->master); +- drm_master_put(&priv->master); +- goto out_close; +- } +- } +- if (dev->driver->master_set) { +- ret = dev->driver->master_set(dev, priv, true); +- if (ret) { +- /* drop both references if this fails */ +- drm_master_put(&priv->minor->master); +- drm_master_put(&priv->master); +- goto out_close; +- } +- } + } else if (drm_is_primary_client(priv)) { + /* get a reference to the master */ + priv->master = drm_master_get(priv->minor->master); +diff --git a/include/drm/drmP.h b/include/drm/drmP.h +index 0b921ae..441b26e 100644 +--- a/include/drm/drmP.h ++++ b/include/drm/drmP.h +@@ -309,6 +309,11 @@ struct drm_file { + unsigned universal_planes:1; + /* true if client understands atomic properties */ + unsigned atomic:1; ++ /* ++ * This client is allowed to gain master privileges for @master. ++ * Protected by struct drm_device::master_mutex. ++ */ ++ unsigned allowed_master:1; + + struct pid *pid; + kuid_t uid; +@@ -910,6 +915,7 @@ extern int drm_open(struct inode *inode, struct file *filp); + extern ssize_t drm_read(struct file *filp, char __user *buffer, + size_t count, loff_t *offset); + extern int drm_release(struct inode *inode, struct file *filp); ++extern int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv); + + /* Mapping support (drm_vm.h) */ + extern unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait); +-- +cgit v0.10.2 diff --git a/kernel/kernel/files/patches/mageia/gpu-drm-i915-Fix-RPS-pointer-passed-from-wait_ioctl-to-i915_wait_request.patch b/kernel/kernel/files/patches/mageia/gpu-drm-i915-Fix-RPS-pointer-passed-from-wait_ioctl-to-i915_wait_request.patch new file mode 100644 index 00000000..a082801a --- /dev/null +++ b/kernel/kernel/files/patches/mageia/gpu-drm-i915-Fix-RPS-pointer-passed-from-wait_ioctl-to-i915_wait_request.patch @@ -0,0 +1,35 @@ +From: Chris Wilson +Subject: [PATCH] drm/i915: Fix RPS pointer passed from wait_ioctl to i915_wait_request +Date: Wed, 2 Dec 2015 09:13:46 +0000 + +In commit 2e1b873072dfe3bbcc158a9c21acde1ab0d36c55 [v4.2] +Author: Chris Wilson +Date: Mon Apr 27 13:41:22 2015 +0100 + + drm/i915: Convert RPS tracking to a intel_rps_client struct + +we converted the __i915_wait_request() to take a new intel_rps_client +struct (rather than having to pass fake drm_i915_file_private structs). +However, due to use of passing a void pointer, I didn't spot one +callsite in wait-ioctl was passing the wrong pointer. + +Signed-off-by: Chris Wilson +Cc: Daniel Vetter +Cc: stable@vger.kernel.org +--- + drivers/gpu/drm/i915/i915_gem.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index f5aef48b93db..cd8c4024af92 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -3045,7 +3045,7 @@ i915_gem_wait_ioctl(struct drm_device *d + if (ret == 0) + ret = __i915_wait_request(req[i], reset_counter, true, + args->timeout_ns > 0 ? &args->timeout_ns : NULL, +- file->driver_priv); ++ to_rps_client(file)); + i915_gem_request_unreference__unlocked(req[i]); + } + return ret; diff --git a/kernel/kernel/files/patches/mageia/net_43.mbox.patch b/kernel/kernel/files/patches/mageia/net_43.mbox.patch new file mode 100644 index 00000000..2233f933 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/net_43.mbox.patch @@ -0,0 +1,4174 @@ +From 19900d0bd94181ffa4d2130b5d6afcc6aef805e1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?fran=C3=A7ois=20romieu?= +Date: Wed, 11 Nov 2015 23:35:18 +0100 +Subject: [PATCH 01/43] r8169: fix kasan reported skb use-after-free. + +[ Upstream commit 39174291d8e8acfd1113214a943263aaa03c57c8 ] + +Signed-off-by: Francois Romieu +Reported-by: Dave Jones +Fixes: d7d2d89d4b0af ("r8169: Add software counter for multicast packages") +Acked-by: Eric Dumazet +Acked-by: Corinna Vinschen +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/realtek/r8169.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c +index b4f2123..79ef799 100644 +--- a/drivers/net/ethernet/realtek/r8169.c ++++ b/drivers/net/ethernet/realtek/r8169.c +@@ -7429,15 +7429,15 @@ process_pkt: + + rtl8169_rx_vlan_tag(desc, skb); + ++ if (skb->pkt_type == PACKET_MULTICAST) ++ dev->stats.multicast++; ++ + napi_gro_receive(&tp->napi, skb); + + u64_stats_update_begin(&tp->rx_stats.syncp); + tp->rx_stats.packets++; + tp->rx_stats.bytes += pkt_size; + u64_stats_update_end(&tp->rx_stats.syncp); +- +- if (skb->pkt_type == PACKET_MULTICAST) +- dev->stats.multicast++; + } + release_descriptor: + desc->opts2 = 0; +-- +2.1.0 + + +From 16e46199ccdb834330ed801019d6b96077291d7c Mon Sep 17 00:00:00 2001 +From: Hannes Frederic Sowa +Date: Tue, 10 Nov 2015 16:23:15 +0100 +Subject: [PATCH 02/43] af-unix: fix use-after-free with concurrent readers + while splicing + +[ Upstream commit 73ed5d25dce0354ea381d6dc93005c3085fae03d ] + +During splicing an af-unix socket to a pipe we have to drop all +af-unix socket locks. While doing so we allow another reader to enter +unix_stream_read_generic which can read, copy and finally free another +skb. If exactly this skb is just in process of being spliced we get a +use-after-free report by kasan. + +First, we must make sure to not have a free while the skb is used during +the splice operation. We simply increment its use counter before unlocking +the reader lock. + +Stream sockets have the nice characteristic that we don't care about +zero length writes and they never reach the peer socket's queue. That +said, we can take the UNIXCB.consumed field as the indicator if the +skb was already freed from the socket's receive queue. If the skb was +fully consumed after we locked the reader side again we know it has been +dropped by a second reader. We indicate a short read to user space and +abort the current splice operation. + +This bug has been found with syzkaller +(http://github.com/google/syzkaller) by Dmitry Vyukov. + +Fixes: 2b514574f7e8 ("net: af_unix: implement splice for stream af_unix sockets") +Reported-by: Dmitry Vyukov +Cc: Dmitry Vyukov +Cc: Eric Dumazet +Acked-by: Eric Dumazet +Signed-off-by: Hannes Frederic Sowa +Signed-off-by: David S. Miller +--- + net/unix/af_unix.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index 94f6582..a5afe41 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -440,6 +440,7 @@ static void unix_release_sock(struct sock *sk, int embrion) + if (state == TCP_LISTEN) + unix_release_sock(skb->sk, 1); + /* passed fds are erased in the kfree_skb hook */ ++ UNIXCB(skb).consumed = skb->len; + kfree_skb(skb); + } + +@@ -2071,6 +2072,7 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state) + + do { + int chunk; ++ bool drop_skb; + struct sk_buff *skb, *last; + + unix_state_lock(sk); +@@ -2151,7 +2153,11 @@ unlock: + } + + chunk = min_t(unsigned int, unix_skb_len(skb) - skip, size); ++ skb_get(skb); + chunk = state->recv_actor(skb, skip, chunk, state); ++ drop_skb = !unix_skb_len(skb); ++ /* skb is only safe to use if !drop_skb */ ++ consume_skb(skb); + if (chunk < 0) { + if (copied == 0) + copied = -EFAULT; +@@ -2160,6 +2166,18 @@ unlock: + copied += chunk; + size -= chunk; + ++ if (drop_skb) { ++ /* the skb was touched by a concurrent reader; ++ * we should not expect anything from this skb ++ * anymore and assume it invalid - we can be ++ * sure it was dropped from the socket queue ++ * ++ * let's report a short read ++ */ ++ err = 0; ++ break; ++ } ++ + /* Mark read part of skb as used */ + if (!(flags & MSG_PEEK)) { + UNIXCB(skb).consumed += chunk; +-- +2.1.0 + + +From 75262dbd214a2a628aa333d51531b9e64fd7dc7e Mon Sep 17 00:00:00 2001 +From: Hannes Frederic Sowa +Date: Mon, 16 Nov 2015 16:25:56 +0100 +Subject: [PATCH 03/43] af_unix: don't append consumed skbs to sk_receive_queue + +[ Upstream commit 8844f97238ca6c1ca92a5d6c69f53efd361a266f ] + +In case multiple writes to a unix stream socket race we could end up in a +situation where we pre-allocate a new skb for use in unix_stream_sendpage +but have to free it again in the locked section because another skb +has been appended meanwhile, which we must use. Accidentally we didn't +clear the pointer after consuming it and so we touched freed memory +while appending it to the sk_receive_queue. So, clear the pointer after +consuming the skb. + +This bug has been found with syzkaller +(http://github.com/google/syzkaller) by Dmitry Vyukov. + +Fixes: 869e7c62486e ("net: af_unix: implement stream sendpage support") +Reported-by: Dmitry Vyukov +Cc: Dmitry Vyukov +Cc: Eric Dumazet +Signed-off-by: Hannes Frederic Sowa +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +--- + net/unix/af_unix.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index a5afe41..3e2ca39 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -1799,6 +1799,7 @@ alloc_skb: + * this - does no harm + */ + consume_skb(newskb); ++ newskb = NULL; + } + + if (skb_append_pagefrags(skb, page, offset, size)) { +-- +2.1.0 + + +From faa83c6e01f8604c385c4e0ccc7ca1da591100a5 Mon Sep 17 00:00:00 2001 +From: Hannes Frederic Sowa +Date: Tue, 17 Nov 2015 15:10:59 +0100 +Subject: [PATCH 04/43] af_unix: take receive queue lock while appending new + skb + +[ Upstream commit a3a116e04cc6a94d595ead4e956ab1bc1d2f4746 ] + +While possibly in future we don't necessarily need to use +sk_buff_head.lock this is a rather larger change, as it affects the +af_unix fd garbage collector, diag and socket cleanups. This is too much +for a stable patch. + +For the time being grab sk_buff_head.lock without disabling bh and irqs, +so don't use locked skb_queue_tail. + +Fixes: 869e7c62486e ("net: af_unix: implement stream sendpage support") +Cc: Eric Dumazet +Signed-off-by: Hannes Frederic Sowa +Reported-by: Eric Dumazet +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +--- + net/unix/af_unix.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index 3e2ca39..42ab2cc 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -1812,8 +1812,11 @@ alloc_skb: + skb->truesize += size; + atomic_add(size, &sk->sk_wmem_alloc); + +- if (newskb) ++ if (newskb) { ++ spin_lock(&other->sk_receive_queue.lock); + __skb_queue_tail(&other->sk_receive_queue, newskb); ++ spin_unlock(&other->sk_receive_queue.lock); ++ } + + unix_state_unlock(other); + mutex_unlock(&unix_sk(other)->readlock); +-- +2.1.0 + + +From a46b9d2bac864f3ef6b21eb96864ddd88794222d Mon Sep 17 00:00:00 2001 +From: Rainer Weikusat +Date: Fri, 20 Nov 2015 22:07:23 +0000 +Subject: [PATCH 05/43] unix: avoid use-after-free in ep_remove_wait_queue + +[ Upstream commit 7d267278a9ece963d77eefec61630223fce08c6c ] + +Rainer Weikusat writes: +An AF_UNIX datagram socket being the client in an n:1 association with +some server socket is only allowed to send messages to the server if the +receive queue of this socket contains at most sk_max_ack_backlog +datagrams. This implies that prospective writers might be forced to go +to sleep despite none of the message presently enqueued on the server +receive queue were sent by them. In order to ensure that these will be +woken up once space becomes again available, the present unix_dgram_poll +routine does a second sock_poll_wait call with the peer_wait wait queue +of the server socket as queue argument (unix_dgram_recvmsg does a wake +up on this queue after a datagram was received). This is inherently +problematic because the server socket is only guaranteed to remain alive +for as long as the client still holds a reference to it. In case the +connection is dissolved via connect or by the dead peer detection logic +in unix_dgram_sendmsg, the server socket may be freed despite "the +polling mechanism" (in particular, epoll) still has a pointer to the +corresponding peer_wait queue. There's no way to forcibly deregister a +wait queue with epoll. + +Based on an idea by Jason Baron, the patch below changes the code such +that a wait_queue_t belonging to the client socket is enqueued on the +peer_wait queue of the server whenever the peer receive queue full +condition is detected by either a sendmsg or a poll. A wake up on the +peer queue is then relayed to the ordinary wait queue of the client +socket via wake function. The connection to the peer wait queue is again +dissolved if either a wake up is about to be relayed or the client +socket reconnects or a dead peer is detected or the client socket is +itself closed. This enables removing the second sock_poll_wait from +unix_dgram_poll, thus avoiding the use-after-free, while still ensuring +that no blocked writer sleeps forever. + +Signed-off-by: Rainer Weikusat +Fixes: ec0d215f9420 ("af_unix: fix 'poll for write'/connected DGRAM sockets") +Reviewed-by: Jason Baron +Signed-off-by: David S. Miller +--- + include/net/af_unix.h | 1 + + net/unix/af_unix.c | 183 ++++++++++++++++++++++++++++++++++++++++++++------ + 2 files changed, 165 insertions(+), 19 deletions(-) + +diff --git a/include/net/af_unix.h b/include/net/af_unix.h +index b36d837..2a91a05 100644 +--- a/include/net/af_unix.h ++++ b/include/net/af_unix.h +@@ -62,6 +62,7 @@ struct unix_sock { + #define UNIX_GC_CANDIDATE 0 + #define UNIX_GC_MAYBE_CYCLE 1 + struct socket_wq peer_wq; ++ wait_queue_t peer_wake; + }; + + static inline struct unix_sock *unix_sk(const struct sock *sk) +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index 42ab2cc..153b2f2 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -326,6 +326,118 @@ found: + return s; + } + ++/* Support code for asymmetrically connected dgram sockets ++ * ++ * If a datagram socket is connected to a socket not itself connected ++ * to the first socket (eg, /dev/log), clients may only enqueue more ++ * messages if the present receive queue of the server socket is not ++ * "too large". This means there's a second writeability condition ++ * poll and sendmsg need to test. The dgram recv code will do a wake ++ * up on the peer_wait wait queue of a socket upon reception of a ++ * datagram which needs to be propagated to sleeping would-be writers ++ * since these might not have sent anything so far. This can't be ++ * accomplished via poll_wait because the lifetime of the server ++ * socket might be less than that of its clients if these break their ++ * association with it or if the server socket is closed while clients ++ * are still connected to it and there's no way to inform "a polling ++ * implementation" that it should let go of a certain wait queue ++ * ++ * In order to propagate a wake up, a wait_queue_t of the client ++ * socket is enqueued on the peer_wait queue of the server socket ++ * whose wake function does a wake_up on the ordinary client socket ++ * wait queue. This connection is established whenever a write (or ++ * poll for write) hit the flow control condition and broken when the ++ * association to the server socket is dissolved or after a wake up ++ * was relayed. ++ */ ++ ++static int unix_dgram_peer_wake_relay(wait_queue_t *q, unsigned mode, int flags, ++ void *key) ++{ ++ struct unix_sock *u; ++ wait_queue_head_t *u_sleep; ++ ++ u = container_of(q, struct unix_sock, peer_wake); ++ ++ __remove_wait_queue(&unix_sk(u->peer_wake.private)->peer_wait, ++ q); ++ u->peer_wake.private = NULL; ++ ++ /* relaying can only happen while the wq still exists */ ++ u_sleep = sk_sleep(&u->sk); ++ if (u_sleep) ++ wake_up_interruptible_poll(u_sleep, key); ++ ++ return 0; ++} ++ ++static int unix_dgram_peer_wake_connect(struct sock *sk, struct sock *other) ++{ ++ struct unix_sock *u, *u_other; ++ int rc; ++ ++ u = unix_sk(sk); ++ u_other = unix_sk(other); ++ rc = 0; ++ spin_lock(&u_other->peer_wait.lock); ++ ++ if (!u->peer_wake.private) { ++ u->peer_wake.private = other; ++ __add_wait_queue(&u_other->peer_wait, &u->peer_wake); ++ ++ rc = 1; ++ } ++ ++ spin_unlock(&u_other->peer_wait.lock); ++ return rc; ++} ++ ++static void unix_dgram_peer_wake_disconnect(struct sock *sk, ++ struct sock *other) ++{ ++ struct unix_sock *u, *u_other; ++ ++ u = unix_sk(sk); ++ u_other = unix_sk(other); ++ spin_lock(&u_other->peer_wait.lock); ++ ++ if (u->peer_wake.private == other) { ++ __remove_wait_queue(&u_other->peer_wait, &u->peer_wake); ++ u->peer_wake.private = NULL; ++ } ++ ++ spin_unlock(&u_other->peer_wait.lock); ++} ++ ++static void unix_dgram_peer_wake_disconnect_wakeup(struct sock *sk, ++ struct sock *other) ++{ ++ unix_dgram_peer_wake_disconnect(sk, other); ++ wake_up_interruptible_poll(sk_sleep(sk), ++ POLLOUT | ++ POLLWRNORM | ++ POLLWRBAND); ++} ++ ++/* preconditions: ++ * - unix_peer(sk) == other ++ * - association is stable ++ */ ++static int unix_dgram_peer_wake_me(struct sock *sk, struct sock *other) ++{ ++ int connected; ++ ++ connected = unix_dgram_peer_wake_connect(sk, other); ++ ++ if (unix_recvq_full(other)) ++ return 1; ++ ++ if (connected) ++ unix_dgram_peer_wake_disconnect(sk, other); ++ ++ return 0; ++} ++ + static inline int unix_writable(struct sock *sk) + { + return (atomic_read(&sk->sk_wmem_alloc) << 2) <= sk->sk_sndbuf; +@@ -430,6 +542,8 @@ static void unix_release_sock(struct sock *sk, int embrion) + skpair->sk_state_change(skpair); + sk_wake_async(skpair, SOCK_WAKE_WAITD, POLL_HUP); + } ++ ++ unix_dgram_peer_wake_disconnect(sk, skpair); + sock_put(skpair); /* It may now die */ + unix_peer(sk) = NULL; + } +@@ -665,6 +779,7 @@ static struct sock *unix_create1(struct net *net, struct socket *sock, int kern) + INIT_LIST_HEAD(&u->link); + mutex_init(&u->readlock); /* single task reading lock */ + init_waitqueue_head(&u->peer_wait); ++ init_waitqueue_func_entry(&u->peer_wake, unix_dgram_peer_wake_relay); + unix_insert_socket(unix_sockets_unbound(sk), sk); + out: + if (sk == NULL) +@@ -1032,6 +1147,8 @@ restart: + if (unix_peer(sk)) { + struct sock *old_peer = unix_peer(sk); + unix_peer(sk) = other; ++ unix_dgram_peer_wake_disconnect_wakeup(sk, old_peer); ++ + unix_state_double_unlock(sk, other); + + if (other != old_peer) +@@ -1471,6 +1588,7 @@ static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg, + struct scm_cookie scm; + int max_level; + int data_len = 0; ++ int sk_locked; + + wait_for_unix_gc(); + err = scm_send(sock, msg, &scm, false); +@@ -1549,12 +1667,14 @@ restart: + goto out_free; + } + ++ sk_locked = 0; + unix_state_lock(other); ++restart_locked: + err = -EPERM; + if (!unix_may_send(sk, other)) + goto out_unlock; + +- if (sock_flag(other, SOCK_DEAD)) { ++ if (unlikely(sock_flag(other, SOCK_DEAD))) { + /* + * Check with 1003.1g - what should + * datagram error +@@ -1562,10 +1682,14 @@ restart: + unix_state_unlock(other); + sock_put(other); + ++ if (!sk_locked) ++ unix_state_lock(sk); ++ + err = 0; +- unix_state_lock(sk); + if (unix_peer(sk) == other) { + unix_peer(sk) = NULL; ++ unix_dgram_peer_wake_disconnect_wakeup(sk, other); ++ + unix_state_unlock(sk); + + unix_dgram_disconnected(sk, other); +@@ -1591,21 +1715,38 @@ restart: + goto out_unlock; + } + +- if (unix_peer(other) != sk && unix_recvq_full(other)) { +- if (!timeo) { +- err = -EAGAIN; +- goto out_unlock; ++ if (unlikely(unix_peer(other) != sk && unix_recvq_full(other))) { ++ if (timeo) { ++ timeo = unix_wait_for_peer(other, timeo); ++ ++ err = sock_intr_errno(timeo); ++ if (signal_pending(current)) ++ goto out_free; ++ ++ goto restart; + } + +- timeo = unix_wait_for_peer(other, timeo); ++ if (!sk_locked) { ++ unix_state_unlock(other); ++ unix_state_double_lock(sk, other); ++ } + +- err = sock_intr_errno(timeo); +- if (signal_pending(current)) +- goto out_free; ++ if (unix_peer(sk) != other || ++ unix_dgram_peer_wake_me(sk, other)) { ++ err = -EAGAIN; ++ sk_locked = 1; ++ goto out_unlock; ++ } + +- goto restart; ++ if (!sk_locked) { ++ sk_locked = 1; ++ goto restart_locked; ++ } + } + ++ if (unlikely(sk_locked)) ++ unix_state_unlock(sk); ++ + if (sock_flag(other, SOCK_RCVTSTAMP)) + __net_timestamp(skb); + maybe_add_creds(skb, sock, other); +@@ -1619,6 +1760,8 @@ restart: + return len; + + out_unlock: ++ if (sk_locked) ++ unix_state_unlock(sk); + unix_state_unlock(other); + out_free: + kfree_skb(skb); +@@ -2475,14 +2618,16 @@ static unsigned int unix_dgram_poll(struct file *file, struct socket *sock, + return mask; + + writable = unix_writable(sk); +- other = unix_peer_get(sk); +- if (other) { +- if (unix_peer(other) != sk) { +- sock_poll_wait(file, &unix_sk(other)->peer_wait, wait); +- if (unix_recvq_full(other)) +- writable = 0; +- } +- sock_put(other); ++ if (writable) { ++ unix_state_lock(sk); ++ ++ other = unix_peer(sk); ++ if (other && unix_peer(other) != sk && ++ unix_recvq_full(other) && ++ unix_dgram_peer_wake_me(sk, other)) ++ writable = 0; ++ ++ unix_state_unlock(sk); + } + + if (writable) +-- +2.1.0 + + +From 8a029a6b8df3a955bd24253ce77cfc93834ce71f Mon Sep 17 00:00:00 2001 +From: Hannes Frederic Sowa +Date: Thu, 26 Nov 2015 12:08:18 +0100 +Subject: [PATCH 06/43] af-unix: passcred support for sendpage + +[ Upstream commit 9490f886b192964796285907d777ff00fba1fa0f ] + +sendpage did not care about credentials at all. This could lead to +situations in which because of fd passing between processes we could +append data to skbs with different scm data. It is illegal to splice those +skbs together. Instead we have to allocate a new skb and if requested +fill out the scm details. + +Fixes: 869e7c62486ec ("net: af_unix: implement stream sendpage support") +Reported-by: Al Viro +Cc: Al Viro +Cc: Eric Dumazet +Signed-off-by: Hannes Frederic Sowa +Signed-off-by: David S. Miller +--- + net/unix/af_unix.c | 79 +++++++++++++++++++++++++++++++++++++++++++----------- + 1 file changed, 64 insertions(+), 15 deletions(-) + +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index 153b2f2..128b098 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -1550,6 +1550,14 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen + return err; + } + ++static bool unix_passcred_enabled(const struct socket *sock, ++ const struct sock *other) ++{ ++ return test_bit(SOCK_PASSCRED, &sock->flags) || ++ !other->sk_socket || ++ test_bit(SOCK_PASSCRED, &other->sk_socket->flags); ++} ++ + /* + * Some apps rely on write() giving SCM_CREDENTIALS + * We include credentials if source or destination socket +@@ -1560,14 +1568,41 @@ static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock, + { + if (UNIXCB(skb).pid) + return; +- if (test_bit(SOCK_PASSCRED, &sock->flags) || +- !other->sk_socket || +- test_bit(SOCK_PASSCRED, &other->sk_socket->flags)) { ++ if (unix_passcred_enabled(sock, other)) { + UNIXCB(skb).pid = get_pid(task_tgid(current)); + current_uid_gid(&UNIXCB(skb).uid, &UNIXCB(skb).gid); + } + } + ++static int maybe_init_creds(struct scm_cookie *scm, ++ struct socket *socket, ++ const struct sock *other) ++{ ++ int err; ++ struct msghdr msg = { .msg_controllen = 0 }; ++ ++ err = scm_send(socket, &msg, scm, false); ++ if (err) ++ return err; ++ ++ if (unix_passcred_enabled(socket, other)) { ++ scm->pid = get_pid(task_tgid(current)); ++ current_uid_gid(&scm->creds.uid, &scm->creds.gid); ++ } ++ return err; ++} ++ ++static bool unix_skb_scm_eq(struct sk_buff *skb, ++ struct scm_cookie *scm) ++{ ++ const struct unix_skb_parms *u = &UNIXCB(skb); ++ ++ return u->pid == scm->pid && ++ uid_eq(u->uid, scm->creds.uid) && ++ gid_eq(u->gid, scm->creds.gid) && ++ unix_secdata_eq(scm, skb); ++} ++ + /* + * Send AF_UNIX data. + */ +@@ -1883,8 +1918,10 @@ out_err: + static ssize_t unix_stream_sendpage(struct socket *socket, struct page *page, + int offset, size_t size, int flags) + { +- int err = 0; +- bool send_sigpipe = true; ++ int err; ++ bool send_sigpipe = false; ++ bool init_scm = true; ++ struct scm_cookie scm; + struct sock *other, *sk = socket->sk; + struct sk_buff *skb, *newskb = NULL, *tail = NULL; + +@@ -1902,7 +1939,7 @@ alloc_skb: + newskb = sock_alloc_send_pskb(sk, 0, 0, flags & MSG_DONTWAIT, + &err, 0); + if (!newskb) +- return err; ++ goto err; + } + + /* we must acquire readlock as we modify already present +@@ -1911,12 +1948,12 @@ alloc_skb: + err = mutex_lock_interruptible(&unix_sk(other)->readlock); + if (err) { + err = flags & MSG_DONTWAIT ? -EAGAIN : -ERESTARTSYS; +- send_sigpipe = false; + goto err; + } + + if (sk->sk_shutdown & SEND_SHUTDOWN) { + err = -EPIPE; ++ send_sigpipe = true; + goto err_unlock; + } + +@@ -1925,17 +1962,27 @@ alloc_skb: + if (sock_flag(other, SOCK_DEAD) || + other->sk_shutdown & RCV_SHUTDOWN) { + err = -EPIPE; ++ send_sigpipe = true; + goto err_state_unlock; + } + ++ if (init_scm) { ++ err = maybe_init_creds(&scm, socket, other); ++ if (err) ++ goto err_state_unlock; ++ init_scm = false; ++ } ++ + skb = skb_peek_tail(&other->sk_receive_queue); + if (tail && tail == skb) { + skb = newskb; +- } else if (!skb) { +- if (newskb) ++ } else if (!skb || !unix_skb_scm_eq(skb, &scm)) { ++ if (newskb) { + skb = newskb; +- else ++ } else { ++ tail = skb; + goto alloc_skb; ++ } + } else if (newskb) { + /* this is fast path, we don't necessarily need to + * call to kfree_skb even though with newskb == NULL +@@ -1956,6 +2003,9 @@ alloc_skb: + atomic_add(size, &sk->sk_wmem_alloc); + + if (newskb) { ++ err = unix_scm_to_skb(&scm, skb, false); ++ if (err) ++ goto err_state_unlock; + spin_lock(&other->sk_receive_queue.lock); + __skb_queue_tail(&other->sk_receive_queue, newskb); + spin_unlock(&other->sk_receive_queue.lock); +@@ -1965,7 +2015,7 @@ alloc_skb: + mutex_unlock(&unix_sk(other)->readlock); + + other->sk_data_ready(other); +- ++ scm_destroy(&scm); + return size; + + err_state_unlock: +@@ -1976,6 +2026,8 @@ err: + kfree_skb(newskb); + if (send_sigpipe && !(flags & MSG_NOSIGNAL)) + send_sig(SIGPIPE, current, 0); ++ if (!init_scm) ++ scm_destroy(&scm); + return err; + } + +@@ -2279,10 +2331,7 @@ unlock: + + if (check_creds) { + /* Never glue messages from different writers */ +- if ((UNIXCB(skb).pid != scm.pid) || +- !uid_eq(UNIXCB(skb).uid, scm.creds.uid) || +- !gid_eq(UNIXCB(skb).gid, scm.creds.gid) || +- !unix_secdata_eq(&scm, skb)) ++ if (!unix_skb_scm_eq(skb, &scm)) + break; + } else if (test_bit(SOCK_PASSCRED, &sock->flags)) { + /* Copy credentials */ +-- +2.1.0 + + +From 6f61ebb821b04690a54ae998160cb758dbaa7f9b Mon Sep 17 00:00:00 2001 +From: Martin KaFai Lau +Date: Wed, 11 Nov 2015 11:51:06 -0800 +Subject: [PATCH 07/43] ipv6: Avoid creating RTF_CACHE from a rt that is not + managed by fib6 tree + +[ Upstream commit 0d3f6d297bfb7af24d0508460fdb3d1ec4903fa3 ] + +The original bug report: +https://bugzilla.redhat.com/show_bug.cgi?id=1272571 + +The setup has a IPv4 GRE tunnel running in a IPSec. The bug +happens when ndisc starts sending router solicitation at the gre +interface. The simplified oops stack is like: + +__lock_acquire+0x1b2/0x1c30 +lock_acquire+0xb9/0x140 +_raw_write_lock_bh+0x3f/0x50 +__ip6_ins_rt+0x2e/0x60 +ip6_ins_rt+0x49/0x50 +~~~~~~~~ +__ip6_rt_update_pmtu.part.54+0x145/0x250 +ip6_rt_update_pmtu+0x2e/0x40 +~~~~~~~~ +ip_tunnel_xmit+0x1f1/0xf40 +__gre_xmit+0x7a/0x90 +ipgre_xmit+0x15a/0x220 +dev_hard_start_xmit+0x2bd/0x480 +__dev_queue_xmit+0x696/0x730 +dev_queue_xmit+0x10/0x20 +neigh_direct_output+0x11/0x20 +ip6_finish_output2+0x21f/0x770 +ip6_finish_output+0xa7/0x1d0 +ip6_output+0x56/0x190 +~~~~~~~~ +ndisc_send_skb+0x1d9/0x400 +ndisc_send_rs+0x88/0xc0 +~~~~~~~~ + +The rt passed to ip6_rt_update_pmtu() is created by +icmp6_dst_alloc() and it is not managed by the fib6 tree, +so its rt6i_table == NULL. When __ip6_rt_update_pmtu() creates +a RTF_CACHE clone, the newly created clone also has rt6i_table == NULL +and it causes the ip6_ins_rt() oops. + +During pmtu update, we only want to create a RTF_CACHE clone +from a rt which is currently managed (or owned) by the +fib6 tree. It means either rt->rt6i_node != NULL or +rt is a RTF_PCPU clone. + +It is worth to note that rt6i_table may not be NULL even it is +not (yet) managed by the fib6 tree (e.g. addrconf_dst_alloc()). +Hence, rt6i_node is a better check instead of rt6i_table. + +Fixes: 45e4fd26683c ("ipv6: Only create RTF_CACHE routes after encountering pmtu") +Signed-off-by: Martin KaFai Lau +Reported-by: Chris Siebenmann +Cc: Chris Siebenmann +Cc: Hannes Frederic Sowa +Signed-off-by: David S. Miller +--- + net/ipv6/route.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index 946880a..711ec7a 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -1340,6 +1340,12 @@ static void rt6_do_update_pmtu(struct rt6_info *rt, u32 mtu) + rt6_update_expires(rt, net->ipv6.sysctl.ip6_rt_mtu_expires); + } + ++static bool rt6_cache_allowed_for_pmtu(const struct rt6_info *rt) ++{ ++ return !(rt->rt6i_flags & RTF_CACHE) && ++ (rt->rt6i_flags & RTF_PCPU || rt->rt6i_node); ++} ++ + static void __ip6_rt_update_pmtu(struct dst_entry *dst, const struct sock *sk, + const struct ipv6hdr *iph, u32 mtu) + { +@@ -1353,7 +1359,7 @@ static void __ip6_rt_update_pmtu(struct dst_entry *dst, const struct sock *sk, + if (mtu >= dst_mtu(dst)) + return; + +- if (rt6->rt6i_flags & RTF_CACHE) { ++ if (!rt6_cache_allowed_for_pmtu(rt6)) { + rt6_do_update_pmtu(rt6, mtu); + } else { + const struct in6_addr *daddr, *saddr; +-- +2.1.0 + + +From 36e5325023d53e603ce46bfcd55587f164850102 Mon Sep 17 00:00:00 2001 +From: Martin KaFai Lau +Date: Wed, 11 Nov 2015 11:51:07 -0800 +Subject: [PATCH 08/43] ipv6: Check expire on DST_NOCACHE route + +[ Upstream commit 5973fb1e245086071bf71994c8b54d99526ded03 ] + +Since the expires of the DST_NOCACHE rt can be set during +the ip6_rt_update_pmtu(), we also need to consider the expires +value when doing ip6_dst_check(). + +This patches creates __rt6_check_expired() to only +check the expire value (if one exists) of the current rt. + +In rt6_dst_from_check(), it adds __rt6_check_expired() as +one of the condition check. + +Signed-off-by: Martin KaFai Lau +Cc: Hannes Frederic Sowa +Signed-off-by: David S. Miller +--- + net/ipv6/route.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index 711ec7a..ea892c1 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -403,6 +403,14 @@ static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev, + } + } + ++static bool __rt6_check_expired(const struct rt6_info *rt) ++{ ++ if (rt->rt6i_flags & RTF_EXPIRES) ++ return time_after(jiffies, rt->dst.expires); ++ else ++ return false; ++} ++ + static bool rt6_check_expired(const struct rt6_info *rt) + { + if (rt->rt6i_flags & RTF_EXPIRES) { +@@ -1270,7 +1278,8 @@ static struct dst_entry *rt6_check(struct rt6_info *rt, u32 cookie) + + static struct dst_entry *rt6_dst_from_check(struct rt6_info *rt, u32 cookie) + { +- if (rt->dst.obsolete == DST_OBSOLETE_FORCE_CHK && ++ if (!__rt6_check_expired(rt) && ++ rt->dst.obsolete == DST_OBSOLETE_FORCE_CHK && + rt6_check((struct rt6_info *)(rt->dst.from), cookie)) + return &rt->dst; + else +-- +2.1.0 + + +From 037104a8ac4a3509ee800cfa124897600c9483e7 Mon Sep 17 00:00:00 2001 +From: Martin KaFai Lau +Date: Wed, 11 Nov 2015 11:51:08 -0800 +Subject: [PATCH 09/43] ipv6: Check rt->dst.from for the DST_NOCACHE route + +[ Upstrem commit 02bcf4e082e4dc634409a6a6cb7def8806d6e5e6 ] + +All DST_NOCACHE rt6_info used to have rt->dst.from set to +its parent. + +After commit 8e3d5be73681 ("ipv6: Avoid double dst_free"), +DST_NOCACHE is also set to rt6_info which does not have +a parent (i.e. rt->dst.from is NULL). + +This patch catches the rt->dst.from == NULL case. + +Fixes: 8e3d5be73681 ("ipv6: Avoid double dst_free") +Signed-off-by: Martin KaFai Lau +Cc: Hannes Frederic Sowa +Signed-off-by: David S. Miller +--- + include/net/ip6_fib.h | 3 ++- + net/ipv6/route.c | 3 ++- + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h +index aaf9700..fb961a5 100644 +--- a/include/net/ip6_fib.h ++++ b/include/net/ip6_fib.h +@@ -167,7 +167,8 @@ static inline void rt6_update_expires(struct rt6_info *rt0, int timeout) + + static inline u32 rt6_get_cookie(const struct rt6_info *rt) + { +- if (rt->rt6i_flags & RTF_PCPU || unlikely(rt->dst.flags & DST_NOCACHE)) ++ if (rt->rt6i_flags & RTF_PCPU || ++ (unlikely(rt->dst.flags & DST_NOCACHE) && rt->dst.from)) + rt = (struct rt6_info *)(rt->dst.from); + + return rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0; +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index ea892c1..d377326 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -1299,7 +1299,8 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie) + + rt6_dst_from_metrics_check(rt); + +- if ((rt->rt6i_flags & RTF_PCPU) || unlikely(dst->flags & DST_NOCACHE)) ++ if (rt->rt6i_flags & RTF_PCPU || ++ (unlikely(dst->flags & DST_NOCACHE) && rt->dst.from)) + return rt6_dst_from_check(rt, cookie); + else + return rt6_check(rt, cookie); +-- +2.1.0 + + +From bbecfdcd08494929d0cde9176346d51007fb77ed Mon Sep 17 00:00:00 2001 +From: Nicolas Dichtel +Date: Fri, 27 Nov 2015 18:17:05 +0100 +Subject: [PATCH 10/43] Revert "ipv6: ndisc: inherit metadata dst when creating + ndisc requests" + +[ Upstream commit 304d888b29cf96f1dd53511ee686499cd8cdf249 ] + +This reverts commit ab450605b35caa768ca33e86db9403229bf42be4. + +In IPv6, we cannot inherit the dst of the original dst. ndisc packets +are IPv6 packets and may take another route than the original packet. + +This patch breaks the following scenario: a packet comes from eth0 and +is forwarded through vxlan1. The encapsulated packet triggers an NS +which cannot be sent because of the wrong route. + +CC: Jiri Benc +CC: Thomas Graf +Signed-off-by: Nicolas Dichtel +Signed-off-by: David S. Miller +--- + include/net/ndisc.h | 3 +-- + net/ipv6/addrconf.c | 2 +- + net/ipv6/ndisc.c | 10 +++------- + net/ipv6/route.c | 2 +- + 4 files changed, 6 insertions(+), 11 deletions(-) + +diff --git a/include/net/ndisc.h b/include/net/ndisc.h +index aba5695..b3a7751 100644 +--- a/include/net/ndisc.h ++++ b/include/net/ndisc.h +@@ -182,8 +182,7 @@ int ndisc_rcv(struct sk_buff *skb); + + void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh, + const struct in6_addr *solicit, +- const struct in6_addr *daddr, const struct in6_addr *saddr, +- struct sk_buff *oskb); ++ const struct in6_addr *daddr, const struct in6_addr *saddr); + + void ndisc_send_rs(struct net_device *dev, + const struct in6_addr *saddr, const struct in6_addr *daddr); +diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c +index dd00828..3939dd2 100644 +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -3628,7 +3628,7 @@ static void addrconf_dad_work(struct work_struct *w) + + /* send a neighbour solicitation for our addr */ + addrconf_addr_solict_mult(&ifp->addr, &mcaddr); +- ndisc_send_ns(ifp->idev->dev, NULL, &ifp->addr, &mcaddr, &in6addr_any, NULL); ++ ndisc_send_ns(ifp->idev->dev, NULL, &ifp->addr, &mcaddr, &in6addr_any); + out: + in6_ifa_put(ifp); + rtnl_unlock(); +diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c +index 64a7135..9ad46cd 100644 +--- a/net/ipv6/ndisc.c ++++ b/net/ipv6/ndisc.c +@@ -553,8 +553,7 @@ static void ndisc_send_unsol_na(struct net_device *dev) + + void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh, + const struct in6_addr *solicit, +- const struct in6_addr *daddr, const struct in6_addr *saddr, +- struct sk_buff *oskb) ++ const struct in6_addr *daddr, const struct in6_addr *saddr) + { + struct sk_buff *skb; + struct in6_addr addr_buf; +@@ -590,9 +589,6 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh, + ndisc_fill_addr_option(skb, ND_OPT_SOURCE_LL_ADDR, + dev->dev_addr); + +- if (!(dev->priv_flags & IFF_XMIT_DST_RELEASE) && oskb) +- skb_dst_copy(skb, oskb); +- + ndisc_send_skb(skb, daddr, saddr); + } + +@@ -679,12 +675,12 @@ static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb) + "%s: trying to ucast probe in NUD_INVALID: %pI6\n", + __func__, target); + } +- ndisc_send_ns(dev, neigh, target, target, saddr, skb); ++ ndisc_send_ns(dev, neigh, target, target, saddr); + } else if ((probes -= NEIGH_VAR(neigh->parms, APP_PROBES)) < 0) { + neigh_app_ns(neigh); + } else { + addrconf_addr_solict_mult(target, &mcaddr); +- ndisc_send_ns(dev, NULL, target, &mcaddr, saddr, skb); ++ ndisc_send_ns(dev, NULL, target, &mcaddr, saddr); + } + } + +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index d377326..fd0e674 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -546,7 +546,7 @@ static void rt6_probe_deferred(struct work_struct *w) + container_of(w, struct __rt6_probe_work, work); + + addrconf_addr_solict_mult(&work->target, &mcaddr); +- ndisc_send_ns(work->dev, NULL, &work->target, &mcaddr, NULL, NULL); ++ ndisc_send_ns(work->dev, NULL, &work->target, &mcaddr, NULL); + dev_put(work->dev); + kfree(work); + } +-- +2.1.0 + + +From 3855e07a82c0180d9110ac03d84405f9ecc79866 Mon Sep 17 00:00:00 2001 +From: Kamal Mostafa +Date: Wed, 11 Nov 2015 14:24:27 -0800 +Subject: [PATCH 11/43] tools/net: Use include/uapi with __EXPORTED_HEADERS__ + +[ Upstream commit d7475de58575c904818efa369c82e88c6648ce2e ] + +Use the local uapi headers to keep in sync with "recently" added #define's +(e.g. SKF_AD_VLAN_TPID). Refactored CFLAGS, and bpf_asm doesn't need -I. + +Fixes: 3f356385e8a4 ("filter: bpf_asm: add minimal bpf asm tool") +Signed-off-by: Kamal Mostafa +Acked-by: Daniel Borkmann +Signed-off-by: David S. Miller +--- + tools/net/Makefile | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/tools/net/Makefile b/tools/net/Makefile +index ee577ea..ddf8880 100644 +--- a/tools/net/Makefile ++++ b/tools/net/Makefile +@@ -4,6 +4,9 @@ CC = gcc + LEX = flex + YACC = bison + ++CFLAGS += -Wall -O2 ++CFLAGS += -D__EXPORTED_HEADERS__ -I../../include/uapi -I../../include ++ + %.yacc.c: %.y + $(YACC) -o $@ -d $< + +@@ -12,15 +15,13 @@ YACC = bison + + all : bpf_jit_disasm bpf_dbg bpf_asm + +-bpf_jit_disasm : CFLAGS = -Wall -O2 -DPACKAGE='bpf_jit_disasm' ++bpf_jit_disasm : CFLAGS += -DPACKAGE='bpf_jit_disasm' + bpf_jit_disasm : LDLIBS = -lopcodes -lbfd -ldl + bpf_jit_disasm : bpf_jit_disasm.o + +-bpf_dbg : CFLAGS = -Wall -O2 + bpf_dbg : LDLIBS = -lreadline + bpf_dbg : bpf_dbg.o + +-bpf_asm : CFLAGS = -Wall -O2 -I. + bpf_asm : LDLIBS = + bpf_asm : bpf_asm.o bpf_exp.yacc.o bpf_exp.lex.o + bpf_exp.lex.o : bpf_exp.yacc.c +-- +2.1.0 + + +From 00e7c45712e9d826a2908cdfb4d15581f825e47d Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +Date: Wed, 11 Nov 2015 23:25:40 +0100 +Subject: [PATCH 12/43] packet: do skb_probe_transport_header when we actually + have data + +[ Upstream commit efdfa2f7848f64517008136fb41f53c4a1faf93a ] + +In tpacket_fill_skb() commit c1aad275b029 ("packet: set transport +header before doing xmit") and later on 40893fd0fd4e ("net: switch +to use skb_probe_transport_header()") was probing for a transport +header on the skb from a ring buffer slot, but at a time, where +the skb has _not even_ been filled with data yet. So that call into +the flow dissector is pretty useless. Lets do it after we've set +up the skb frags. + +Fixes: c1aad275b029 ("packet: set transport header before doing xmit") +Reported-by: Eric Dumazet +Signed-off-by: Daniel Borkmann +Acked-by: Jason Wang +Signed-off-by: David S. Miller +--- + net/packet/af_packet.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index 27b2898..be038c9 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -2368,8 +2368,6 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, + skb_reserve(skb, hlen); + skb_reset_network_header(skb); + +- if (!packet_use_direct_xmit(po)) +- skb_probe_transport_header(skb, 0); + if (unlikely(po->tp_tx_has_off)) { + int off_min, off_max, off; + off_min = po->tp_hdrlen - sizeof(struct sockaddr_ll); +@@ -2449,6 +2447,9 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, + len = ((to_write > len_max) ? len_max : to_write); + } + ++ if (!packet_use_direct_xmit(po)) ++ skb_probe_transport_header(skb, 0); ++ + return tp_len; + } + +-- +2.1.0 + + +From 995afa88f27c706e0daf329f6fb07398414f2334 Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +Date: Wed, 11 Nov 2015 23:25:41 +0100 +Subject: [PATCH 13/43] packet: always probe for transport header + +[ Upstream commit 8fd6c80d9dd938ca338c70698533a7e304752846 ] + +We concluded that the skb_probe_transport_header() should better be +called unconditionally. Avoiding the call into the flow dissector has +also not really much to do with the direct xmit mode. + +While it seems that only virtio_net code makes use of GSO from non +RX/TX ring packet socket paths, we should probe for a transport header +nevertheless before they hit devices. + +Reference: http://thread.gmane.org/gmane.linux.network/386173/ +Signed-off-by: Daniel Borkmann +Acked-by: Jason Wang +Signed-off-by: David S. Miller +--- + net/packet/af_packet.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index be038c9..3059f51 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -2447,8 +2447,7 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, + len = ((to_write > len_max) ? len_max : to_write); + } + +- if (!packet_use_direct_xmit(po)) +- skb_probe_transport_header(skb, 0); ++ skb_probe_transport_header(skb, 0); + + return tp_len; + } +@@ -2800,8 +2799,8 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) + len += vnet_hdr_len; + } + +- if (!packet_use_direct_xmit(po)) +- skb_probe_transport_header(skb, reserve); ++ skb_probe_transport_header(skb, reserve); ++ + if (unlikely(extra_len == 4)) + skb->no_fcs = 1; + +-- +2.1.0 + + +From 85df0fab1bfabd5a88b9d53a09d34df51672282a Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +Date: Wed, 11 Nov 2015 23:25:42 +0100 +Subject: [PATCH 14/43] packet: only allow extra vlan len on ethernet devices + +[ Upstream commit 3c70c132488794e2489ab045559b0ce0afcf17de ] + +Packet sockets can be used by various net devices and are not +really restricted to ARPHRD_ETHER device types. However, when +currently checking for the extra 4 bytes that can be transmitted +in VLAN case, our assumption is that we generally probe on +ARPHRD_ETHER devices. Therefore, before looking into Ethernet +header, check the device type first. + +This also fixes the issue where non-ARPHRD_ETHER devices could +have no dev->hard_header_len in TX_RING SOCK_RAW case, and thus +the check would test unfilled linear part of the skb (instead +of non-linear). + +Fixes: 57f89bfa2140 ("network: Allow af_packet to transmit +4 bytes for VLAN packets.") +Fixes: 52f1454f629f ("packet: allow to transmit +4 byte in TX_RING slot for VLAN case") +Signed-off-by: Daniel Borkmann +Acked-by: Willem de Bruijn +Signed-off-by: David S. Miller +--- + net/packet/af_packet.c | 60 +++++++++++++++++++++----------------------------- + 1 file changed, 25 insertions(+), 35 deletions(-) + +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index 3059f51..6e3cd2f 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -1741,6 +1741,20 @@ static void fanout_release(struct sock *sk) + kfree_rcu(po->rollover, rcu); + } + ++static bool packet_extra_vlan_len_allowed(const struct net_device *dev, ++ struct sk_buff *skb) ++{ ++ /* Earlier code assumed this would be a VLAN pkt, double-check ++ * this now that we have the actual packet in hand. We can only ++ * do this check on Ethernet devices. ++ */ ++ if (unlikely(dev->type != ARPHRD_ETHER)) ++ return false; ++ ++ skb_reset_mac_header(skb); ++ return likely(eth_hdr(skb)->h_proto == htons(ETH_P_8021Q)); ++} ++ + static const struct proto_ops packet_ops; + + static const struct proto_ops packet_ops_spkt; +@@ -1902,18 +1916,10 @@ retry: + goto retry; + } + +- if (len > (dev->mtu + dev->hard_header_len + extra_len)) { +- /* Earlier code assumed this would be a VLAN pkt, +- * double-check this now that we have the actual +- * packet in hand. +- */ +- struct ethhdr *ehdr; +- skb_reset_mac_header(skb); +- ehdr = eth_hdr(skb); +- if (ehdr->h_proto != htons(ETH_P_8021Q)) { +- err = -EMSGSIZE; +- goto out_unlock; +- } ++ if (len > (dev->mtu + dev->hard_header_len + extra_len) && ++ !packet_extra_vlan_len_allowed(dev, skb)) { ++ err = -EMSGSIZE; ++ goto out_unlock; + } + + skb->protocol = proto; +@@ -2525,18 +2531,10 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) + tp_len = tpacket_fill_skb(po, skb, ph, dev, size_max, proto, + addr, hlen); + if (likely(tp_len >= 0) && +- tp_len > dev->mtu + dev->hard_header_len) { +- struct ethhdr *ehdr; +- /* Earlier code assumed this would be a VLAN pkt, +- * double-check this now that we have the actual +- * packet in hand. +- */ ++ tp_len > dev->mtu + dev->hard_header_len && ++ !packet_extra_vlan_len_allowed(dev, skb)) ++ tp_len = -EMSGSIZE; + +- skb_reset_mac_header(skb); +- ehdr = eth_hdr(skb); +- if (ehdr->h_proto != htons(ETH_P_8021Q)) +- tp_len = -EMSGSIZE; +- } + if (unlikely(tp_len < 0)) { + if (po->tp_loss) { + __packet_set_status(po, ph, +@@ -2757,18 +2755,10 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) + + sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags); + +- if (!gso_type && (len > dev->mtu + reserve + extra_len)) { +- /* Earlier code assumed this would be a VLAN pkt, +- * double-check this now that we have the actual +- * packet in hand. +- */ +- struct ethhdr *ehdr; +- skb_reset_mac_header(skb); +- ehdr = eth_hdr(skb); +- if (ehdr->h_proto != htons(ETH_P_8021Q)) { +- err = -EMSGSIZE; +- goto out_free; +- } ++ if (!gso_type && (len > dev->mtu + reserve + extra_len) && ++ !packet_extra_vlan_len_allowed(dev, skb)) { ++ err = -EMSGSIZE; ++ goto out_free; + } + + skb->protocol = proto; +-- +2.1.0 + + +From 3862137bdee867b99ade815a3c4d966ab223ac6d Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +Date: Wed, 11 Nov 2015 23:25:43 +0100 +Subject: [PATCH 15/43] packet: infer protocol from ethernet header if unset + +[ Upstream commit c72219b75fde768efccf7666342282fab7f9e4e7 ] + +In case no struct sockaddr_ll has been passed to packet +socket's sendmsg() when doing a TX_RING flush run, then +skb->protocol is set to po->num instead, which is the protocol +passed via socket(2)/bind(2). + +Applications only xmitting can go the path of allocating the +socket as socket(PF_PACKET, , 0) and do a bind(2) on the +TX_RING with sll_protocol of 0. That way, register_prot_hook() +is neither called on creation nor on bind time, which saves +cycles when there's no interest in capturing anyway. + +That leaves us however with po->num 0 instead and therefore +the TX_RING flush run sets skb->protocol to 0 as well. Eric +reported that this leads to problems when using tools like +trafgen over bonding device. I.e. the bonding's hash function +could invoke the kernel's flow dissector, which depends on +skb->protocol being properly set. In the current situation, all +the traffic is then directed to a single slave. + +Fix it up by inferring skb->protocol from the Ethernet header +when not set and we have ARPHRD_ETHER device type. This is only +done in case of SOCK_RAW and where we have a dev->hard_header_len +length. In case of ARPHRD_ETHER devices, this is guaranteed to +cover ETH_HLEN, and therefore being accessed on the skb after +the skb_store_bits(). + +Reported-by: Eric Dumazet +Signed-off-by: Daniel Borkmann +Acked-by: Willem de Bruijn +Signed-off-by: David S. Miller +--- + net/packet/af_packet.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index 6e3cd2f..45d4196 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -2338,6 +2338,15 @@ static bool ll_header_truncated(const struct net_device *dev, int len) + return false; + } + ++static void tpacket_set_protocol(const struct net_device *dev, ++ struct sk_buff *skb) ++{ ++ if (dev->type == ARPHRD_ETHER) { ++ skb_reset_mac_header(skb); ++ skb->protocol = eth_hdr(skb)->h_proto; ++ } ++} ++ + static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, + void *frame, struct net_device *dev, int size_max, + __be16 proto, unsigned char *addr, int hlen) +@@ -2419,6 +2428,8 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, + dev->hard_header_len); + if (unlikely(err)) + return err; ++ if (!skb->protocol) ++ tpacket_set_protocol(dev, skb); + + data += dev->hard_header_len; + to_write -= dev->hard_header_len; +-- +2.1.0 + + +From c5cde0ccf91927c87fd06b86d39d580a9244fb57 Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +Date: Wed, 11 Nov 2015 23:25:44 +0100 +Subject: [PATCH 16/43] packet: fix tpacket_snd max frame len + +[ Upstream commit 5cfb4c8d05b4409c4044cb9c05b19705c1d9818b ] + +Since it's introduction in commit 69e3c75f4d54 ("net: TX_RING and +packet mmap"), TX_RING could be used from SOCK_DGRAM and SOCK_RAW +side. When used with SOCK_DGRAM only, the size_max > dev->mtu + +reserve check should have reserve as 0, but currently, this is +unconditionally set (in it's original form as dev->hard_header_len). + +I think this is not correct since tpacket_fill_skb() would then +take dev->mtu and dev->hard_header_len into account for SOCK_DGRAM, +the extra VLAN_HLEN could be possible in both cases. Presumably, the +reserve code was copied from packet_snd(), but later on missed the +check. Make it similar as we have it in packet_snd(). + +Fixes: 69e3c75f4d54 ("net: TX_RING and packet mmap") +Signed-off-by: Daniel Borkmann +Acked-by: Willem de Bruijn +Signed-off-by: David S. Miller +--- + net/packet/af_packet.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index 45d4196..4695a36 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -2510,12 +2510,13 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) + if (unlikely(!(dev->flags & IFF_UP))) + goto out_put; + +- reserve = dev->hard_header_len + VLAN_HLEN; ++ if (po->sk.sk_socket->type == SOCK_RAW) ++ reserve = dev->hard_header_len; + size_max = po->tx_ring.frame_size + - (po->tp_hdrlen - sizeof(struct sockaddr_ll)); + +- if (size_max > dev->mtu + reserve) +- size_max = dev->mtu + reserve; ++ if (size_max > dev->mtu + reserve + VLAN_HLEN) ++ size_max = dev->mtu + reserve + VLAN_HLEN; + + do { + ph = packet_current_frame(po, &po->tx_ring, +@@ -2542,7 +2543,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) + tp_len = tpacket_fill_skb(po, skb, ph, dev, size_max, proto, + addr, hlen); + if (likely(tp_len >= 0) && +- tp_len > dev->mtu + dev->hard_header_len && ++ tp_len > dev->mtu + reserve && + !packet_extra_vlan_len_allowed(dev, skb)) + tp_len = -EMSGSIZE; + +-- +2.1.0 + + +From 93d8395a99eefdd3b470cf9c04e947c6cb8bb85a Mon Sep 17 00:00:00 2001 +From: lucien +Date: Thu, 12 Nov 2015 13:07:07 +0800 +Subject: [PATCH 17/43] sctp: translate host order to network order when + setting a hmacid + +[ Upstream commit ed5a377d87dc4c87fb3e1f7f698cba38cd893103 ] + +now sctp auth cannot work well when setting a hmacid manually, which +is caused by that we didn't use the network order for hmacid, so fix +it by adding the transformation in sctp_auth_ep_set_hmacs. + +even we set hmacid with the network order in userspace, it still +can't work, because of this condition in sctp_auth_ep_set_hmacs(): + + if (id > SCTP_AUTH_HMAC_ID_MAX) + return -EOPNOTSUPP; + +so this wasn't working before and thus it won't break compatibility. + +Fixes: 65b07e5d0d09 ("[SCTP]: API updates to suport SCTP-AUTH extensions.") +Signed-off-by: Xin Long +Signed-off-by: Marcelo Ricardo Leitner +Acked-by: Neil Horman +Acked-by: Vlad Yasevich +Signed-off-by: David S. Miller +--- + net/sctp/auth.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/net/sctp/auth.c b/net/sctp/auth.c +index 4f15b7d..1543e39 100644 +--- a/net/sctp/auth.c ++++ b/net/sctp/auth.c +@@ -809,8 +809,8 @@ int sctp_auth_ep_set_hmacs(struct sctp_endpoint *ep, + if (!has_sha1) + return -EINVAL; + +- memcpy(ep->auth_hmacs_list->hmac_ids, &hmacs->shmac_idents[0], +- hmacs->shmac_num_idents * sizeof(__u16)); ++ for (i = 0; i < hmacs->shmac_num_idents; i++) ++ ep->auth_hmacs_list->hmac_ids[i] = htons(hmacs->shmac_idents[i]); + ep->auth_hmacs_list->param_hdr.length = htons(sizeof(sctp_paramhdr_t) + + hmacs->shmac_num_idents * sizeof(__u16)); + return 0; +-- +2.1.0 + + +From d53e3dbdedfaa2e1e0fd8b37a5e34b0df8a295c5 Mon Sep 17 00:00:00 2001 +From: Tariq Toukan +Date: Thu, 12 Nov 2015 19:35:26 +0200 +Subject: [PATCH 18/43] net/mlx5e: Added self loopback prevention + +[ Upstream commit 66189961e986e53ae39822898fc2ce88f44c61bb ] + +Prevent outgoing multicast frames from looping back to the RX queue. + +By introducing new HW capability self_lb_en_modifiable, which indicates +the support to modify self_lb_en bit in modify_tir command. + +When this capability is set we can prevent TIRs from sending back +loopback multicast traffic to their own RQs, by "refreshing TIRs" with +modify_tir command, on every time new channels (SQs/RQs) are created at +device open. +This is needed since TIRs are static and only allocated once on driver +load, and the loopback decision is under their responsibility. + +Fixes issues of the kind: +"IPv6: eth2: IPv6 duplicate address fe80::e61d:2dff:fe5c:f2e9 detected!" +The issue is seen since the IPv6 solicitations multicast messages are +loopedback and the network stack thinks they are coming from another host. + +Fixes: 5c50368f3831 ("net/mlx5e: Light-weight netdev open/stop") +Signed-off-by: Tariq Toukan +Signed-off-by: Saeed Mahameed +Signed-off-by: Or Gerlitz +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 56 ++++++++++++++++++++++- + include/linux/mlx5/mlx5_ifc.h | 24 ++++++---- + 2 files changed, 68 insertions(+), 12 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +index 59874d6..443632d 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +@@ -1332,6 +1332,42 @@ static int mlx5e_modify_tir_lro(struct mlx5e_priv *priv, int tt) + return err; + } + ++static int mlx5e_refresh_tir_self_loopback_enable(struct mlx5_core_dev *mdev, ++ u32 tirn) ++{ ++ void *in; ++ int inlen; ++ int err; ++ ++ inlen = MLX5_ST_SZ_BYTES(modify_tir_in); ++ in = mlx5_vzalloc(inlen); ++ if (!in) ++ return -ENOMEM; ++ ++ MLX5_SET(modify_tir_in, in, bitmask.self_lb_en, 1); ++ ++ err = mlx5_core_modify_tir(mdev, tirn, in, inlen); ++ ++ kvfree(in); ++ ++ return err; ++} ++ ++static int mlx5e_refresh_tirs_self_loopback_enable(struct mlx5e_priv *priv) ++{ ++ int err; ++ int i; ++ ++ for (i = 0; i < MLX5E_NUM_TT; i++) { ++ err = mlx5e_refresh_tir_self_loopback_enable(priv->mdev, ++ priv->tirn[i]); ++ if (err) ++ return err; ++ } ++ ++ return 0; ++} ++ + static int mlx5e_set_dev_port_mtu(struct net_device *netdev) + { + struct mlx5e_priv *priv = netdev_priv(netdev); +@@ -1367,13 +1403,20 @@ int mlx5e_open_locked(struct net_device *netdev) + + err = mlx5e_set_dev_port_mtu(netdev); + if (err) +- return err; ++ goto err_clear_state_opened_flag; + + err = mlx5e_open_channels(priv); + if (err) { + netdev_err(netdev, "%s: mlx5e_open_channels failed, %d\n", + __func__, err); +- return err; ++ goto err_clear_state_opened_flag; ++ } ++ ++ err = mlx5e_refresh_tirs_self_loopback_enable(priv); ++ if (err) { ++ netdev_err(netdev, "%s: mlx5e_refresh_tirs_self_loopback_enable failed, %d\n", ++ __func__, err); ++ goto err_close_channels; + } + + mlx5e_update_carrier(priv); +@@ -1382,6 +1425,12 @@ int mlx5e_open_locked(struct net_device *netdev) + schedule_delayed_work(&priv->update_stats_work, 0); + + return 0; ++ ++err_close_channels: ++ mlx5e_close_channels(priv); ++err_clear_state_opened_flag: ++ clear_bit(MLX5E_STATE_OPENED, &priv->state); ++ return err; + } + + static int mlx5e_open(struct net_device *netdev) +@@ -1899,6 +1948,9 @@ static int mlx5e_check_required_hca_cap(struct mlx5_core_dev *mdev) + "Not creating net device, some required device capabilities are missing\n"); + return -ENOTSUPP; + } ++ if (!MLX5_CAP_ETH(mdev, self_lb_en_modifiable)) ++ mlx5_core_warn(mdev, "Self loop back prevention is not supported\n"); ++ + return 0; + } + +diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h +index dd20974..1565324 100644 +--- a/include/linux/mlx5/mlx5_ifc.h ++++ b/include/linux/mlx5/mlx5_ifc.h +@@ -453,26 +453,28 @@ struct mlx5_ifc_per_protocol_networking_offload_caps_bits { + u8 lro_cap[0x1]; + u8 lro_psh_flag[0x1]; + u8 lro_time_stamp[0x1]; +- u8 reserved_0[0x6]; ++ u8 reserved_0[0x3]; ++ u8 self_lb_en_modifiable[0x1]; ++ u8 reserved_1[0x2]; + u8 max_lso_cap[0x5]; +- u8 reserved_1[0x4]; ++ u8 reserved_2[0x4]; + u8 rss_ind_tbl_cap[0x4]; +- u8 reserved_2[0x3]; ++ u8 reserved_3[0x3]; + u8 tunnel_lso_const_out_ip_id[0x1]; +- u8 reserved_3[0x2]; ++ u8 reserved_4[0x2]; + u8 tunnel_statless_gre[0x1]; + u8 tunnel_stateless_vxlan[0x1]; + +- u8 reserved_4[0x20]; ++ u8 reserved_5[0x20]; + +- u8 reserved_5[0x10]; ++ u8 reserved_6[0x10]; + u8 lro_min_mss_size[0x10]; + +- u8 reserved_6[0x120]; ++ u8 reserved_7[0x120]; + + u8 lro_timer_supported_periods[4][0x20]; + +- u8 reserved_7[0x600]; ++ u8 reserved_8[0x600]; + }; + + struct mlx5_ifc_roce_cap_bits { +@@ -4051,9 +4053,11 @@ struct mlx5_ifc_modify_tis_in_bits { + }; + + struct mlx5_ifc_modify_tir_bitmask_bits { +- u8 reserved[0x20]; ++ u8 reserved_0[0x20]; + +- u8 reserved1[0x1f]; ++ u8 reserved_1[0x1b]; ++ u8 self_lb_en[0x1]; ++ u8 reserved_2[0x3]; + u8 lro[0x1]; + }; + +-- +2.1.0 + + +From 752f833f18bc5af0d0f5172cbeb554cf9b836311 Mon Sep 17 00:00:00 2001 +From: Eran Ben Elisha +Date: Thu, 12 Nov 2015 19:35:29 +0200 +Subject: [PATCH 19/43] net/mlx4_core: Fix sleeping while holding spinlock at + rem_slave_counters + +[ Upstream commit f5adbfee72282bb1f456d52b04adacd4fe6ac502 ] + +When cleaning slave's counter resources, we hold a spinlock that +protects the slave's counters list. As part of the clean, we call +__mlx4_clear_if_stat which calls mlx4_alloc_cmd_mailbox which is a +sleepable function. + +In order to fix this issue, hold the spinlock, and copy all counter +indices into a temporary array, and release the spinlock. Afterwards, +iterate over this array and free every counter. Repeat this scenario +until the original list is empty (a new counter might have been added +while releasing the counters from the temporary array). + +Fixes: b72ca7e96acf ("net/mlx4_core: Reset counters data when freed") +Reported-by: Moni Shoua +Tested-by: Moni Shoua +Signed-off-by: Jack Morgenstein +Signed-off-by: Eran Ben Elisha +Signed-off-by: Or Gerlitz +Signed-off-by: David S. Miller +--- + .../net/ethernet/mellanox/mlx4/resource_tracker.c | 39 +++++++++++++++------- + 1 file changed, 27 insertions(+), 12 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +index 731423c..8bead97 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c ++++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +@@ -4934,26 +4934,41 @@ static void rem_slave_counters(struct mlx4_dev *dev, int slave) + struct res_counter *counter; + struct res_counter *tmp; + int err; +- int index; ++ int *counters_arr = NULL; ++ int i, j; + + err = move_all_busy(dev, slave, RES_COUNTER); + if (err) + mlx4_warn(dev, "rem_slave_counters: Could not move all counters - too busy for slave %d\n", + slave); + +- spin_lock_irq(mlx4_tlock(dev)); +- list_for_each_entry_safe(counter, tmp, counter_list, com.list) { +- if (counter->com.owner == slave) { +- index = counter->com.res_id; +- rb_erase(&counter->com.node, +- &tracker->res_tree[RES_COUNTER]); +- list_del(&counter->com.list); +- kfree(counter); +- __mlx4_counter_free(dev, index); ++ counters_arr = kmalloc_array(dev->caps.max_counters, ++ sizeof(*counters_arr), GFP_KERNEL); ++ if (!counters_arr) ++ return; ++ ++ do { ++ i = 0; ++ j = 0; ++ spin_lock_irq(mlx4_tlock(dev)); ++ list_for_each_entry_safe(counter, tmp, counter_list, com.list) { ++ if (counter->com.owner == slave) { ++ counters_arr[i++] = counter->com.res_id; ++ rb_erase(&counter->com.node, ++ &tracker->res_tree[RES_COUNTER]); ++ list_del(&counter->com.list); ++ kfree(counter); ++ } ++ } ++ spin_unlock_irq(mlx4_tlock(dev)); ++ ++ while (j < i) { ++ __mlx4_counter_free(dev, counters_arr[j++]); + mlx4_release_resource(dev, slave, RES_COUNTER, 1, 0); + } +- } +- spin_unlock_irq(mlx4_tlock(dev)); ++ } while (i); ++ ++ kfree(counters_arr); + } + + static void rem_slave_xrcdns(struct mlx4_dev *dev, int slave) +-- +2.1.0 + + +From 30de3861d01de70551c41529a9933cc2d3221c7b Mon Sep 17 00:00:00 2001 +From: "Jason A. Donenfeld" +Date: Thu, 12 Nov 2015 17:35:58 +0100 +Subject: [PATCH 20/43] ip_tunnel: disable preemption when updating per-cpu + tstats + +[ Upstream commit b4fe85f9c9146f60457e9512fb6055e69e6a7a65 ] + +Drivers like vxlan use the recently introduced +udp_tunnel_xmit_skb/udp_tunnel6_xmit_skb APIs. udp_tunnel6_xmit_skb +makes use of ip6tunnel_xmit, and ip6tunnel_xmit, after sending the +packet, updates the struct stats using the usual +u64_stats_update_begin/end calls on this_cpu_ptr(dev->tstats). +udp_tunnel_xmit_skb makes use of iptunnel_xmit, which doesn't touch +tstats, so drivers like vxlan, immediately after, call +iptunnel_xmit_stats, which does the same thing - calls +u64_stats_update_begin/end on this_cpu_ptr(dev->tstats). + +While vxlan is probably fine (I don't know?), calling a similar function +from, say, an unbound workqueue, on a fully preemptable kernel causes +real issues: + +[ 188.434537] BUG: using smp_processor_id() in preemptible [00000000] code: kworker/u8:0/6 +[ 188.435579] caller is debug_smp_processor_id+0x17/0x20 +[ 188.435583] CPU: 0 PID: 6 Comm: kworker/u8:0 Not tainted 4.2.6 #2 +[ 188.435607] Call Trace: +[ 188.435611] [] dump_stack+0x4f/0x7b +[ 188.435615] [] check_preemption_disabled+0x19d/0x1c0 +[ 188.435619] [] debug_smp_processor_id+0x17/0x20 + +The solution would be to protect the whole +this_cpu_ptr(dev->tstats)/u64_stats_update_begin/end blocks with +disabling preemption and then reenabling it. + +Signed-off-by: Jason A. Donenfeld +Acked-by: Hannes Frederic Sowa +Signed-off-by: David S. Miller +--- + include/net/ip6_tunnel.h | 3 ++- + include/net/ip_tunnels.h | 3 ++- + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/include/net/ip6_tunnel.h b/include/net/ip6_tunnel.h +index fa915fa..d49a8f8 100644 +--- a/include/net/ip6_tunnel.h ++++ b/include/net/ip6_tunnel.h +@@ -90,11 +90,12 @@ static inline void ip6tunnel_xmit(struct sock *sk, struct sk_buff *skb, + err = ip6_local_out_sk(sk, skb); + + if (net_xmit_eval(err) == 0) { +- struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats); ++ struct pcpu_sw_netstats *tstats = get_cpu_ptr(dev->tstats); + u64_stats_update_begin(&tstats->syncp); + tstats->tx_bytes += pkt_len; + tstats->tx_packets++; + u64_stats_update_end(&tstats->syncp); ++ put_cpu_ptr(tstats); + } else { + stats->tx_errors++; + stats->tx_aborted_errors++; +diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h +index f6dafec..62a750a 100644 +--- a/include/net/ip_tunnels.h ++++ b/include/net/ip_tunnels.h +@@ -287,12 +287,13 @@ static inline void iptunnel_xmit_stats(int err, + struct pcpu_sw_netstats __percpu *stats) + { + if (err > 0) { +- struct pcpu_sw_netstats *tstats = this_cpu_ptr(stats); ++ struct pcpu_sw_netstats *tstats = get_cpu_ptr(stats); + + u64_stats_update_begin(&tstats->syncp); + tstats->tx_bytes += err; + tstats->tx_packets++; + u64_stats_update_end(&tstats->syncp); ++ put_cpu_ptr(tstats); + } else if (err < 0) { + err_stats->tx_errors++; + err_stats->tx_aborted_errors++; +-- +2.1.0 + + +From b532a633740a46806a53d618634ff1169c5e9a4b Mon Sep 17 00:00:00 2001 +From: Dragos Tatulea +Date: Mon, 16 Nov 2015 10:52:48 +0100 +Subject: [PATCH 21/43] net: switchdev: fix return code of fdb_dump stub + +[ Upstream commit 24cb7055a3066634a0f3fa0cd6a4780652905d35 ] + +rtnl_fdb_dump always expects an index to be returned by the ndo_fdb_dump op, +but when CONFIG_NET_SWITCHDEV is off, it returns an error. + +Fix that by returning the given unmodified idx. + +A similar fix was 0890cf6cb6ab ("switchdev: fix return value of +switchdev_port_fdb_dump in case of error") but for the CONFIG_NET_SWITCHDEV=y +case. + +Fixes: 45d4122ca7cd ("switchdev: add support for fdb add/del/dump via switchdev_port_obj ops.") +Signed-off-by: Dragos Tatulea +Acked-by: Jiri Pirko +Signed-off-by: David S. Miller +--- + include/net/switchdev.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/net/switchdev.h b/include/net/switchdev.h +index 319baab..731c40e 100644 +--- a/include/net/switchdev.h ++++ b/include/net/switchdev.h +@@ -272,7 +272,7 @@ static inline int switchdev_port_fdb_dump(struct sk_buff *skb, + struct net_device *filter_dev, + int idx) + { +- return -EOPNOTSUPP; ++ return idx; + } + + static inline void switchdev_port_fwd_mark_set(struct net_device *dev, +-- +2.1.0 + + +From 06416634e5b57f33854a5905bdf87ddc68f99ff4 Mon Sep 17 00:00:00 2001 +From: Pavel Fedin +Date: Mon, 16 Nov 2015 17:51:34 +0300 +Subject: [PATCH 22/43] net: thunder: Check for driver data in nicvf_remove() + +[ Upstream commit 7750130d93decff06120df0d8ea024ff8a038a21 ] + +In some cases the crash is caused by nicvf_remove() being called from +outside. For example, if we try to feed the device to vfio after the +probe has failed for some reason. So, move the check to better place. + +Signed-off-by: Pavel Fedin +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/cavium/thunder/nicvf_main.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c +index a937772..7f709cb 100644 +--- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c ++++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c +@@ -1583,8 +1583,14 @@ err_disable_device: + static void nicvf_remove(struct pci_dev *pdev) + { + struct net_device *netdev = pci_get_drvdata(pdev); +- struct nicvf *nic = netdev_priv(netdev); +- struct net_device *pnetdev = nic->pnicvf->netdev; ++ struct nicvf *nic; ++ struct net_device *pnetdev; ++ ++ if (!netdev) ++ return; ++ ++ nic = netdev_priv(netdev); ++ pnetdev = nic->pnicvf->netdev; + + /* Check if this Qset is assigned to different VF. + * If yes, clean primary and all secondary Qsets. +-- +2.1.0 + + +From fba5174af82c781b154aa5ffcc0fad2229767ec5 Mon Sep 17 00:00:00 2001 +From: Neil Horman +Date: Mon, 16 Nov 2015 13:09:10 -0500 +Subject: [PATCH 23/43] snmp: Remove duplicate OUTMCAST stat increment + +[ Upstream commit 41033f029e393a64e81966cbe34d66c6cf8a2e7e ] + +the OUTMCAST stat is double incremented, getting bumped once in the mcast code +itself, and again in the common ip output path. Remove the mcast bump, as its +not needed + +Validated by the reporter, with good results + +Signed-off-by: Neil Horman +Reported-by: Claus Jensen +CC: Claus Jensen +CC: David Miller +Signed-off-by: David S. Miller +--- + net/ipv6/mcast.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c +index 083b292..41e3b5e 100644 +--- a/net/ipv6/mcast.c ++++ b/net/ipv6/mcast.c +@@ -1651,7 +1651,6 @@ out: + if (!err) { + ICMP6MSGOUT_INC_STATS(net, idev, ICMPV6_MLD2_REPORT); + ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS); +- IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUTMCAST, payload_len); + } else { + IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS); + } +@@ -2014,7 +2013,6 @@ out: + if (!err) { + ICMP6MSGOUT_INC_STATS(net, idev, type); + ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS); +- IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUTMCAST, full_len); + } else + IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS); + +-- +2.1.0 + + +From 677298fd534e16274c8859e7658e57864bddb2a9 Mon Sep 17 00:00:00 2001 +From: Paolo Abeni +Date: Wed, 18 Nov 2015 16:40:19 +0100 +Subject: [PATCH 24/43] net/ip6_tunnel: fix dst leak + +[ Upstream commit 206b49500df558dbc15d8836b09f6397ec5ed8bb ] + +the commit cdf3464e6c6b ("ipv6: Fix dst_entry refcnt bugs in ip6_tunnel") +introduced percpu storage for ip6_tunnel dst cache, but while clearing +such cache it used raw_cpu_ptr to walk the per cpu entries, so cached +dst on non current cpu are not actually reset. + +This patch replaces raw_cpu_ptr with per_cpu_ptr, properly cleaning +such storage. + +Fixes: cdf3464e6c6b ("ipv6: Fix dst_entry refcnt bugs in ip6_tunnel") +Signed-off-by: Paolo Abeni +Acked-by: Martin KaFai Lau +Signed-off-by: David S. Miller +--- + net/ipv6/ip6_tunnel.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c +index eabffbb..137fca4 100644 +--- a/net/ipv6/ip6_tunnel.c ++++ b/net/ipv6/ip6_tunnel.c +@@ -177,7 +177,7 @@ void ip6_tnl_dst_reset(struct ip6_tnl *t) + int i; + + for_each_possible_cpu(i) +- ip6_tnl_per_cpu_dst_set(raw_cpu_ptr(t->dst_cache), NULL); ++ ip6_tnl_per_cpu_dst_set(per_cpu_ptr(t->dst_cache, i), NULL); + } + EXPORT_SYMBOL_GPL(ip6_tnl_dst_reset); + +-- +2.1.0 + + +From 1451e186dddbd12331cbbd82cd1ec4df6207d598 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= +Date: Wed, 18 Nov 2015 21:13:07 +0100 +Subject: [PATCH 25/43] net: qmi_wwan: add XS Stick W100-2 from 4G Systems +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +[ Upstream commit 68242a5a1e2edce39b069385cbafb82304eac0f1 ] + +Thomas reports +" +4gsystems sells two total different LTE-surfsticks under the same name. +.. +The newer version of XS Stick W100 is from "omega" +.. +Under windows the driver switches to the same ID, and uses MI03\6 for +network and MI01\6 for modem. +.. +echo "1c9e 9b01" > /sys/bus/usb/drivers/qmi_wwan/new_id +echo "1c9e 9b01" > /sys/bus/usb-serial/drivers/option1/new_id + +T: Bus=01 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=1c9e ProdID=9b01 Rev=02.32 +S: Manufacturer=USB Modem +S: Product=USB Modem +S: SerialNumber= +C: #Ifs= 5 Cfg#= 1 Atr=80 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=ff Prot=ff Driver=option +I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=option +I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan +I: If#= 4 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage + +Now all important things are there: + +wwp0s29f7u2i3 (net), ttyUSB2 (at), cdc-wdm0 (qmi), ttyUSB1 (at) + +There is also ttyUSB0, but it is not usable, at least not for at. + +The device works well with qmi and ModemManager-NetworkManager. +" + +Reported-by: Thomas Schäfer +Signed-off-by: Bjørn Mork +Signed-off-by: David S. Miller +--- + drivers/net/usb/qmi_wwan.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c +index 2a7c1be..66e0853 100644 +--- a/drivers/net/usb/qmi_wwan.c ++++ b/drivers/net/usb/qmi_wwan.c +@@ -775,6 +775,7 @@ static const struct usb_device_id products[] = { + {QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */ + {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */ + {QMI_FIXED_INTF(0x1bc7, 0x1201, 2)}, /* Telit LE920 */ ++ {QMI_FIXED_INTF(0x1c9e, 0x9b01, 3)}, /* XS Stick W100-2 from 4G Systems */ + {QMI_FIXED_INTF(0x0b3c, 0xc000, 4)}, /* Olivetti Olicard 100 */ + {QMI_FIXED_INTF(0x0b3c, 0xc001, 4)}, /* Olivetti Olicard 120 */ + {QMI_FIXED_INTF(0x0b3c, 0xc002, 4)}, /* Olivetti Olicard 140 */ +-- +2.1.0 + + +From c137397256ef9502cfba4de0fa77f850ed0ad7a6 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Wed, 18 Nov 2015 12:40:13 -0800 +Subject: [PATCH 26/43] tcp: md5: fix lockdep annotation + +[ Upstream commit 1b8e6a01e19f001e9f93b39c32387961c91ed3cc ] + +When a passive TCP is created, we eventually call tcp_md5_do_add() +with sk pointing to the child. It is not owner by the user yet (we +will add this socket into listener accept queue a bit later anyway) + +But we do own the spinlock, so amend the lockdep annotation to avoid +following splat : + +[ 8451.090932] net/ipv4/tcp_ipv4.c:923 suspicious rcu_dereference_protected() usage! +[ 8451.090932] +[ 8451.090932] other info that might help us debug this: +[ 8451.090932] +[ 8451.090934] +[ 8451.090934] rcu_scheduler_active = 1, debug_locks = 1 +[ 8451.090936] 3 locks held by socket_sockopt_/214795: +[ 8451.090936] #0: (rcu_read_lock){.+.+..}, at: [] __netif_receive_skb_core+0x151/0xe90 +[ 8451.090947] #1: (rcu_read_lock){.+.+..}, at: [] ip_local_deliver_finish+0x43/0x2b0 +[ 8451.090952] #2: (slock-AF_INET){+.-...}, at: [] sk_clone_lock+0x1c5/0x500 +[ 8451.090958] +[ 8451.090958] stack backtrace: +[ 8451.090960] CPU: 7 PID: 214795 Comm: socket_sockopt_ + +[ 8451.091215] Call Trace: +[ 8451.091216] [] dump_stack+0x55/0x76 +[ 8451.091229] [] lockdep_rcu_suspicious+0xeb/0x110 +[ 8451.091235] [] tcp_md5_do_add+0x1bf/0x1e0 +[ 8451.091239] [] tcp_v4_syn_recv_sock+0x1f1/0x4c0 +[ 8451.091242] [] ? tcp_v4_md5_hash_skb+0x167/0x190 +[ 8451.091246] [] tcp_check_req+0x3c8/0x500 +[ 8451.091249] [] ? tcp_v4_inbound_md5_hash+0x11e/0x190 +[ 8451.091253] [] tcp_v4_rcv+0x3c0/0x9f0 +[ 8451.091256] [] ? ip_local_deliver_finish+0x43/0x2b0 +[ 8451.091260] [] ip_local_deliver_finish+0xb6/0x2b0 +[ 8451.091263] [] ? ip_local_deliver_finish+0x43/0x2b0 +[ 8451.091267] [] ip_local_deliver+0x48/0x80 +[ 8451.091270] [] ip_rcv_finish+0x160/0x700 +[ 8451.091273] [] ip_rcv+0x29e/0x3d0 +[ 8451.091277] [] __netif_receive_skb_core+0xb47/0xe90 + +Fixes: a8afca0329988 ("tcp: md5: protects md5sig_info with RCU") +Signed-off-by: Eric Dumazet +Reported-by: Willem de Bruijn +Signed-off-by: David S. Miller +--- + net/ipv4/tcp_ipv4.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c +index 93898e0..a7739c8 100644 +--- a/net/ipv4/tcp_ipv4.c ++++ b/net/ipv4/tcp_ipv4.c +@@ -922,7 +922,8 @@ int tcp_md5_do_add(struct sock *sk, const union tcp_md5_addr *addr, + } + + md5sig = rcu_dereference_protected(tp->md5sig_info, +- sock_owned_by_user(sk)); ++ sock_owned_by_user(sk) || ++ lockdep_is_held(&sk->sk_lock.slock)); + if (!md5sig) { + md5sig = kmalloc(sizeof(*md5sig), gfp); + if (!md5sig) +-- +2.1.0 + + +From 9a9201e594f1e328a927ea12f672a3541b03d797 Mon Sep 17 00:00:00 2001 +From: Yuchung Cheng +Date: Wed, 18 Nov 2015 18:17:30 -0800 +Subject: [PATCH 27/43] tcp: disable Fast Open on timeouts after handshake + +[ Upstream commit 0e45f4da5981895e885dd72fe912a3f8e32bae73 ] + +Some middle-boxes black-hole the data after the Fast Open handshake +(https://www.ietf.org/proceedings/94/slides/slides-94-tcpm-13.pdf). +The exact reason is unknown. The work-around is to disable Fast Open +temporarily after multiple recurring timeouts with few or no data +delivered in the established state. + +Signed-off-by: Yuchung Cheng +Signed-off-by: Eric Dumazet +Reported-by: Christoph Paasch +Signed-off-by: David S. Miller +--- + net/ipv4/tcp_timer.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c +index 7149ebc..04f0a05 100644 +--- a/net/ipv4/tcp_timer.c ++++ b/net/ipv4/tcp_timer.c +@@ -176,6 +176,18 @@ static int tcp_write_timeout(struct sock *sk) + syn_set = true; + } else { + if (retransmits_timed_out(sk, sysctl_tcp_retries1, 0, 0)) { ++ /* Some middle-boxes may black-hole Fast Open _after_ ++ * the handshake. Therefore we conservatively disable ++ * Fast Open on this path on recurring timeouts with ++ * few or zero bytes acked after Fast Open. ++ */ ++ if (tp->syn_data_acked && ++ tp->bytes_acked <= tp->rx_opt.mss_clamp) { ++ tcp_fastopen_cache_set(sk, 0, NULL, true, 0); ++ if (icsk->icsk_retransmits == sysctl_tcp_retries1) ++ NET_INC_STATS_BH(sock_net(sk), ++ LINUX_MIB_TCPFASTOPENACTIVEFAIL); ++ } + /* Black hole detection */ + tcp_mtu_probing(icsk, sk); + +-- +2.1.0 + + +From fc6c61249dd9e249b96291b83c0751b441cda8de Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Wed, 18 Nov 2015 21:03:33 -0800 +Subject: [PATCH 28/43] tcp: fix potential huge kmalloc() calls in TCP_REPAIR + +[ Upstream commit 5d4c9bfbabdb1d497f21afd81501e5c54b0c85d9 ] + +tcp_send_rcvq() is used for re-injecting data into tcp receive queue. + +Problems : + +- No check against size is performed, allowed user to fool kernel in + attempting very large memory allocations, eventually triggering + OOM when memory is fragmented. + +- In case of fault during the copy we do not return correct errno. + +Lets use alloc_skb_with_frags() to cook optimal skbs. + +Fixes: 292e8d8c8538 ("tcp: Move rcvq sending to tcp_input.c") +Fixes: c0e88ff0f256 ("tcp: Repair socket queues") +Signed-off-by: Eric Dumazet +Cc: Pavel Emelyanov +Acked-by: Pavel Emelyanov +Signed-off-by: David S. Miller +--- + net/ipv4/tcp_input.c | 22 +++++++++++++++++++--- + 1 file changed, 19 insertions(+), 3 deletions(-) + +diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c +index a8f515b..cc6bd43 100644 +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -4457,19 +4457,34 @@ static int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, int + int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size) + { + struct sk_buff *skb; ++ int err = -ENOMEM; ++ int data_len = 0; + bool fragstolen; + + if (size == 0) + return 0; + +- skb = alloc_skb(size, sk->sk_allocation); ++ if (size > PAGE_SIZE) { ++ int npages = min_t(size_t, size >> PAGE_SHIFT, MAX_SKB_FRAGS); ++ ++ data_len = npages << PAGE_SHIFT; ++ size = data_len + (size & ~PAGE_MASK); ++ } ++ skb = alloc_skb_with_frags(size - data_len, data_len, ++ PAGE_ALLOC_COSTLY_ORDER, ++ &err, sk->sk_allocation); + if (!skb) + goto err; + ++ skb_put(skb, size - data_len); ++ skb->data_len = data_len; ++ skb->len = size; ++ + if (tcp_try_rmem_schedule(sk, skb, skb->truesize)) + goto err_free; + +- if (memcpy_from_msg(skb_put(skb, size), msg, size)) ++ err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, size); ++ if (err) + goto err_free; + + TCP_SKB_CB(skb)->seq = tcp_sk(sk)->rcv_nxt; +@@ -4485,7 +4500,8 @@ int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size) + err_free: + kfree_skb(skb); + err: +- return -ENOMEM; ++ return err; ++ + } + + static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) +-- +2.1.0 + + +From 419ee3eb1d6dea668f00ee440c670f8f479f8216 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Thu, 26 Nov 2015 08:18:14 -0800 +Subject: [PATCH 29/43] tcp: initialize tp->copied_seq in case of cross SYN + connection + +[ Upstream commit 142a2e7ece8d8ac0e818eb2c91f99ca894730e2a ] + +Dmitry provided a syzkaller (http://github.com/google/syzkaller) +generated program that triggers the WARNING at +net/ipv4/tcp.c:1729 in tcp_recvmsg() : + +WARN_ON(tp->copied_seq != tp->rcv_nxt && + !(flags & (MSG_PEEK | MSG_TRUNC))); + +His program is specifically attempting a Cross SYN TCP exchange, +that we support (for the pleasure of hackers ?), but it looks we +lack proper tcp->copied_seq initialization. + +Thanks again Dmitry for your report and testings. + +Signed-off-by: Eric Dumazet +Reported-by: Dmitry Vyukov +Tested-by: Dmitry Vyukov +Signed-off-by: David S. Miller +--- + net/ipv4/tcp_input.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c +index cc6bd43..0a2b61d 100644 +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -5659,6 +5659,7 @@ discard: + } + + tp->rcv_nxt = TCP_SKB_CB(skb)->seq + 1; ++ tp->copied_seq = tp->rcv_nxt; + tp->rcv_wup = TCP_SKB_CB(skb)->seq + 1; + + /* RFC1323: The window in SYN & SYN/ACK segments is +-- +2.1.0 + + +From 4d8baf23458211113b2b4aaac26d715a1cfa9a4f Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +Date: Fri, 20 Nov 2015 00:11:56 +0100 +Subject: [PATCH 30/43] net, scm: fix PaX detected msg_controllen overflow in + scm_detach_fds + +[ Upstream commit 6900317f5eff0a7070c5936e5383f589e0de7a09 ] + +David and HacKurx reported a following/similar size overflow triggered +in a grsecurity kernel, thanks to PaX's gcc size overflow plugin: + +(Already fixed in later grsecurity versions by Brad and PaX Team.) + +[ 1002.296137] PAX: size overflow detected in function scm_detach_fds net/core/scm.c:314 + cicus.202_127 min, count: 4, decl: msg_controllen; num: 0; context: msghdr; +[ 1002.296145] CPU: 0 PID: 3685 Comm: scm_rights_recv Not tainted 4.2.3-grsec+ #7 +[ 1002.296149] Hardware name: Apple Inc. MacBookAir5,1/Mac-66F35F19FE2A0D05, [...] +[ 1002.296153] ffffffff81c27366 0000000000000000 ffffffff81c27375 ffffc90007843aa8 +[ 1002.296162] ffffffff818129ba 0000000000000000 ffffffff81c27366 ffffc90007843ad8 +[ 1002.296169] ffffffff8121f838 fffffffffffffffc fffffffffffffffc ffffc90007843e60 +[ 1002.296176] Call Trace: +[ 1002.296190] [] dump_stack+0x45/0x57 +[ 1002.296200] [] report_size_overflow+0x38/0x60 +[ 1002.296209] [] scm_detach_fds+0x2ce/0x300 +[ 1002.296220] [] unix_stream_read_generic+0x609/0x930 +[ 1002.296228] [] unix_stream_recvmsg+0x4f/0x60 +[ 1002.296236] [] ? unix_set_peek_off+0x50/0x50 +[ 1002.296243] [] sock_recvmsg+0x47/0x60 +[ 1002.296248] [] ___sys_recvmsg+0xe2/0x1e0 +[ 1002.296257] [] __sys_recvmsg+0x46/0x80 +[ 1002.296263] [] SyS_recvmsg+0x2c/0x40 +[ 1002.296271] [] entry_SYSCALL_64_fastpath+0x12/0x85 + +Further investigation showed that this can happen when an *odd* number of +fds are being passed over AF_UNIX sockets. + +In these cases CMSG_LEN(i * sizeof(int)) and CMSG_SPACE(i * sizeof(int)), +where i is the number of successfully passed fds, differ by 4 bytes due +to the extra CMSG_ALIGN() padding in CMSG_SPACE() to an 8 byte boundary +on 64 bit. The padding is used to align subsequent cmsg headers in the +control buffer. + +When the control buffer passed in from the receiver side *lacks* these 4 +bytes (e.g. due to buggy/wrong API usage), then msg->msg_controllen will +overflow in scm_detach_fds(): + + int cmlen = CMSG_LEN(i * sizeof(int)); <--- cmlen w/o tail-padding + err = put_user(SOL_SOCKET, &cm->cmsg_level); + if (!err) + err = put_user(SCM_RIGHTS, &cm->cmsg_type); + if (!err) + err = put_user(cmlen, &cm->cmsg_len); + if (!err) { + cmlen = CMSG_SPACE(i * sizeof(int)); <--- cmlen w/ 4 byte extra tail-padding + msg->msg_control += cmlen; + msg->msg_controllen -= cmlen; <--- iff no tail-padding space here ... + } ... wrap-around + +F.e. it will wrap to a length of 18446744073709551612 bytes in case the +receiver passed in msg->msg_controllen of 20 bytes, and the sender +properly transferred 1 fd to the receiver, so that its CMSG_LEN results +in 20 bytes and CMSG_SPACE in 24 bytes. + +In case of MSG_CMSG_COMPAT (scm_detach_fds_compat()), I haven't seen an +issue in my tests as alignment seems always on 4 byte boundary. Same +should be in case of native 32 bit, where we end up with 4 byte boundaries +as well. + +In practice, passing msg->msg_controllen of 20 to recvmsg() while receiving +a single fd would mean that on successful return, msg->msg_controllen is +being set by the kernel to 24 bytes instead, thus more than the input +buffer advertised. It could f.e. become an issue if such application later +on zeroes or copies the control buffer based on the returned msg->msg_controllen +elsewhere. + +Maximum number of fds we can send is a hard upper limit SCM_MAX_FD (253). + +Going over the code, it seems like msg->msg_controllen is not being read +after scm_detach_fds() in scm_recv() anymore by the kernel, good! + +Relevant recvmsg() handler are unix_dgram_recvmsg() (unix_seqpacket_recvmsg()) +and unix_stream_recvmsg(). Both return back to their recvmsg() caller, +and ___sys_recvmsg() places the updated length, that is, new msg_control - +old msg_control pointer into msg->msg_controllen (hence the 24 bytes seen +in the example). + +Long time ago, Wei Yongjun fixed something related in commit 1ac70e7ad24a +("[NET]: Fix function put_cmsg() which may cause usr application memory +overflow"). + +RFC3542, section 20.2. says: + + The fields shown as "XX" are possible padding, between the cmsghdr + structure and the data, and between the data and the next cmsghdr + structure, if required by the implementation. While sending an + application may or may not include padding at the end of last + ancillary data in msg_controllen and implementations must accept both + as valid. On receiving a portable application must provide space for + padding at the end of the last ancillary data as implementations may + copy out the padding at the end of the control message buffer and + include it in the received msg_controllen. When recvmsg() is called + if msg_controllen is too small for all the ancillary data items + including any trailing padding after the last item an implementation + may set MSG_CTRUNC. + +Since we didn't place MSG_CTRUNC for already quite a long time, just do +the same as in 1ac70e7ad24a to avoid an overflow. + +Btw, even man-page author got this wrong :/ See db939c9b26e9 ("cmsg.3: Fix +error in SCM_RIGHTS code sample"). Some people must have copied this (?), +thus it got triggered in the wild (reported several times during boot by +David and HacKurx). + +No Fixes tag this time as pre 2002 (that is, pre history tree). + +Reported-by: David Sterba +Reported-by: HacKurx +Cc: PaX Team +Cc: Emese Revfy +Cc: Brad Spengler +Cc: Wei Yongjun +Cc: Eric Dumazet +Reviewed-by: Hannes Frederic Sowa +Signed-off-by: Daniel Borkmann +Signed-off-by: David S. Miller +--- + net/core/scm.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/net/core/scm.c b/net/core/scm.c +index 3b6899b..8a1741b 100644 +--- a/net/core/scm.c ++++ b/net/core/scm.c +@@ -305,6 +305,8 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm) + err = put_user(cmlen, &cm->cmsg_len); + if (!err) { + cmlen = CMSG_SPACE(i*sizeof(int)); ++ if (msg->msg_controllen < cmlen) ++ cmlen = msg->msg_controllen; + msg->msg_control += cmlen; + msg->msg_controllen -= cmlen; + } +-- +2.1.0 + + +From fd10116065e9a7bde6eb70f3f69c5e9ec2722e2e Mon Sep 17 00:00:00 2001 +From: Nikolay Aleksandrov +Date: Fri, 20 Nov 2015 13:54:19 +0100 +Subject: [PATCH 31/43] net: ipmr: fix static mfc/dev leaks on table + destruction + +[ Upstream commit 0e615e9601a15efeeb8942cf7cd4dadba0c8c5a7 ] + +When destroying an mrt table the static mfc entries and the static +devices are kept, which leads to devices that can never be destroyed +(because of refcnt taken) and leaked memory, for example: +unreferenced object 0xffff880034c144c0 (size 192): + comm "mfc-broken", pid 4777, jiffies 4320349055 (age 46001.964s) + hex dump (first 32 bytes): + 98 53 f0 34 00 88 ff ff 98 53 f0 34 00 88 ff ff .S.4.....S.4.... + ef 0a 0a 14 01 02 03 04 00 00 00 00 01 00 00 00 ................ + backtrace: + [] kmemleak_alloc+0x4e/0xb0 + [] kmem_cache_alloc+0x190/0x300 + [] ip_mroute_setsockopt+0x5cb/0x910 + [] do_ip_setsockopt.isra.11+0x105/0xff0 + [] ip_setsockopt+0x30/0xa0 + [] raw_setsockopt+0x33/0x90 + [] sock_common_setsockopt+0x14/0x20 + [] SyS_setsockopt+0x71/0xc0 + [] entry_SYSCALL_64_fastpath+0x16/0x7a + [] 0xffffffffffffffff + +Make sure that everything is cleaned on netns destruction. + +Signed-off-by: Nikolay Aleksandrov +Reviewed-by: Cong Wang +Signed-off-by: David S. Miller +--- + net/ipv4/ipmr.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c +index 8e8203d..ef7e2c4 100644 +--- a/net/ipv4/ipmr.c ++++ b/net/ipv4/ipmr.c +@@ -134,7 +134,7 @@ static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, + struct mfc_cache *c, struct rtmsg *rtm); + static void mroute_netlink_event(struct mr_table *mrt, struct mfc_cache *mfc, + int cmd); +-static void mroute_clean_tables(struct mr_table *mrt); ++static void mroute_clean_tables(struct mr_table *mrt, bool all); + static void ipmr_expire_process(unsigned long arg); + + #ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES +@@ -350,7 +350,7 @@ static struct mr_table *ipmr_new_table(struct net *net, u32 id) + static void ipmr_free_table(struct mr_table *mrt) + { + del_timer_sync(&mrt->ipmr_expire_timer); +- mroute_clean_tables(mrt); ++ mroute_clean_tables(mrt, true); + kfree(mrt); + } + +@@ -1208,7 +1208,7 @@ static int ipmr_mfc_add(struct net *net, struct mr_table *mrt, + * Close the multicast socket, and clear the vif tables etc + */ + +-static void mroute_clean_tables(struct mr_table *mrt) ++static void mroute_clean_tables(struct mr_table *mrt, bool all) + { + int i; + LIST_HEAD(list); +@@ -1217,8 +1217,9 @@ static void mroute_clean_tables(struct mr_table *mrt) + /* Shut down all active vif entries */ + + for (i = 0; i < mrt->maxvif; i++) { +- if (!(mrt->vif_table[i].flags & VIFF_STATIC)) +- vif_delete(mrt, i, 0, &list); ++ if (!all && (mrt->vif_table[i].flags & VIFF_STATIC)) ++ continue; ++ vif_delete(mrt, i, 0, &list); + } + unregister_netdevice_many(&list); + +@@ -1226,7 +1227,7 @@ static void mroute_clean_tables(struct mr_table *mrt) + + for (i = 0; i < MFC_LINES; i++) { + list_for_each_entry_safe(c, next, &mrt->mfc_cache_array[i], list) { +- if (c->mfc_flags & MFC_STATIC) ++ if (!all && (c->mfc_flags & MFC_STATIC)) + continue; + list_del_rcu(&c->list); + mroute_netlink_event(mrt, c, RTM_DELROUTE); +@@ -1261,7 +1262,7 @@ static void mrtsock_destruct(struct sock *sk) + NETCONFA_IFINDEX_ALL, + net->ipv4.devconf_all); + RCU_INIT_POINTER(mrt->mroute_sk, NULL); +- mroute_clean_tables(mrt); ++ mroute_clean_tables(mrt, false); + } + } + rtnl_unlock(); +-- +2.1.0 + + +From 6fea7a6bf9a832ea306a816204984e2244000784 Mon Sep 17 00:00:00 2001 +From: Nikolay Aleksandrov +Date: Fri, 20 Nov 2015 13:54:20 +0100 +Subject: [PATCH 32/43] net: ip6mr: fix static mfc/dev leaks on table + destruction + +[ Upstream commit 4c6980462f32b4f282c5d8e5f7ea8070e2937725 ] + +Similar to ipv4, when destroying an mrt table the static mfc entries and +the static devices are kept, which leads to devices that can never be +destroyed (because of refcnt taken) and leaked memory. Make sure that +everything is cleaned up on netns destruction. + +Fixes: 8229efdaef1e ("netns: ip6mr: enable namespace support in ipv6 multicast forwarding code") +CC: Benjamin Thery +Signed-off-by: Nikolay Aleksandrov +Reviewed-by: Cong Wang +Signed-off-by: David S. Miller +--- + net/ipv6/ip6mr.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c +index 0e004cc..35eee72 100644 +--- a/net/ipv6/ip6mr.c ++++ b/net/ipv6/ip6mr.c +@@ -118,7 +118,7 @@ static void mr6_netlink_event(struct mr6_table *mrt, struct mfc6_cache *mfc, + int cmd); + static int ip6mr_rtm_dumproute(struct sk_buff *skb, + struct netlink_callback *cb); +-static void mroute_clean_tables(struct mr6_table *mrt); ++static void mroute_clean_tables(struct mr6_table *mrt, bool all); + static void ipmr_expire_process(unsigned long arg); + + #ifdef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES +@@ -334,7 +334,7 @@ static struct mr6_table *ip6mr_new_table(struct net *net, u32 id) + static void ip6mr_free_table(struct mr6_table *mrt) + { + del_timer_sync(&mrt->ipmr_expire_timer); +- mroute_clean_tables(mrt); ++ mroute_clean_tables(mrt, true); + kfree(mrt); + } + +@@ -1542,7 +1542,7 @@ static int ip6mr_mfc_add(struct net *net, struct mr6_table *mrt, + * Close the multicast socket, and clear the vif tables etc + */ + +-static void mroute_clean_tables(struct mr6_table *mrt) ++static void mroute_clean_tables(struct mr6_table *mrt, bool all) + { + int i; + LIST_HEAD(list); +@@ -1552,8 +1552,9 @@ static void mroute_clean_tables(struct mr6_table *mrt) + * Shut down all active vif entries + */ + for (i = 0; i < mrt->maxvif; i++) { +- if (!(mrt->vif6_table[i].flags & VIFF_STATIC)) +- mif6_delete(mrt, i, &list); ++ if (!all && (mrt->vif6_table[i].flags & VIFF_STATIC)) ++ continue; ++ mif6_delete(mrt, i, &list); + } + unregister_netdevice_many(&list); + +@@ -1562,7 +1563,7 @@ static void mroute_clean_tables(struct mr6_table *mrt) + */ + for (i = 0; i < MFC6_LINES; i++) { + list_for_each_entry_safe(c, next, &mrt->mfc6_cache_array[i], list) { +- if (c->mfc_flags & MFC_STATIC) ++ if (!all && (c->mfc_flags & MFC_STATIC)) + continue; + write_lock_bh(&mrt_lock); + list_del(&c->list); +@@ -1625,7 +1626,7 @@ int ip6mr_sk_done(struct sock *sk) + net->ipv6.devconf_all); + write_unlock_bh(&mrt_lock); + +- mroute_clean_tables(mrt); ++ mroute_clean_tables(mrt, false); + err = 0; + break; + } +-- +2.1.0 + + +From 46b15261453a821e3d33889189715d61c4fb0af2 Mon Sep 17 00:00:00 2001 +From: Nikolay Aleksandrov +Date: Sat, 21 Nov 2015 19:46:19 +0100 +Subject: [PATCH 33/43] vrf: fix double free and memory corruption on + register_netdevice failure + +[ Upstream commit 7f109f7cc37108cba7243bc832988525b0d85909 ] + +When vrf's ->newlink is called, if register_netdevice() fails then it +does free_netdev(), but that's also done by rtnl_newlink() so a second +free happens and memory gets corrupted, to reproduce execute the +following line a couple of times (1 - 5 usually is enough): +$ for i in `seq 1 5`; do ip link add vrf: type vrf table 1; done; +This works because we fail in register_netdevice() because of the wrong +name "vrf:". + +And here's a trace of one crash: +[ 28.792157] ------------[ cut here ]------------ +[ 28.792407] kernel BUG at fs/namei.c:246! +[ 28.792608] invalid opcode: 0000 [#1] SMP +[ 28.793240] Modules linked in: vrf nfsd auth_rpcgss oid_registry +nfs_acl nfs lockd grace sunrpc crct10dif_pclmul crc32_pclmul +crc32c_intel qxl drm_kms_helper ttm drm aesni_intel aes_x86_64 psmouse +glue_helper lrw evdev gf128mul i2c_piix4 ablk_helper cryptd ppdev +parport_pc parport serio_raw pcspkr virtio_balloon virtio_console +i2c_core acpi_cpufreq button 9pnet_virtio 9p 9pnet fscache ipv6 autofs4 +ext4 crc16 mbcache jbd2 virtio_blk virtio_net sg sr_mod cdrom +ata_generic ehci_pci uhci_hcd ehci_hcd e1000 usbcore usb_common ata_piix +libata virtio_pci virtio_ring virtio scsi_mod floppy +[ 28.796016] CPU: 0 PID: 1148 Comm: ld-linux-x86-64 Not tainted +4.4.0-rc1+ #24 +[ 28.796016] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), +BIOS 1.8.1-20150318_183358- 04/01/2014 +[ 28.796016] task: ffff8800352561c0 ti: ffff88003592c000 task.ti: +ffff88003592c000 +[ 28.796016] RIP: 0010:[] [] +putname+0x43/0x60 +[ 28.796016] RSP: 0018:ffff88003592fe88 EFLAGS: 00010246 +[ 28.796016] RAX: 0000000000000000 RBX: ffff8800352561c0 RCX: +0000000000000001 +[ 28.796016] RDX: 0000000000000000 RSI: 0000000000000000 RDI: +ffff88003784f000 +[ 28.796016] RBP: ffff88003592ff08 R08: 0000000000000001 R09: +0000000000000000 +[ 28.796016] R10: 0000000000000000 R11: 0000000000000001 R12: +0000000000000000 +[ 28.796016] R13: 000000000000047c R14: ffff88003784f000 R15: +ffff8800358c4a00 +[ 28.796016] FS: 0000000000000000(0000) GS:ffff88003fc00000(0000) +knlGS:0000000000000000 +[ 28.796016] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 28.796016] CR2: 00007ffd583bc2d9 CR3: 0000000035a99000 CR4: +00000000000406f0 +[ 28.796016] Stack: +[ 28.796016] ffffffff8121045d ffffffff812102d3 ffff8800352561c0 +ffff880035a91660 +[ 28.796016] ffff8800008a9880 0000000000000000 ffffffff81a49940 +00ffffff81218684 +[ 28.796016] ffff8800352561c0 000000000000047c 0000000000000000 +ffff880035b36d80 +[ 28.796016] Call Trace: +[ 28.796016] [] ? +do_execveat_common.isra.34+0x74d/0x930 +[ 28.796016] [] ? +do_execveat_common.isra.34+0x5c3/0x930 +[ 28.796016] [] do_execve+0x2c/0x30 +[ 28.796016] [] +call_usermodehelper_exec_async+0xf0/0x140 +[ 28.796016] [] ? umh_complete+0x40/0x40 +[ 28.796016] [] ret_from_fork+0x3f/0x70 +[ 28.796016] Code: 48 8d 47 1c 48 89 e5 53 48 8b 37 48 89 fb 48 39 c6 +74 1a 48 8b 3d 7e e9 8f 00 e8 49 fa fc ff 48 89 df e8 f1 01 fd ff 5b 5d +f3 c3 <0f> 0b 48 89 fe 48 8b 3d 61 e9 8f 00 e8 2c fa fc ff 5b 5d eb e9 +[ 28.796016] RIP [] putname+0x43/0x60 +[ 28.796016] RSP + +Fixes: 193125dbd8eb ("net: Introduce VRF device driver") +Signed-off-by: Nikolay Aleksandrov +Acked-by: David Ahern +Signed-off-by: David S. Miller +--- + drivers/net/vrf.c | 15 ++------------- + 1 file changed, 2 insertions(+), 13 deletions(-) + +diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c +index 488c6f5..c9e309c 100644 +--- a/drivers/net/vrf.c ++++ b/drivers/net/vrf.c +@@ -581,7 +581,6 @@ static int vrf_newlink(struct net *src_net, struct net_device *dev, + { + struct net_vrf *vrf = netdev_priv(dev); + struct net_vrf_dev *vrf_ptr; +- int err; + + if (!data || !data[IFLA_VRF_TABLE]) + return -EINVAL; +@@ -590,26 +589,16 @@ static int vrf_newlink(struct net *src_net, struct net_device *dev, + + dev->priv_flags |= IFF_VRF_MASTER; + +- err = -ENOMEM; + vrf_ptr = kmalloc(sizeof(*dev->vrf_ptr), GFP_KERNEL); + if (!vrf_ptr) +- goto out_fail; ++ return -ENOMEM; + + vrf_ptr->ifindex = dev->ifindex; + vrf_ptr->tb_id = vrf->tb_id; + +- err = register_netdevice(dev); +- if (err < 0) +- goto out_fail; +- + rcu_assign_pointer(dev->vrf_ptr, vrf_ptr); + +- return 0; +- +-out_fail: +- kfree(vrf_ptr); +- free_netdev(dev); +- return err; ++ return register_netdev(dev); + } + + static size_t vrf_nl_getsize(const struct net_device *dev) +-- +2.1.0 + + +From 3ac4063f990a9e106c8971d60e1b430518fb5cec Mon Sep 17 00:00:00 2001 +From: Aaro Koskinen +Date: Sun, 22 Nov 2015 01:08:54 +0200 +Subject: [PATCH 34/43] broadcom: fix PHY_ID_BCM5481 entry in the id table + +[ Upstream commit 3c25a860d17b7378822f35d8c9141db9507e3beb ] + +Commit fcb26ec5b18d ("broadcom: move all PHY_ID's to header") +updated broadcom_tbl to use PHY_IDs, but incorrectly replaced 0x0143bca0 +with PHY_ID_BCM5482 (making a duplicate entry, and completely omitting +the original). Fix that. + +Fixes: fcb26ec5b18d ("broadcom: move all PHY_ID's to header") +Signed-off-by: Aaro Koskinen +Signed-off-by: David S. Miller +--- + drivers/net/phy/broadcom.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c +index 9c71295..85e64044 100644 +--- a/drivers/net/phy/broadcom.c ++++ b/drivers/net/phy/broadcom.c +@@ -675,7 +675,7 @@ static struct mdio_device_id __maybe_unused broadcom_tbl[] = { + { PHY_ID_BCM5461, 0xfffffff0 }, + { PHY_ID_BCM54616S, 0xfffffff0 }, + { PHY_ID_BCM5464, 0xfffffff0 }, +- { PHY_ID_BCM5482, 0xfffffff0 }, ++ { PHY_ID_BCM5481, 0xfffffff0 }, + { PHY_ID_BCM5482, 0xfffffff0 }, + { PHY_ID_BCM50610, 0xfffffff0 }, + { PHY_ID_BCM50610M, 0xfffffff0 }, +-- +2.1.0 + + +From d71b7cd7146378b31252e33a23ad693b6d461ed8 Mon Sep 17 00:00:00 2001 +From: Ying Xue +Date: Tue, 24 Nov 2015 13:57:57 +0800 +Subject: [PATCH 35/43] tipc: fix error handling of expanding buffer headroom + +[ Upstream commit 7098356baca723513e97ca0020df4e18bc353be3 ] + +Coverity says: + +*** CID 1338065: Error handling issues (CHECKED_RETURN) +/net/tipc/udp_media.c: 162 in tipc_udp_send_msg() +156 struct udp_media_addr *dst = (struct udp_media_addr *)&dest->value; +157 struct udp_media_addr *src = (struct udp_media_addr *)&b->addr.value; +158 struct sk_buff *clone; +159 struct rtable *rt; +160 +161 if (skb_headroom(skb) < UDP_MIN_HEADROOM) +>>> CID 1338065: Error handling issues (CHECKED_RETURN) +>>> Calling "pskb_expand_head" without checking return value (as is done elsewhere 51 out of 56 times). +162 pskb_expand_head(skb, UDP_MIN_HEADROOM, 0, GFP_ATOMIC); +163 +164 clone = skb_clone(skb, GFP_ATOMIC); +165 skb_set_inner_protocol(clone, htons(ETH_P_TIPC)); +166 ub = rcu_dereference_rtnl(b->media_ptr); +167 if (!ub) { + +When expanding buffer headroom over udp tunnel with pskb_expand_head(), +it's unfortunate that we don't check its return value. As a result, if +the function returns an error code due to the lack of memory, it may +cause unpredictable consequence as we unconditionally consider that +it's always successful. + +Fixes: e53567948f82 ("tipc: conditionally expand buffer headroom over udp tunnel") +Reported-by: +Cc: Stephen Hemminger +Signed-off-by: Ying Xue +Signed-off-by: David S. Miller +--- + net/tipc/udp_media.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c +index cd7c5f1..86f2e7c 100644 +--- a/net/tipc/udp_media.c ++++ b/net/tipc/udp_media.c +@@ -159,8 +159,11 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb, + struct sk_buff *clone; + struct rtable *rt; + +- if (skb_headroom(skb) < UDP_MIN_HEADROOM) +- pskb_expand_head(skb, UDP_MIN_HEADROOM, 0, GFP_ATOMIC); ++ if (skb_headroom(skb) < UDP_MIN_HEADROOM) { ++ err = pskb_expand_head(skb, UDP_MIN_HEADROOM, 0, GFP_ATOMIC); ++ if (err) ++ goto tx_error; ++ } + + clone = skb_clone(skb, GFP_ATOMIC); + skb_set_inner_protocol(clone, htons(ETH_P_TIPC)); +-- +2.1.0 + + +From d26834684ff963259ed7fd9e19c816ed71d7bf61 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20Kube=C4=8Dek?= +Date: Tue, 24 Nov 2015 15:07:11 +0100 +Subject: [PATCH 36/43] ipv6: distinguish frag queues by device for multicast + and link-local packets + +[ Upstream commit 264640fc2c5f4f913db5c73fa3eb1ead2c45e9d7 ] + +If a fragmented multicast packet is received on an ethernet device which +has an active macvlan on top of it, each fragment is duplicated and +received both on the underlying device and the macvlan. If some +fragments for macvlan are processed before the whole packet for the +underlying device is reassembled, the "overlapping fragments" test in +ip6_frag_queue() discards the whole fragment queue. + +To resolve this, add device ifindex to the search key and require it to +match reassembling multicast packets and packets to link-local +addresses. + +Note: similar patch has been already submitted by Yoshifuji Hideaki in + + http://patchwork.ozlabs.org/patch/220979/ + +but got lost and forgotten for some reason. + +Signed-off-by: Michal Kubecek +Signed-off-by: David S. Miller +--- + include/net/ipv6.h | 1 + + net/ipv6/netfilter/nf_conntrack_reasm.c | 5 +++-- + net/ipv6/reassembly.c | 10 +++++++--- + 3 files changed, 11 insertions(+), 5 deletions(-) + +diff --git a/include/net/ipv6.h b/include/net/ipv6.h +index 711cca4..1b63717 100644 +--- a/include/net/ipv6.h ++++ b/include/net/ipv6.h +@@ -490,6 +490,7 @@ struct ip6_create_arg { + u32 user; + const struct in6_addr *src; + const struct in6_addr *dst; ++ int iif; + u8 ecn; + }; + +diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c +index c7196ad..dc50143 100644 +--- a/net/ipv6/netfilter/nf_conntrack_reasm.c ++++ b/net/ipv6/netfilter/nf_conntrack_reasm.c +@@ -190,7 +190,7 @@ static void nf_ct_frag6_expire(unsigned long data) + /* Creation primitives. */ + static inline struct frag_queue *fq_find(struct net *net, __be32 id, + u32 user, struct in6_addr *src, +- struct in6_addr *dst, u8 ecn) ++ struct in6_addr *dst, int iif, u8 ecn) + { + struct inet_frag_queue *q; + struct ip6_create_arg arg; +@@ -200,6 +200,7 @@ static inline struct frag_queue *fq_find(struct net *net, __be32 id, + arg.user = user; + arg.src = src; + arg.dst = dst; ++ arg.iif = iif; + arg.ecn = ecn; + + local_bh_disable(); +@@ -603,7 +604,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user) + fhdr = (struct frag_hdr *)skb_transport_header(clone); + + fq = fq_find(net, fhdr->identification, user, &hdr->saddr, &hdr->daddr, +- ip6_frag_ecn(hdr)); ++ skb->dev ? skb->dev->ifindex : 0, ip6_frag_ecn(hdr)); + if (fq == NULL) { + pr_debug("Can't find and can't create new queue\n"); + goto ret_orig; +diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c +index f1159bb..04013a9 100644 +--- a/net/ipv6/reassembly.c ++++ b/net/ipv6/reassembly.c +@@ -108,7 +108,10 @@ bool ip6_frag_match(const struct inet_frag_queue *q, const void *a) + return fq->id == arg->id && + fq->user == arg->user && + ipv6_addr_equal(&fq->saddr, arg->src) && +- ipv6_addr_equal(&fq->daddr, arg->dst); ++ ipv6_addr_equal(&fq->daddr, arg->dst) && ++ (arg->iif == fq->iif || ++ !(ipv6_addr_type(arg->dst) & (IPV6_ADDR_MULTICAST | ++ IPV6_ADDR_LINKLOCAL))); + } + EXPORT_SYMBOL(ip6_frag_match); + +@@ -180,7 +183,7 @@ static void ip6_frag_expire(unsigned long data) + + static struct frag_queue * + fq_find(struct net *net, __be32 id, const struct in6_addr *src, +- const struct in6_addr *dst, u8 ecn) ++ const struct in6_addr *dst, int iif, u8 ecn) + { + struct inet_frag_queue *q; + struct ip6_create_arg arg; +@@ -190,6 +193,7 @@ fq_find(struct net *net, __be32 id, const struct in6_addr *src, + arg.user = IP6_DEFRAG_LOCAL_DELIVER; + arg.src = src; + arg.dst = dst; ++ arg.iif = iif; + arg.ecn = ecn; + + hash = inet6_hash_frag(id, src, dst); +@@ -551,7 +555,7 @@ static int ipv6_frag_rcv(struct sk_buff *skb) + } + + fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr, +- ip6_frag_ecn(hdr)); ++ skb->dev ? skb->dev->ifindex : 0, ip6_frag_ecn(hdr)); + if (fq) { + int ret; + +-- +2.1.0 + + +From a9bb7b65ac7cd16bafc5cbd4ebb182ce5bbcb488 Mon Sep 17 00:00:00 2001 +From: Quentin Casasnovas +Date: Tue, 24 Nov 2015 17:13:21 -0500 +Subject: [PATCH 37/43] RDS: fix race condition when sending a message on + unbound socket + +[ Upstream commit 8c7188b23474cca017b3ef354c4a58456f68303a ] + +Sasha's found a NULL pointer dereference in the RDS connection code when +sending a message to an apparently unbound socket. The problem is caused +by the code checking if the socket is bound in rds_sendmsg(), which checks +the rs_bound_addr field without taking a lock on the socket. This opens a +race where rs_bound_addr is temporarily set but where the transport is not +in rds_bind(), leading to a NULL pointer dereference when trying to +dereference 'trans' in __rds_conn_create(). + +Vegard wrote a reproducer for this issue, so kindly ask him to share if +you're interested. + +I cannot reproduce the NULL pointer dereference using Vegard's reproducer +with this patch, whereas I could without. + +Complete earlier incomplete fix to CVE-2015-6937: + + 74e98eb08588 ("RDS: verify the underlying transport exists before creating a connection") + +Cc: David S. Miller +Cc: stable@vger.kernel.org + +Reviewed-by: Vegard Nossum +Reviewed-by: Sasha Levin +Acked-by: Santosh Shilimkar +Signed-off-by: Quentin Casasnovas +Signed-off-by: David S. Miller +--- + net/rds/connection.c | 6 ------ + net/rds/send.c | 4 +++- + 2 files changed, 3 insertions(+), 7 deletions(-) + +diff --git a/net/rds/connection.c b/net/rds/connection.c +index 49adeef..9b2de5e 100644 +--- a/net/rds/connection.c ++++ b/net/rds/connection.c +@@ -190,12 +190,6 @@ new_conn: + } + } + +- if (trans == NULL) { +- kmem_cache_free(rds_conn_slab, conn); +- conn = ERR_PTR(-ENODEV); +- goto out; +- } +- + conn->c_trans = trans; + + ret = trans->conn_alloc(conn, gfp); +diff --git a/net/rds/send.c b/net/rds/send.c +index 4df61a5..859de6f 100644 +--- a/net/rds/send.c ++++ b/net/rds/send.c +@@ -1009,11 +1009,13 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len) + release_sock(sk); + } + +- /* racing with another thread binding seems ok here */ ++ lock_sock(sk); + if (daddr == 0 || rs->rs_bound_addr == 0) { ++ release_sock(sk); + ret = -ENOTCONN; /* XXX not a great errno */ + goto out; + } ++ release_sock(sk); + + if (payload_len > rds_sk_sndbuf(rs)) { + ret = -EMSGSIZE; +-- +2.1.0 + + +From f6c7967f25e8220913bedf596c260c379dab5341 Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +Date: Mon, 30 Nov 2015 13:02:56 +0100 +Subject: [PATCH 38/43] bpf, array: fix heap out-of-bounds access when updating + elements + +[ Upstream commit fbca9d2d35c6ef1b323fae75cc9545005ba25097 ] + +During own review but also reported by Dmitry's syzkaller [1] it has been +noticed that we trigger a heap out-of-bounds access on eBPF array maps +when updating elements. This happens with each map whose map->value_size +(specified during map creation time) is not multiple of 8 bytes. + +In array_map_alloc(), elem_size is round_up(attr->value_size, 8) and +used to align array map slots for faster access. However, in function +array_map_update_elem(), we update the element as ... + +memcpy(array->value + array->elem_size * index, value, array->elem_size); + +... where we access 'value' out-of-bounds, since it was allocated from +map_update_elem() from syscall side as kmalloc(map->value_size, GFP_USER) +and later on copied through copy_from_user(value, uvalue, map->value_size). +Thus, up to 7 bytes, we can access out-of-bounds. + +Same could happen from within an eBPF program, where in worst case we +access beyond an eBPF program's designated stack. + +Since 1be7f75d1668 ("bpf: enable non-root eBPF programs") didn't hit an +official release yet, it only affects priviledged users. + +In case of array_map_lookup_elem(), the verifier prevents eBPF programs +from accessing beyond map->value_size through check_map_access(). Also +from syscall side map_lookup_elem() only copies map->value_size back to +user, so nothing could leak. + + [1] http://github.com/google/syzkaller + +Fixes: 28fbcfa08d8e ("bpf: add array type of eBPF maps") +Reported-by: Dmitry Vyukov +Signed-off-by: Daniel Borkmann +Acked-by: Alexei Starovoitov +Signed-off-by: David S. Miller +--- + kernel/bpf/arraymap.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c +index 29ace10..7a0decf 100644 +--- a/kernel/bpf/arraymap.c ++++ b/kernel/bpf/arraymap.c +@@ -104,7 +104,7 @@ static int array_map_update_elem(struct bpf_map *map, void *key, void *value, + /* all elements already exist */ + return -EEXIST; + +- memcpy(array->value + array->elem_size * index, value, array->elem_size); ++ memcpy(array->value + array->elem_size * index, value, map->value_size); + return 0; + } + +-- +2.1.0 + + +From 5c3c67ba34c640fa3d93ff4e0506cb5826619de2 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Sun, 29 Nov 2015 19:37:57 -0800 +Subject: [PATCH 39/43] ipv6: add complete rcu protection around np->opt + +[ Upstream commit 45f6fad84cc305103b28d73482b344d7f5b76f39 ] + +This patch addresses multiple problems : + +UDP/RAW sendmsg() need to get a stable struct ipv6_txoptions +while socket is not locked : Other threads can change np->opt +concurrently. Dmitry posted a syzkaller +(http://github.com/google/syzkaller) program desmonstrating +use-after-free. + +Starting with TCP/DCCP lockless listeners, tcp_v6_syn_recv_sock() +and dccp_v6_request_recv_sock() also need to use RCU protection +to dereference np->opt once (before calling ipv6_dup_options()) + +This patch adds full RCU protection to np->opt + +Reported-by: Dmitry Vyukov +Signed-off-by: Eric Dumazet +Acked-by: Hannes Frederic Sowa +Signed-off-by: David S. Miller +--- + include/linux/ipv6.h | 2 +- + include/net/ipv6.h | 21 ++++++++++++++++++++- + net/dccp/ipv6.c | 33 +++++++++++++++++++++------------ + net/ipv6/af_inet6.c | 13 +++++++++---- + net/ipv6/datagram.c | 4 +++- + net/ipv6/exthdrs.c | 3 ++- + net/ipv6/inet6_connection_sock.c | 11 ++++++++--- + net/ipv6/ipv6_sockglue.c | 33 ++++++++++++++++++++++----------- + net/ipv6/raw.c | 8 ++++++-- + net/ipv6/syncookies.c | 2 +- + net/ipv6/tcp_ipv6.c | 28 +++++++++++++++++----------- + net/ipv6/udp.c | 8 ++++++-- + net/l2tp/l2tp_ip6.c | 8 ++++++-- + 13 files changed, 122 insertions(+), 52 deletions(-) + +diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h +index f1f32af..3e4ff3f 100644 +--- a/include/linux/ipv6.h ++++ b/include/linux/ipv6.h +@@ -227,7 +227,7 @@ struct ipv6_pinfo { + struct ipv6_ac_socklist *ipv6_ac_list; + struct ipv6_fl_socklist __rcu *ipv6_fl_list; + +- struct ipv6_txoptions *opt; ++ struct ipv6_txoptions __rcu *opt; + struct sk_buff *pktoptions; + struct sk_buff *rxpmtu; + struct inet6_cork cork; +diff --git a/include/net/ipv6.h b/include/net/ipv6.h +index 1b63717..b14e158 100644 +--- a/include/net/ipv6.h ++++ b/include/net/ipv6.h +@@ -205,6 +205,7 @@ extern rwlock_t ip6_ra_lock; + */ + + struct ipv6_txoptions { ++ atomic_t refcnt; + /* Length of this structure */ + int tot_len; + +@@ -217,7 +218,7 @@ struct ipv6_txoptions { + struct ipv6_opt_hdr *dst0opt; + struct ipv6_rt_hdr *srcrt; /* Routing Header */ + struct ipv6_opt_hdr *dst1opt; +- ++ struct rcu_head rcu; + /* Option buffer, as read by IPV6_PKTOPTIONS, starts here. */ + }; + +@@ -252,6 +253,24 @@ struct ipv6_fl_socklist { + struct rcu_head rcu; + }; + ++static inline struct ipv6_txoptions *txopt_get(const struct ipv6_pinfo *np) ++{ ++ struct ipv6_txoptions *opt; ++ ++ rcu_read_lock(); ++ opt = rcu_dereference(np->opt); ++ if (opt && !atomic_inc_not_zero(&opt->refcnt)) ++ opt = NULL; ++ rcu_read_unlock(); ++ return opt; ++} ++ ++static inline void txopt_put(struct ipv6_txoptions *opt) ++{ ++ if (opt && atomic_dec_and_test(&opt->refcnt)) ++ kfree_rcu(opt, rcu); ++} ++ + struct ip6_flowlabel *fl6_sock_lookup(struct sock *sk, __be32 label); + struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions *opt_space, + struct ip6_flowlabel *fl, +diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c +index 5165571..a049050 100644 +--- a/net/dccp/ipv6.c ++++ b/net/dccp/ipv6.c +@@ -202,7 +202,9 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req) + security_req_classify_flow(req, flowi6_to_flowi(&fl6)); + + +- final_p = fl6_update_dst(&fl6, np->opt, &final); ++ rcu_read_lock(); ++ final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), &final); ++ rcu_read_unlock(); + + dst = ip6_dst_lookup_flow(sk, &fl6, final_p); + if (IS_ERR(dst)) { +@@ -219,7 +221,10 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req) + &ireq->ir_v6_loc_addr, + &ireq->ir_v6_rmt_addr); + fl6.daddr = ireq->ir_v6_rmt_addr; +- err = ip6_xmit(sk, skb, &fl6, np->opt, np->tclass); ++ rcu_read_lock(); ++ err = ip6_xmit(sk, skb, &fl6, rcu_dereference(np->opt), ++ np->tclass); ++ rcu_read_unlock(); + err = net_xmit_eval(err); + } + +@@ -415,6 +420,7 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, + { + struct inet_request_sock *ireq = inet_rsk(req); + struct ipv6_pinfo *newnp, *np = inet6_sk(sk); ++ struct ipv6_txoptions *opt; + struct inet_sock *newinet; + struct dccp6_sock *newdp6; + struct sock *newsk; +@@ -534,13 +540,15 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, + * Yes, keeping reference count would be much more clever, but we make + * one more one thing there: reattach optmem to newsk. + */ +- if (np->opt != NULL) +- newnp->opt = ipv6_dup_options(newsk, np->opt); +- ++ opt = rcu_dereference(np->opt); ++ if (opt) { ++ opt = ipv6_dup_options(newsk, opt); ++ RCU_INIT_POINTER(newnp->opt, opt); ++ } + inet_csk(newsk)->icsk_ext_hdr_len = 0; +- if (newnp->opt != NULL) +- inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen + +- newnp->opt->opt_flen); ++ if (opt) ++ inet_csk(newsk)->icsk_ext_hdr_len = opt->opt_nflen + ++ opt->opt_flen; + + dccp_sync_mss(newsk, dst_mtu(dst)); + +@@ -793,6 +801,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, + struct ipv6_pinfo *np = inet6_sk(sk); + struct dccp_sock *dp = dccp_sk(sk); + struct in6_addr *saddr = NULL, *final_p, final; ++ struct ipv6_txoptions *opt; + struct flowi6 fl6; + struct dst_entry *dst; + int addr_type; +@@ -892,7 +901,8 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, + fl6.fl6_sport = inet->inet_sport; + security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); + +- final_p = fl6_update_dst(&fl6, np->opt, &final); ++ opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk)); ++ final_p = fl6_update_dst(&fl6, opt, &final); + + dst = ip6_dst_lookup_flow(sk, &fl6, final_p); + if (IS_ERR(dst)) { +@@ -912,9 +922,8 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, + __ip6_dst_store(sk, dst, NULL, NULL); + + icsk->icsk_ext_hdr_len = 0; +- if (np->opt != NULL) +- icsk->icsk_ext_hdr_len = (np->opt->opt_flen + +- np->opt->opt_nflen); ++ if (opt) ++ icsk->icsk_ext_hdr_len = opt->opt_flen + opt->opt_nflen; + + inet->inet_dport = usin->sin6_port; + +diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c +index 44bb66b..38d66dd 100644 +--- a/net/ipv6/af_inet6.c ++++ b/net/ipv6/af_inet6.c +@@ -428,9 +428,11 @@ void inet6_destroy_sock(struct sock *sk) + + /* Free tx options */ + +- opt = xchg(&np->opt, NULL); +- if (opt) +- sock_kfree_s(sk, opt, opt->tot_len); ++ opt = xchg((__force struct ipv6_txoptions **)&np->opt, NULL); ++ if (opt) { ++ atomic_sub(opt->tot_len, &sk->sk_omem_alloc); ++ txopt_put(opt); ++ } + } + EXPORT_SYMBOL_GPL(inet6_destroy_sock); + +@@ -659,7 +661,10 @@ int inet6_sk_rebuild_header(struct sock *sk) + fl6.fl6_sport = inet->inet_sport; + security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); + +- final_p = fl6_update_dst(&fl6, np->opt, &final); ++ rcu_read_lock(); ++ final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), ++ &final); ++ rcu_read_unlock(); + + dst = ip6_dst_lookup_flow(sk, &fl6, final_p); + if (IS_ERR(dst)) { +diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c +index 9aadd57..a42a673 100644 +--- a/net/ipv6/datagram.c ++++ b/net/ipv6/datagram.c +@@ -167,8 +167,10 @@ ipv4_connected: + + security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); + +- opt = flowlabel ? flowlabel->opt : np->opt; ++ rcu_read_lock(); ++ opt = flowlabel ? flowlabel->opt : rcu_dereference(np->opt); + final_p = fl6_update_dst(&fl6, opt, &final); ++ rcu_read_unlock(); + + dst = ip6_dst_lookup_flow(sk, &fl6, final_p); + err = 0; +diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c +index ce203b0..ea7c4d6 100644 +--- a/net/ipv6/exthdrs.c ++++ b/net/ipv6/exthdrs.c +@@ -727,6 +727,7 @@ ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt) + *((char **)&opt2->dst1opt) += dif; + if (opt2->srcrt) + *((char **)&opt2->srcrt) += dif; ++ atomic_set(&opt2->refcnt, 1); + } + return opt2; + } +@@ -790,7 +791,7 @@ ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt, + return ERR_PTR(-ENOBUFS); + + memset(opt2, 0, tot_len); +- ++ atomic_set(&opt2->refcnt, 1); + opt2->tot_len = tot_len; + p = (char *)(opt2 + 1); + +diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c +index 6927f3f..9beed30 100644 +--- a/net/ipv6/inet6_connection_sock.c ++++ b/net/ipv6/inet6_connection_sock.c +@@ -77,7 +77,9 @@ struct dst_entry *inet6_csk_route_req(struct sock *sk, + memset(fl6, 0, sizeof(*fl6)); + fl6->flowi6_proto = IPPROTO_TCP; + fl6->daddr = ireq->ir_v6_rmt_addr; +- final_p = fl6_update_dst(fl6, np->opt, &final); ++ rcu_read_lock(); ++ final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final); ++ rcu_read_unlock(); + fl6->saddr = ireq->ir_v6_loc_addr; + fl6->flowi6_oif = ireq->ir_iif; + fl6->flowi6_mark = ireq->ir_mark; +@@ -207,7 +209,9 @@ static struct dst_entry *inet6_csk_route_socket(struct sock *sk, + fl6->fl6_dport = inet->inet_dport; + security_sk_classify_flow(sk, flowi6_to_flowi(fl6)); + +- final_p = fl6_update_dst(fl6, np->opt, &final); ++ rcu_read_lock(); ++ final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final); ++ rcu_read_unlock(); + + dst = __inet6_csk_dst_check(sk, np->dst_cookie); + if (!dst) { +@@ -240,7 +244,8 @@ int inet6_csk_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl_unused + /* Restore final destination back after routing done */ + fl6.daddr = sk->sk_v6_daddr; + +- res = ip6_xmit(sk, skb, &fl6, np->opt, np->tclass); ++ res = ip6_xmit(sk, skb, &fl6, rcu_dereference(np->opt), ++ np->tclass); + rcu_read_unlock(); + return res; + } +diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c +index 63e6956..4449ad1 100644 +--- a/net/ipv6/ipv6_sockglue.c ++++ b/net/ipv6/ipv6_sockglue.c +@@ -111,7 +111,8 @@ struct ipv6_txoptions *ipv6_update_options(struct sock *sk, + icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie); + } + } +- opt = xchg(&inet6_sk(sk)->opt, opt); ++ opt = xchg((__force struct ipv6_txoptions **)&inet6_sk(sk)->opt, ++ opt); + sk_dst_reset(sk); + + return opt; +@@ -231,9 +232,12 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, + sk->sk_socket->ops = &inet_dgram_ops; + sk->sk_family = PF_INET; + } +- opt = xchg(&np->opt, NULL); +- if (opt) +- sock_kfree_s(sk, opt, opt->tot_len); ++ opt = xchg((__force struct ipv6_txoptions **)&np->opt, ++ NULL); ++ if (opt) { ++ atomic_sub(opt->tot_len, &sk->sk_omem_alloc); ++ txopt_put(opt); ++ } + pktopt = xchg(&np->pktoptions, NULL); + kfree_skb(pktopt); + +@@ -403,7 +407,8 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, + if (optname != IPV6_RTHDR && !ns_capable(net->user_ns, CAP_NET_RAW)) + break; + +- opt = ipv6_renew_options(sk, np->opt, optname, ++ opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk)); ++ opt = ipv6_renew_options(sk, opt, optname, + (struct ipv6_opt_hdr __user *)optval, + optlen); + if (IS_ERR(opt)) { +@@ -432,8 +437,10 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, + retv = 0; + opt = ipv6_update_options(sk, opt); + sticky_done: +- if (opt) +- sock_kfree_s(sk, opt, opt->tot_len); ++ if (opt) { ++ atomic_sub(opt->tot_len, &sk->sk_omem_alloc); ++ txopt_put(opt); ++ } + break; + } + +@@ -486,6 +493,7 @@ sticky_done: + break; + + memset(opt, 0, sizeof(*opt)); ++ atomic_set(&opt->refcnt, 1); + opt->tot_len = sizeof(*opt) + optlen; + retv = -EFAULT; + if (copy_from_user(opt+1, optval, optlen)) +@@ -502,8 +510,10 @@ update: + retv = 0; + opt = ipv6_update_options(sk, opt); + done: +- if (opt) +- sock_kfree_s(sk, opt, opt->tot_len); ++ if (opt) { ++ atomic_sub(opt->tot_len, &sk->sk_omem_alloc); ++ txopt_put(opt); ++ } + break; + } + case IPV6_UNICAST_HOPS: +@@ -1110,10 +1120,11 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, + case IPV6_RTHDR: + case IPV6_DSTOPTS: + { ++ struct ipv6_txoptions *opt; + + lock_sock(sk); +- len = ipv6_getsockopt_sticky(sk, np->opt, +- optname, optval, len); ++ opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk)); ++ len = ipv6_getsockopt_sticky(sk, opt, optname, optval, len); + release_sock(sk); + /* check if ipv6_getsockopt_sticky() returns err code */ + if (len < 0) +diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c +index fdbada156..fe97729 100644 +--- a/net/ipv6/raw.c ++++ b/net/ipv6/raw.c +@@ -732,6 +732,7 @@ static int raw6_getfrag(void *from, char *to, int offset, int len, int odd, + + static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) + { ++ struct ipv6_txoptions *opt_to_free = NULL; + struct ipv6_txoptions opt_space; + DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name); + struct in6_addr *daddr, *final_p, final; +@@ -838,8 +839,10 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) + if (!(opt->opt_nflen|opt->opt_flen)) + opt = NULL; + } +- if (!opt) +- opt = np->opt; ++ if (!opt) { ++ opt = txopt_get(np); ++ opt_to_free = opt; ++ } + if (flowlabel) + opt = fl6_merge_options(&opt_space, flowlabel, opt); + opt = ipv6_fixup_options(&opt_space, opt); +@@ -905,6 +908,7 @@ done: + dst_release(dst); + out: + fl6_sock_release(flowlabel); ++ txopt_put(opt_to_free); + return err < 0 ? err : len; + do_confirm: + dst_confirm(dst); +diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c +index 0909f4e..f30bfdc 100644 +--- a/net/ipv6/syncookies.c ++++ b/net/ipv6/syncookies.c +@@ -225,7 +225,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) + memset(&fl6, 0, sizeof(fl6)); + fl6.flowi6_proto = IPPROTO_TCP; + fl6.daddr = ireq->ir_v6_rmt_addr; +- final_p = fl6_update_dst(&fl6, np->opt, &final); ++ final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), &final); + fl6.saddr = ireq->ir_v6_loc_addr; + fl6.flowi6_oif = sk->sk_bound_dev_if; + fl6.flowi6_mark = ireq->ir_mark; +diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c +index 97d9314..9e9b77b 100644 +--- a/net/ipv6/tcp_ipv6.c ++++ b/net/ipv6/tcp_ipv6.c +@@ -120,6 +120,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, + struct ipv6_pinfo *np = inet6_sk(sk); + struct tcp_sock *tp = tcp_sk(sk); + struct in6_addr *saddr = NULL, *final_p, final; ++ struct ipv6_txoptions *opt; + struct flowi6 fl6; + struct dst_entry *dst; + int addr_type; +@@ -235,7 +236,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, + fl6.fl6_dport = usin->sin6_port; + fl6.fl6_sport = inet->inet_sport; + +- final_p = fl6_update_dst(&fl6, np->opt, &final); ++ opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk)); ++ final_p = fl6_update_dst(&fl6, opt, &final); + + security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); + +@@ -263,9 +265,9 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, + tcp_fetch_timewait_stamp(sk, dst); + + icsk->icsk_ext_hdr_len = 0; +- if (np->opt) +- icsk->icsk_ext_hdr_len = (np->opt->opt_flen + +- np->opt->opt_nflen); ++ if (opt) ++ icsk->icsk_ext_hdr_len = opt->opt_flen + ++ opt->opt_nflen; + + tp->rx_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr); + +@@ -461,7 +463,8 @@ static int tcp_v6_send_synack(struct sock *sk, struct dst_entry *dst, + fl6->flowlabel = ip6_flowlabel(ipv6_hdr(ireq->pktopts)); + + skb_set_queue_mapping(skb, queue_mapping); +- err = ip6_xmit(sk, skb, fl6, np->opt, np->tclass); ++ err = ip6_xmit(sk, skb, fl6, rcu_dereference(np->opt), ++ np->tclass); + err = net_xmit_eval(err); + } + +@@ -991,6 +994,7 @@ static struct sock *tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, + struct inet_request_sock *ireq; + struct ipv6_pinfo *newnp, *np = inet6_sk(sk); + struct tcp6_sock *newtcp6sk; ++ struct ipv6_txoptions *opt; + struct inet_sock *newinet; + struct tcp_sock *newtp; + struct sock *newsk; +@@ -1126,13 +1130,15 @@ static struct sock *tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, + but we make one more one thing there: reattach optmem + to newsk. + */ +- if (np->opt) +- newnp->opt = ipv6_dup_options(newsk, np->opt); +- ++ opt = rcu_dereference(np->opt); ++ if (opt) { ++ opt = ipv6_dup_options(newsk, opt); ++ RCU_INIT_POINTER(newnp->opt, opt); ++ } + inet_csk(newsk)->icsk_ext_hdr_len = 0; +- if (newnp->opt) +- inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen + +- newnp->opt->opt_flen); ++ if (opt) ++ inet_csk(newsk)->icsk_ext_hdr_len = opt->opt_nflen + ++ opt->opt_flen; + + tcp_ca_openreq_child(newsk, dst); + +diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c +index 0aba654..8379fc2 100644 +--- a/net/ipv6/udp.c ++++ b/net/ipv6/udp.c +@@ -1107,6 +1107,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) + DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name); + struct in6_addr *daddr, *final_p, final; + struct ipv6_txoptions *opt = NULL; ++ struct ipv6_txoptions *opt_to_free = NULL; + struct ip6_flowlabel *flowlabel = NULL; + struct flowi6 fl6; + struct dst_entry *dst; +@@ -1260,8 +1261,10 @@ do_udp_sendmsg: + opt = NULL; + connected = 0; + } +- if (!opt) +- opt = np->opt; ++ if (!opt) { ++ opt = txopt_get(np); ++ opt_to_free = opt; ++ } + if (flowlabel) + opt = fl6_merge_options(&opt_space, flowlabel, opt); + opt = ipv6_fixup_options(&opt_space, opt); +@@ -1370,6 +1373,7 @@ release_dst: + out: + dst_release(dst); + fl6_sock_release(flowlabel); ++ txopt_put(opt_to_free); + if (!err) + return len; + /* +diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c +index d1ded37..0ce9da9 100644 +--- a/net/l2tp/l2tp_ip6.c ++++ b/net/l2tp/l2tp_ip6.c +@@ -486,6 +486,7 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) + DECLARE_SOCKADDR(struct sockaddr_l2tpip6 *, lsa, msg->msg_name); + struct in6_addr *daddr, *final_p, final; + struct ipv6_pinfo *np = inet6_sk(sk); ++ struct ipv6_txoptions *opt_to_free = NULL; + struct ipv6_txoptions *opt = NULL; + struct ip6_flowlabel *flowlabel = NULL; + struct dst_entry *dst = NULL; +@@ -575,8 +576,10 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) + opt = NULL; + } + +- if (opt == NULL) +- opt = np->opt; ++ if (!opt) { ++ opt = txopt_get(np); ++ opt_to_free = opt; ++ } + if (flowlabel) + opt = fl6_merge_options(&opt_space, flowlabel, opt); + opt = ipv6_fixup_options(&opt_space, opt); +@@ -631,6 +634,7 @@ done: + dst_release(dst); + out: + fl6_sock_release(flowlabel); ++ txopt_put(opt_to_free); + + return err < 0 ? err : len; + +-- +2.1.0 + + +From 42b4973eefcdcfc62b49c61f50f9f1e81ae6a615 Mon Sep 17 00:00:00 2001 +From: Konstantin Khlebnikov +Date: Tue, 1 Dec 2015 01:14:48 +0300 +Subject: [PATCH 40/43] net/neighbour: fix crash at dumping device-agnostic + proxy entries + +[ Upstream commit 6adc5fd6a142c6e2c80574c1db0c7c17dedaa42e ] + +Proxy entries could have null pointer to net-device. + +Signed-off-by: Konstantin Khlebnikov +Fixes: 84920c1420e2 ("net: Allow ipv6 proxies and arp proxies be shown with iproute2") +Signed-off-by: David S. Miller +--- + net/core/neighbour.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/net/core/neighbour.c b/net/core/neighbour.c +index 2b515ba..c169bba 100644 +--- a/net/core/neighbour.c ++++ b/net/core/neighbour.c +@@ -2215,7 +2215,7 @@ static int pneigh_fill_info(struct sk_buff *skb, struct pneigh_entry *pn, + ndm->ndm_pad2 = 0; + ndm->ndm_flags = pn->flags | NTF_PROXY; + ndm->ndm_type = RTN_UNICAST; +- ndm->ndm_ifindex = pn->dev->ifindex; ++ ndm->ndm_ifindex = pn->dev ? pn->dev->ifindex : 0; + ndm->ndm_state = NUD_NONE; + + if (nla_put(skb, NDA_DST, tbl->key_len, pn->key)) +@@ -2290,7 +2290,7 @@ static int pneigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb, + if (h > s_h) + s_idx = 0; + for (n = tbl->phash_buckets[h], idx = 0; n; n = n->next) { +- if (dev_net(n->dev) != net) ++ if (pneigh_net(n) != net) + continue; + if (idx < s_idx) + goto next; +-- +2.1.0 + + +From f7391ce93c846664fb548ff4054edc165e7a5442 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Tue, 1 Dec 2015 07:20:07 -0800 +Subject: [PATCH 41/43] ipv6: sctp: implement sctp_v6_destroy_sock() + +[ Upstream commit 602dd62dfbda3e63a2d6a3cbde953ebe82bf5087 ] + +Dmitry Vyukov reported a memory leak using IPV6 SCTP sockets. + +We need to call inet6_destroy_sock() to properly release +inet6 specific fields. + +Reported-by: Dmitry Vyukov +Signed-off-by: Eric Dumazet +Acked-by: Daniel Borkmann +Signed-off-by: David S. Miller +--- + net/sctp/socket.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/net/sctp/socket.c b/net/sctp/socket.c +index 17bef01..3ec88be 100644 +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -7375,6 +7375,13 @@ struct proto sctp_prot = { + + #if IS_ENABLED(CONFIG_IPV6) + ++#include ++static void sctp_v6_destroy_sock(struct sock *sk) ++{ ++ sctp_destroy_sock(sk); ++ inet6_destroy_sock(sk); ++} ++ + struct proto sctpv6_prot = { + .name = "SCTPv6", + .owner = THIS_MODULE, +@@ -7384,7 +7391,7 @@ struct proto sctpv6_prot = { + .accept = sctp_accept, + .ioctl = sctp_ioctl, + .init = sctp_init_sock, +- .destroy = sctp_destroy_sock, ++ .destroy = sctp_v6_destroy_sock, + .shutdown = sctp_shutdown, + .setsockopt = sctp_setsockopt, + .getsockopt = sctp_getsockopt, +-- +2.1.0 + + +From c391cc510c3cf6b5a8dd57fbc1de26b4b28bd7e0 Mon Sep 17 00:00:00 2001 +From: Paolo Abeni +Date: Tue, 1 Dec 2015 18:33:36 +0100 +Subject: [PATCH 42/43] openvswitch: fix hangup on vxlan/gre/geneve device + deletion + +[ Upstream commit 13175303024c8f4cd09e51079a8fcbbe572111ec ] + +Each openvswitch tunnel vport (vxlan,gre,geneve) holds a reference +to the underlying tunnel device, but never released it when such +device is deleted. +Deleting the underlying device via the ip tool cause the kernel to +hangup in the netdev_wait_allrefs() loop. +This commit ensure that on device unregistration dp_detach_port_notify() +is called for all vports that hold the device reference, properly +releasing it. + +Fixes: 614732eaa12d ("openvswitch: Use regular VXLAN net_device device") +Fixes: b2acd1dc3949 ("openvswitch: Use regular GRE net_device instead of vport") +Fixes: 6b001e682e90 ("openvswitch: Use Geneve device.") +Signed-off-by: Paolo Abeni +Acked-by: Flavio Leitner +Acked-by: Pravin B Shelar +Signed-off-by: David S. Miller +--- + net/openvswitch/dp_notify.c | 2 +- + net/openvswitch/vport-netdev.c | 8 ++++++-- + 2 files changed, 7 insertions(+), 3 deletions(-) + +diff --git a/net/openvswitch/dp_notify.c b/net/openvswitch/dp_notify.c +index a7a80a6..653d073 100644 +--- a/net/openvswitch/dp_notify.c ++++ b/net/openvswitch/dp_notify.c +@@ -58,7 +58,7 @@ void ovs_dp_notify_wq(struct work_struct *work) + struct hlist_node *n; + + hlist_for_each_entry_safe(vport, n, &dp->ports[i], dp_hash_node) { +- if (vport->ops->type != OVS_VPORT_TYPE_NETDEV) ++ if (vport->ops->type == OVS_VPORT_TYPE_INTERNAL) + continue; + + if (!(vport->dev->priv_flags & IFF_OVS_DATAPATH)) +diff --git a/net/openvswitch/vport-netdev.c b/net/openvswitch/vport-netdev.c +index f7e8dcc..ac14c48 100644 +--- a/net/openvswitch/vport-netdev.c ++++ b/net/openvswitch/vport-netdev.c +@@ -180,9 +180,13 @@ void ovs_netdev_tunnel_destroy(struct vport *vport) + if (vport->dev->priv_flags & IFF_OVS_DATAPATH) + ovs_netdev_detach_dev(vport); + +- /* Early release so we can unregister the device */ ++ /* We can be invoked by both explicit vport deletion and ++ * underlying netdev deregistration; delete the link only ++ * if it's not already shutting down. ++ */ ++ if (vport->dev->reg_state == NETREG_REGISTERED) ++ rtnl_delete_link(vport->dev); + dev_put(vport->dev); +- rtnl_delete_link(vport->dev); + vport->dev = NULL; + rtnl_unlock(); + +-- +2.1.0 + + +From d6c39cbd9479fcce790b2381042c9405fc170384 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Tue, 1 Dec 2015 20:08:51 -0800 +Subject: [PATCH 43/43] net_sched: fix qdisc_tree_decrease_qlen() races + +[ Upstream commit 4eaf3b84f2881c9c028f1d5e76c52ab575fe3a66 ] + +qdisc_tree_decrease_qlen() suffers from two problems on multiqueue +devices. + +One problem is that it updates sch->q.qlen and sch->qstats.drops +on the mq/mqprio root qdisc, while it should not : Daniele +reported underflows errors : +[ 681.774821] PAX: sch->q.qlen: 0 n: 1 +[ 681.774825] PAX: size overflow detected in function qdisc_tree_decrease_qlen net/sched/sch_api.c:769 cicus.693_49 min, count: 72, decl: qlen; num: 0; context: sk_buff_head; +[ 681.774954] CPU: 2 PID: 19 Comm: ksoftirqd/2 Tainted: G O 4.2.6.201511282239-1-grsec #1 +[ 681.774955] Hardware name: ASUSTeK COMPUTER INC. X302LJ/X302LJ, BIOS X302LJ.202 03/05/2015 +[ 681.774956] ffffffffa9a04863 0000000000000000 0000000000000000 ffffffffa990ff7c +[ 681.774959] ffffc90000d3bc38 ffffffffa95d2810 0000000000000007 ffffffffa991002b +[ 681.774960] ffffc90000d3bc68 ffffffffa91a44f4 0000000000000001 0000000000000001 +[ 681.774962] Call Trace: +[ 681.774967] [] dump_stack+0x4c/0x7f +[ 681.774970] [] report_size_overflow+0x34/0x50 +[ 681.774972] [] qdisc_tree_decrease_qlen+0x152/0x160 +[ 681.774976] [] fq_codel_dequeue+0x7b1/0x820 [sch_fq_codel] +[ 681.774978] [] ? qdisc_peek_dequeued+0xa0/0xa0 [sch_fq_codel] +[ 681.774980] [] __qdisc_run+0x4d/0x1d0 +[ 681.774983] [] net_tx_action+0xc2/0x160 +[ 681.774985] [] __do_softirq+0xf1/0x200 +[ 681.774987] [] run_ksoftirqd+0x1e/0x30 +[ 681.774989] [] smpboot_thread_fn+0x150/0x260 +[ 681.774991] [] ? sort_range+0x40/0x40 +[ 681.774992] [] kthread+0xe4/0x100 +[ 681.774994] [] ? kthread_worker_fn+0x170/0x170 +[ 681.774995] [] ret_from_fork+0x3e/0x70 + +mq/mqprio have their own ways to report qlen/drops by folding stats on +all their queues, with appropriate locking. + +A second problem is that qdisc_tree_decrease_qlen() calls qdisc_lookup() +without proper locking : concurrent qdisc updates could corrupt the list +that qdisc_match_from_root() parses to find a qdisc given its handle. + +Fix first problem adding a TCQ_F_NOPARENT qdisc flag that +qdisc_tree_decrease_qlen() can use to abort its tree traversal, +as soon as it meets a mq/mqprio qdisc children. + +Second problem can be fixed by RCU protection. +Qdisc are already freed after RCU grace period, so qdisc_list_add() and +qdisc_list_del() simply have to use appropriate rcu list variants. + +A future patch will add a per struct netdev_queue list anchor, so that +qdisc_tree_decrease_qlen() can have more efficient lookups. + +Reported-by: Daniele Fucini +Signed-off-by: Eric Dumazet +Cc: Cong Wang +Cc: Jamal Hadi Salim +Signed-off-by: David S. Miller +--- + include/net/sch_generic.h | 3 +++ + net/sched/sch_api.c | 27 ++++++++++++++++++--------- + net/sched/sch_generic.c | 2 +- + net/sched/sch_mq.c | 4 ++-- + net/sched/sch_mqprio.c | 4 ++-- + 5 files changed, 26 insertions(+), 14 deletions(-) + +diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h +index 444faa8..f1ad8f8 100644 +--- a/include/net/sch_generic.h ++++ b/include/net/sch_generic.h +@@ -61,6 +61,9 @@ struct Qdisc { + */ + #define TCQ_F_WARN_NONWC (1 << 16) + #define TCQ_F_CPUSTATS 0x20 /* run using percpu statistics */ ++#define TCQ_F_NOPARENT 0x40 /* root of its hierarchy : ++ * qdisc_tree_decrease_qlen() should stop. ++ */ + u32 limit; + const struct Qdisc_ops *ops; + struct qdisc_size_table __rcu *stab; +diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c +index f43c8f3..7ec667d 100644 +--- a/net/sched/sch_api.c ++++ b/net/sched/sch_api.c +@@ -253,7 +253,8 @@ int qdisc_set_default(const char *name) + } + + /* We know handle. Find qdisc among all qdisc's attached to device +- (root qdisc, all its children, children of children etc.) ++ * (root qdisc, all its children, children of children etc.) ++ * Note: caller either uses rtnl or rcu_read_lock() + */ + + static struct Qdisc *qdisc_match_from_root(struct Qdisc *root, u32 handle) +@@ -264,7 +265,7 @@ static struct Qdisc *qdisc_match_from_root(struct Qdisc *root, u32 handle) + root->handle == handle) + return root; + +- list_for_each_entry(q, &root->list, list) { ++ list_for_each_entry_rcu(q, &root->list, list) { + if (q->handle == handle) + return q; + } +@@ -277,15 +278,18 @@ void qdisc_list_add(struct Qdisc *q) + struct Qdisc *root = qdisc_dev(q)->qdisc; + + WARN_ON_ONCE(root == &noop_qdisc); +- list_add_tail(&q->list, &root->list); ++ ASSERT_RTNL(); ++ list_add_tail_rcu(&q->list, &root->list); + } + } + EXPORT_SYMBOL(qdisc_list_add); + + void qdisc_list_del(struct Qdisc *q) + { +- if ((q->parent != TC_H_ROOT) && !(q->flags & TCQ_F_INGRESS)) +- list_del(&q->list); ++ if ((q->parent != TC_H_ROOT) && !(q->flags & TCQ_F_INGRESS)) { ++ ASSERT_RTNL(); ++ list_del_rcu(&q->list); ++ } + } + EXPORT_SYMBOL(qdisc_list_del); + +@@ -750,14 +754,18 @@ void qdisc_tree_decrease_qlen(struct Qdisc *sch, unsigned int n) + if (n == 0) + return; + drops = max_t(int, n, 0); ++ rcu_read_lock(); + while ((parentid = sch->parent)) { + if (TC_H_MAJ(parentid) == TC_H_MAJ(TC_H_INGRESS)) +- return; ++ break; + ++ if (sch->flags & TCQ_F_NOPARENT) ++ break; ++ /* TODO: perform the search on a per txq basis */ + sch = qdisc_lookup(qdisc_dev(sch), TC_H_MAJ(parentid)); + if (sch == NULL) { +- WARN_ON(parentid != TC_H_ROOT); +- return; ++ WARN_ON_ONCE(parentid != TC_H_ROOT); ++ break; + } + cops = sch->ops->cl_ops; + if (cops->qlen_notify) { +@@ -768,6 +776,7 @@ void qdisc_tree_decrease_qlen(struct Qdisc *sch, unsigned int n) + sch->q.qlen -= n; + __qdisc_qstats_drop(sch, drops); + } ++ rcu_read_unlock(); + } + EXPORT_SYMBOL(qdisc_tree_decrease_qlen); + +@@ -941,7 +950,7 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue, + } + lockdep_set_class(qdisc_lock(sch), &qdisc_tx_lock); + if (!netif_is_multiqueue(dev)) +- sch->flags |= TCQ_F_ONETXQUEUE; ++ sch->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT; + } + + sch->handle = handle; +diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c +index cb5d4ad..e82a1ad 100644 +--- a/net/sched/sch_generic.c ++++ b/net/sched/sch_generic.c +@@ -737,7 +737,7 @@ static void attach_one_default_qdisc(struct net_device *dev, + return; + } + if (!netif_is_multiqueue(dev)) +- qdisc->flags |= TCQ_F_ONETXQUEUE; ++ qdisc->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT; + dev_queue->qdisc_sleeping = qdisc; + } + +diff --git a/net/sched/sch_mq.c b/net/sched/sch_mq.c +index f3cbaec..3e82f04 100644 +--- a/net/sched/sch_mq.c ++++ b/net/sched/sch_mq.c +@@ -63,7 +63,7 @@ static int mq_init(struct Qdisc *sch, struct nlattr *opt) + if (qdisc == NULL) + goto err; + priv->qdiscs[ntx] = qdisc; +- qdisc->flags |= TCQ_F_ONETXQUEUE; ++ qdisc->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT; + } + + sch->flags |= TCQ_F_MQROOT; +@@ -156,7 +156,7 @@ static int mq_graft(struct Qdisc *sch, unsigned long cl, struct Qdisc *new, + + *old = dev_graft_qdisc(dev_queue, new); + if (new) +- new->flags |= TCQ_F_ONETXQUEUE; ++ new->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT; + if (dev->flags & IFF_UP) + dev_activate(dev); + return 0; +diff --git a/net/sched/sch_mqprio.c b/net/sched/sch_mqprio.c +index 3811a74..ad70ecf 100644 +--- a/net/sched/sch_mqprio.c ++++ b/net/sched/sch_mqprio.c +@@ -132,7 +132,7 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt) + goto err; + } + priv->qdiscs[i] = qdisc; +- qdisc->flags |= TCQ_F_ONETXQUEUE; ++ qdisc->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT; + } + + /* If the mqprio options indicate that hardware should own +@@ -209,7 +209,7 @@ static int mqprio_graft(struct Qdisc *sch, unsigned long cl, struct Qdisc *new, + *old = dev_graft_qdisc(dev_queue, new); + + if (new) +- new->flags |= TCQ_F_ONETXQUEUE; ++ new->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT; + + if (dev->flags & IFF_UP) + dev_activate(dev); +-- +2.1.0 + diff --git a/kernel/kernel/files/patches/mageia/stable-arm-8449-1-fix-bug-in-vdsomunge-swab32-macro.patch b/kernel/kernel/files/patches/mageia/stable-arm-8449-1-fix-bug-in-vdsomunge-swab32-macro.patch deleted file mode 100644 index 75e9e9e0..00000000 --- a/kernel/kernel/files/patches/mageia/stable-arm-8449-1-fix-bug-in-vdsomunge-swab32-macro.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 38850d786a799c3ff2de0dc1980902c3263698dc Mon Sep 17 00:00:00 2001 -From: "H. Nikolaus Schaller" -Date: Wed, 28 Oct 2015 19:00:26 +0100 -Subject: ARM: 8449/1: fix bug in vdsomunge swab32 macro - -From: "H. Nikolaus Schaller" - -commit 38850d786a799c3ff2de0dc1980902c3263698dc upstream. - -Commit 8a603f91cc48 ("ARM: 8445/1: fix vdsomunge not to depend on -glibc specific byteswap.h") unfortunately introduced a bug created but -not found during discussion and patch simplification. - -Reported-by: Efraim Yawitz -Signed-off-by: H. Nikolaus Schaller -Fixes: 8a603f91cc48 ("ARM: 8445/1: fix vdsomunge not to depend on glibc specific byteswap.h") -Signed-off-by: Nathan Lynch -Signed-off-by: Russell King -Signed-off-by: Greg Kroah-Hartman - ---- - arch/arm/vdso/vdsomunge.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/arch/arm/vdso/vdsomunge.c -+++ b/arch/arm/vdso/vdsomunge.c -@@ -66,7 +66,7 @@ - ((((x) & 0x000000ff) << 24) | \ - (((x) & 0x0000ff00) << 8) | \ - (((x) & 0x00ff0000) >> 8) | \ -- (((x) & 0xff000000) << 24)) -+ (((x) & 0xff000000) >> 24)) - - #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - #define HOST_ORDER ELFDATA2LSB diff --git a/kernel/kernel/files/patches/mageia/stable-bonding-fix-panic-on-non-arphrd_ether-enslave-failure.patch b/kernel/kernel/files/patches/mageia/stable-bonding-fix-panic-on-non-arphrd_ether-enslave-failure.patch deleted file mode 100644 index e1098d87..00000000 --- a/kernel/kernel/files/patches/mageia/stable-bonding-fix-panic-on-non-arphrd_ether-enslave-failure.patch +++ /dev/null @@ -1,44 +0,0 @@ -From foo@baz Tue Nov 17 14:33:46 PST 2015 -From: Jay Vosburgh -Date: Fri, 6 Nov 2015 17:23:23 -0800 -Subject: bonding: fix panic on non-ARPHRD_ETHER enslave failure - -From: Jay Vosburgh - -[ Upstream commit 40baec225765c54eefa870530dd613bad9829bb7 ] - -Since commit 7d5cd2ce529b, when bond_enslave fails on devices that -are not ARPHRD_ETHER, if needed, it resets the bonding device back to -ARPHRD_ETHER by calling ether_setup. - - Unfortunately, ether_setup clobbers dev->flags, clearing IFF_UP -if the bond device is up, leaving it in a quasi-down state without -having actually gone through dev_close. For bonding, if any periodic -work queue items are active (miimon, arp_interval, etc), those will -remain running, as they are stopped by bond_close. At this point, if -the bonding module is unloaded or the bond is deleted, the system will -panic when the work function is called. - - This panic is resolved by calling dev_close on the bond itself -prior to calling ether_setup. - -Cc: Nikolay Aleksandrov -Signed-off-by: Jay Vosburgh -Fixes: 7d5cd2ce5292 ("bonding: correctly handle bonding type change on enslave failure") -Acked-by: Nikolay Aleksandrov -Signed-off-by: David S. Miller -Signed-off-by: Greg Kroah-Hartman ---- - drivers/net/bonding/bond_main.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/bonding/bond_main.c -+++ b/drivers/net/bonding/bond_main.c -@@ -1749,6 +1749,7 @@ err_undo_flags: - slave_dev->dev_addr)) - eth_hw_addr_random(bond_dev); - if (bond_dev->type != ARPHRD_ETHER) { -+ dev_close(bond_dev); - ether_setup(bond_dev); - bond_dev->flags |= IFF_MASTER; - bond_dev->priv_flags &= ~IFF_TX_SKB_SHARING; diff --git a/kernel/kernel/files/patches/mageia/stable-ipmr-fix-possible-race-resulting-from-improper-usage-of-ip_inc_stats_bh-in-preemptible-context.patch b/kernel/kernel/files/patches/mageia/stable-ipmr-fix-possible-race-resulting-from-improper-usage-of-ip_inc_stats_bh-in-preemptible-context.patch deleted file mode 100644 index 60bd8b15..00000000 --- a/kernel/kernel/files/patches/mageia/stable-ipmr-fix-possible-race-resulting-from-improper-usage-of-ip_inc_stats_bh-in-preemptible-context.patch +++ /dev/null @@ -1,75 +0,0 @@ -From foo@baz Tue Nov 17 14:33:46 PST 2015 -From: Ani Sinha -Date: Fri, 30 Oct 2015 16:54:31 -0700 -Subject: ipmr: fix possible race resulting from improper usage of IP_INC_STATS_BH() in preemptible context. - -From: Ani Sinha - -[ Upstream commit 44f49dd8b5a606870a1f21101522a0f9c4414784 ] - -Fixes the following kernel BUG : - -BUG: using __this_cpu_add() in preemptible [00000000] code: bash/2758 -caller is __this_cpu_preempt_check+0x13/0x15 -CPU: 0 PID: 2758 Comm: bash Tainted: P O 3.18.19 #2 - ffffffff8170eaca ffff880110d1b788 ffffffff81482b2a 0000000000000000 - 0000000000000000 ffff880110d1b7b8 ffffffff812010ae ffff880007cab800 - ffff88001a060800 ffff88013a899108 ffff880108b84240 ffff880110d1b7c8 -Call Trace: -[] dump_stack+0x52/0x80 -[] check_preemption_disabled+0xce/0xe1 -[] __this_cpu_preempt_check+0x13/0x15 -[] ipmr_queue_xmit+0x647/0x70c -[] ip_mr_forward+0x32f/0x34e -[] ip_mroute_setsockopt+0xe03/0x108c -[] ? get_parent_ip+0x11/0x42 -[] ? pollwake+0x4d/0x51 -[] ? default_wake_function+0x0/0xf -[] ? get_parent_ip+0x11/0x42 -[] ? __wake_up_common+0x45/0x77 -[] ? _raw_spin_unlock_irqrestore+0x1d/0x32 -[] ? __wake_up_sync_key+0x4a/0x53 -[] ? sock_def_readable+0x71/0x75 -[] do_ip_setsockopt+0x9d/0xb55 -[] ? unix_seqpacket_sendmsg+0x3f/0x41 -[] ? sock_sendmsg+0x6d/0x86 -[] ? sockfd_lookup_light+0x12/0x5d -[] ? SyS_sendto+0xf3/0x11b -[] ? new_sync_read+0x82/0xaa -[] compat_ip_setsockopt+0x3b/0x99 -[] compat_raw_setsockopt+0x11/0x32 -[] compat_sock_common_setsockopt+0x18/0x1f -[] compat_SyS_setsockopt+0x1a9/0x1cf -[] compat_SyS_socketcall+0x180/0x1e3 -[] cstar_dispatch+0x7/0x1e - -Signed-off-by: Ani Sinha -Acked-by: Eric Dumazet -Signed-off-by: David S. Miller -Signed-off-by: Greg Kroah-Hartman ---- - net/ipv4/ipmr.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/net/ipv4/ipmr.c -+++ b/net/ipv4/ipmr.c -@@ -1682,8 +1682,8 @@ static inline int ipmr_forward_finish(st - { - struct ip_options *opt = &(IPCB(skb)->opt); - -- IP_INC_STATS_BH(dev_net(skb_dst(skb)->dev), IPSTATS_MIB_OUTFORWDATAGRAMS); -- IP_ADD_STATS_BH(dev_net(skb_dst(skb)->dev), IPSTATS_MIB_OUTOCTETS, skb->len); -+ IP_INC_STATS(dev_net(skb_dst(skb)->dev), IPSTATS_MIB_OUTFORWDATAGRAMS); -+ IP_ADD_STATS(dev_net(skb_dst(skb)->dev), IPSTATS_MIB_OUTOCTETS, skb->len); - - if (unlikely(opt->optlen)) - ip_forward_options(skb); -@@ -1745,7 +1745,7 @@ static void ipmr_queue_xmit(struct net * - * to blackhole. - */ - -- IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_FRAGFAILS); -+ IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGFAILS); - ip_rt_put(rt); - goto out_free; - } diff --git a/kernel/kernel/files/patches/mageia/stable-ipv4-disable-bh-when-changing-ip-local-port-range.patch b/kernel/kernel/files/patches/mageia/stable-ipv4-disable-bh-when-changing-ip-local-port-range.patch deleted file mode 100644 index e5b5ff20..00000000 --- a/kernel/kernel/files/patches/mageia/stable-ipv4-disable-bh-when-changing-ip-local-port-range.patch +++ /dev/null @@ -1,66 +0,0 @@ -From foo@baz Tue Nov 17 14:33:46 PST 2015 -From: WANG Cong -Date: Tue, 3 Nov 2015 14:32:57 -0800 -Subject: ipv4: disable BH when changing ip local port range - -From: WANG Cong - -[ Upstream commit 4ee3bd4a8c7463cdef0b82ebc33fc94a9170a7e0 ] - -This fixes the following lockdep warning: - - [ INFO: inconsistent lock state ] - 4.3.0-rc7+ #1197 Not tainted - --------------------------------- - inconsistent {IN-SOFTIRQ-R} -> {SOFTIRQ-ON-W} usage. - sysctl/1019 [HC0[0]:SC0[0]:HE1:SE1] takes: - (&(&net->ipv4.ip_local_ports.lock)->seqcount){+.+-..}, at: [] ipv4_local_port_range+0xb4/0x12a - {IN-SOFTIRQ-R} state was registered at: - [] __lock_acquire+0x2f6/0xdf0 - [] lock_acquire+0x11c/0x1a4 - [] inet_get_local_port_range+0x4e/0xae - [] udp_flow_src_port.constprop.40+0x23/0x116 - [] vxlan_xmit_one+0x219/0xa6a - [] vxlan_xmit+0xa6b/0xaa5 - [] dev_hard_start_xmit+0x2ae/0x465 - [] __dev_queue_xmit+0x531/0x633 - [] dev_queue_xmit_sk+0x13/0x15 - [] neigh_resolve_output+0x12f/0x14d - [] ip6_finish_output2+0x344/0x39f - [] ip6_finish_output+0x88/0x8e - [] ip6_output+0x91/0xe5 - [] dst_output_sk+0x47/0x4c - [] NF_HOOK_THRESH.constprop.30+0x38/0x82 - [] mld_sendpack+0x189/0x266 - [] mld_ifc_timer_expire+0x1ef/0x223 - [] call_timer_fn+0xfb/0x28c - [] run_timer_softirq+0x1c7/0x1f1 - -Fixes: b8f1a55639e6 ("udp: Add function to make source port for UDP tunnels") -Cc: Tom Herbert -Signed-off-by: Cong Wang -Signed-off-by: David S. Miller -Signed-off-by: Greg Kroah-Hartman ---- - net/ipv4/sysctl_net_ipv4.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/net/ipv4/sysctl_net_ipv4.c -+++ b/net/ipv4/sysctl_net_ipv4.c -@@ -48,14 +48,14 @@ static void set_local_port_range(struct - { - bool same_parity = !((range[0] ^ range[1]) & 1); - -- write_seqlock(&net->ipv4.ip_local_ports.lock); -+ write_seqlock_bh(&net->ipv4.ip_local_ports.lock); - if (same_parity && !net->ipv4.ip_local_ports.warned) { - net->ipv4.ip_local_ports.warned = true; - pr_err_ratelimited("ip_local_port_range: prefer different parity for start/end values.\n"); - } - net->ipv4.ip_local_ports.range[0] = range[0]; - net->ipv4.ip_local_ports.range[1] = range[1]; -- write_sequnlock(&net->ipv4.ip_local_ports.lock); -+ write_sequnlock_bh(&net->ipv4.ip_local_ports.lock); - } - - /* Validate changes from /proc interface. */ diff --git a/kernel/kernel/files/patches/mageia/stable-ipv4-fix-to-not-remove-local-route-on-link-down.patch b/kernel/kernel/files/patches/mageia/stable-ipv4-fix-to-not-remove-local-route-on-link-down.patch deleted file mode 100644 index d870c43b..00000000 --- a/kernel/kernel/files/patches/mageia/stable-ipv4-fix-to-not-remove-local-route-on-link-down.patch +++ /dev/null @@ -1,120 +0,0 @@ -From foo@baz Tue Nov 17 14:33:46 PST 2015 -From: Julian Anastasov -Date: Fri, 30 Oct 2015 10:23:33 +0200 -Subject: ipv4: fix to not remove local route on link down - -From: Julian Anastasov - -[ Upstream commit 4f823defdd5b106a5e89745ee8b163c71855de1e ] - -When fib_netdev_event calls fib_disable_ip on NETDEV_DOWN event -we should not delete the local routes if the local address -is still present. The confusion comes from the fact that both -fib_netdev_event and fib_inetaddr_event use the NETDEV_DOWN -constant. Fix it by returning back the variable 'force'. - -Steps to reproduce: -modprobe dummy -ifconfig dummy0 192.168.168.1 up -ifconfig dummy0 down -ip route list table local | grep dummy | grep host -local 192.168.168.1 dev dummy0 proto kernel scope host src 192.168.168.1 - -Fixes: 8a3d03166f19 ("net: track link-status of ipv4 nexthops") -Signed-off-by: Julian Anastasov -Signed-off-by: David S. Miller -Signed-off-by: Greg Kroah-Hartman ---- - include/net/ip_fib.h | 2 +- - net/ipv4/fib_frontend.c | 13 +++++++------ - net/ipv4/fib_semantics.c | 11 ++++++++--- - 3 files changed, 16 insertions(+), 10 deletions(-) - ---- a/include/net/ip_fib.h -+++ b/include/net/ip_fib.h -@@ -317,7 +317,7 @@ void fib_flush_external(struct net *net) - - /* Exported by fib_semantics.c */ - int ip_fib_check_default(__be32 gw, struct net_device *dev); --int fib_sync_down_dev(struct net_device *dev, unsigned long event); -+int fib_sync_down_dev(struct net_device *dev, unsigned long event, bool force); - int fib_sync_down_addr(struct net *net, __be32 local); - int fib_sync_up(struct net_device *dev, unsigned int nh_flags); - void fib_select_multipath(struct fib_result *res); ---- a/net/ipv4/fib_frontend.c -+++ b/net/ipv4/fib_frontend.c -@@ -1110,9 +1110,10 @@ static void nl_fib_lookup_exit(struct ne - net->ipv4.fibnl = NULL; - } - --static void fib_disable_ip(struct net_device *dev, unsigned long event) -+static void fib_disable_ip(struct net_device *dev, unsigned long event, -+ bool force) - { -- if (fib_sync_down_dev(dev, event)) -+ if (fib_sync_down_dev(dev, event, force)) - fib_flush(dev_net(dev)); - rt_cache_flush(dev_net(dev)); - arp_ifdown(dev); -@@ -1140,7 +1141,7 @@ static int fib_inetaddr_event(struct not - /* Last address was deleted from this interface. - * Disable IP. - */ -- fib_disable_ip(dev, event); -+ fib_disable_ip(dev, event, true); - } else { - rt_cache_flush(dev_net(dev)); - } -@@ -1157,7 +1158,7 @@ static int fib_netdev_event(struct notif - unsigned int flags; - - if (event == NETDEV_UNREGISTER) { -- fib_disable_ip(dev, event); -+ fib_disable_ip(dev, event, true); - rt_flush_dev(dev); - return NOTIFY_DONE; - } -@@ -1178,14 +1179,14 @@ static int fib_netdev_event(struct notif - rt_cache_flush(net); - break; - case NETDEV_DOWN: -- fib_disable_ip(dev, event); -+ fib_disable_ip(dev, event, false); - break; - case NETDEV_CHANGE: - flags = dev_get_flags(dev); - if (flags & (IFF_RUNNING | IFF_LOWER_UP)) - fib_sync_up(dev, RTNH_F_LINKDOWN); - else -- fib_sync_down_dev(dev, event); -+ fib_sync_down_dev(dev, event, false); - /* fall through */ - case NETDEV_CHANGEMTU: - rt_cache_flush(net); ---- a/net/ipv4/fib_semantics.c -+++ b/net/ipv4/fib_semantics.c -@@ -1281,7 +1281,13 @@ int fib_sync_down_addr(struct net *net, - return ret; - } - --int fib_sync_down_dev(struct net_device *dev, unsigned long event) -+/* Event force Flags Description -+ * NETDEV_CHANGE 0 LINKDOWN Carrier OFF, not for scope host -+ * NETDEV_DOWN 0 LINKDOWN|DEAD Link down, not for scope host -+ * NETDEV_DOWN 1 LINKDOWN|DEAD Last address removed -+ * NETDEV_UNREGISTER 1 LINKDOWN|DEAD Device removed -+ */ -+int fib_sync_down_dev(struct net_device *dev, unsigned long event, bool force) - { - int ret = 0; - int scope = RT_SCOPE_NOWHERE; -@@ -1290,8 +1296,7 @@ int fib_sync_down_dev(struct net_device - struct hlist_head *head = &fib_info_devhash[hash]; - struct fib_nh *nh; - -- if (event == NETDEV_UNREGISTER || -- event == NETDEV_DOWN) -+ if (force) - scope = -1; - - hlist_for_each_entry(nh, head, nh_hash) { diff --git a/kernel/kernel/files/patches/mageia/stable-ipv4-update-rtnh_f_linkdown-flag-on-up-event.patch b/kernel/kernel/files/patches/mageia/stable-ipv4-update-rtnh_f_linkdown-flag-on-up-event.patch deleted file mode 100644 index 8497ac23..00000000 --- a/kernel/kernel/files/patches/mageia/stable-ipv4-update-rtnh_f_linkdown-flag-on-up-event.patch +++ /dev/null @@ -1,62 +0,0 @@ -From foo@baz Tue Nov 17 14:33:46 PST 2015 -From: Julian Anastasov -Date: Fri, 30 Oct 2015 10:23:34 +0200 -Subject: ipv4: update RTNH_F_LINKDOWN flag on UP event - -From: Julian Anastasov - -[ Upstream commit c9b3292eeb52c6834e972eb5b8fe38914771ed12 ] - -When nexthop is part of multipath route we should clear the -LINKDOWN flag when link goes UP or when first address is added. -This is needed because we always set LINKDOWN flag when DEAD flag -was set but now on UP the nexthop is not dead anymore. Examples when -LINKDOWN bit can be forgotten when no NETDEV_CHANGE is delivered: - -- link goes down (LINKDOWN is set), then link goes UP and device -shows carrier OK but LINKDOWN remains set - -- last address is deleted (LINKDOWN is set), then address is -added and device shows carrier OK but LINKDOWN remains set - -Steps to reproduce: -modprobe dummy -ifconfig dummy0 192.168.168.1 up - -here add a multipath route where one nexthop is for dummy0: - -ip route add 1.2.3.4 nexthop dummy0 nexthop SOME_OTHER_DEVICE -ifconfig dummy0 down -ifconfig dummy0 up - -now ip route shows nexthop that is not dead. Now set the sysctl var: - -echo 1 > /proc/sys/net/ipv4/conf/dummy0/ignore_routes_with_linkdown - -now ip route will show a dead nexthop because the forgotten -RTNH_F_LINKDOWN is propagated as RTNH_F_DEAD. - -Fixes: 8a3d03166f19 ("net: track link-status of ipv4 nexthops") -Signed-off-by: Julian Anastasov -Signed-off-by: David S. Miller -Signed-off-by: Greg Kroah-Hartman ---- - net/ipv4/fib_semantics.c | 7 +++++++ - 1 file changed, 7 insertions(+) - ---- a/net/ipv4/fib_semantics.c -+++ b/net/ipv4/fib_semantics.c -@@ -1445,6 +1445,13 @@ int fib_sync_up(struct net_device *dev, - if (!(dev->flags & IFF_UP)) - return 0; - -+ if (nh_flags & RTNH_F_DEAD) { -+ unsigned int flags = dev_get_flags(dev); -+ -+ if (flags & (IFF_RUNNING | IFF_LOWER_UP)) -+ nh_flags |= RTNH_F_LINKDOWN; -+ } -+ - prev_fi = NULL; - hash = fib_devindex_hashfn(dev->ifindex); - head = &fib_info_devhash[hash]; diff --git a/kernel/kernel/files/patches/mageia/stable-ipv6-clean-up-dev_snmp6-proc-entry-when-we-fail-to-initialize-inet6_dev.patch b/kernel/kernel/files/patches/mageia/stable-ipv6-clean-up-dev_snmp6-proc-entry-when-we-fail-to-initialize-inet6_dev.patch deleted file mode 100644 index b8b89098..00000000 --- a/kernel/kernel/files/patches/mageia/stable-ipv6-clean-up-dev_snmp6-proc-entry-when-we-fail-to-initialize-inet6_dev.patch +++ /dev/null @@ -1,32 +0,0 @@ -From foo@baz Tue Nov 17 14:33:46 PST 2015 -From: Sabrina Dubroca -Date: Wed, 4 Nov 2015 14:47:53 +0100 -Subject: ipv6: clean up dev_snmp6 proc entry when we fail to initialize inet6_dev - -From: Sabrina Dubroca - -[ Upstream commit 2a189f9e57650e9f310ddf4aad75d66c1233a064 ] - -In ipv6_add_dev, when addrconf_sysctl_register fails, we do not clean up -the dev_snmp6 entry that we have already registered for this device. -Call snmp6_unregister_dev in this case. - -Fixes: a317a2f19da7d ("ipv6: fail early when creating netdev named all or default") -Reported-by: Dmitry Vyukov -Signed-off-by: Sabrina Dubroca -Signed-off-by: David S. Miller -Signed-off-by: Greg Kroah-Hartman ---- - net/ipv6/addrconf.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/net/ipv6/addrconf.c -+++ b/net/ipv6/addrconf.c -@@ -417,6 +417,7 @@ static struct inet6_dev *ipv6_add_dev(st - if (err) { - ipv6_mc_destroy_dev(ndev); - del_timer(&ndev->regen_timer); -+ snmp6_unregister_dev(ndev); - goto err_release; - } - /* protected by rtnl_lock */ diff --git a/kernel/kernel/files/patches/mageia/stable-net-avoid-null-deref-in-inet_ctl_sock_destroy.patch b/kernel/kernel/files/patches/mageia/stable-net-avoid-null-deref-in-inet_ctl_sock_destroy.patch deleted file mode 100644 index 19ff7872..00000000 --- a/kernel/kernel/files/patches/mageia/stable-net-avoid-null-deref-in-inet_ctl_sock_destroy.patch +++ /dev/null @@ -1,33 +0,0 @@ -From foo@baz Tue Nov 17 14:33:46 PST 2015 -From: Eric Dumazet -Date: Mon, 2 Nov 2015 07:50:07 -0800 -Subject: net: avoid NULL deref in inet_ctl_sock_destroy() - -From: Eric Dumazet - -[ Upstream commit 8fa677d2706d325d71dab91bf6e6512c05214e37 ] - -Under low memory conditions, tcp_sk_init() and icmp_sk_init() -can both iterate on all possible cpus and call inet_ctl_sock_destroy(), -with eventual NULL pointer. - -Signed-off-by: Eric Dumazet -Reported-by: Dmitry Vyukov -Signed-off-by: David S. Miller -Signed-off-by: Greg Kroah-Hartman ---- - include/net/inet_common.h | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/include/net/inet_common.h -+++ b/include/net/inet_common.h -@@ -41,7 +41,8 @@ int inet_recv_error(struct sock *sk, str - - static inline void inet_ctl_sock_destroy(struct sock *sk) - { -- sock_release(sk->sk_socket); -+ if (sk) -+ sock_release(sk->sk_socket); - } - - #endif diff --git a/kernel/kernel/files/patches/mageia/stable-net-bcmgenet-software-reset-ephy-after-power-on.patch b/kernel/kernel/files/patches/mageia/stable-net-bcmgenet-software-reset-ephy-after-power-on.patch deleted file mode 100644 index 31b1823d..00000000 --- a/kernel/kernel/files/patches/mageia/stable-net-bcmgenet-software-reset-ephy-after-power-on.patch +++ /dev/null @@ -1,91 +0,0 @@ -From foo@baz Tue Nov 17 14:33:46 PST 2015 -From: Florian Fainelli -Date: Thu, 29 Oct 2015 18:11:35 -0700 -Subject: net: bcmgenet: Software reset EPHY after power on - -From: Florian Fainelli - -[ Upstream commit 5dbebbb44a6ad94aab2cd1a46f7676f255403f64 ] - -The EPHY on GENET v1->v3 is extremely finicky, and will show occasional -failures based on the timing and reset sequence, ranging from duplicate -packets, to extremely high latencies. - -Perform an additional software reset, and re-configuration to make sure it is -in a consistent and working state. - -Fixes: 6ac3ce8295e6 ("net: bcmgenet: Remove excessive PHY reset") -Signed-off-by: Florian Fainelli -Signed-off-by: David S. Miller -Signed-off-by: Greg Kroah-Hartman ---- - drivers/net/ethernet/broadcom/genet/bcmgenet.c | 4 +++- - drivers/net/ethernet/broadcom/genet/bcmgenet.h | 1 + - drivers/net/ethernet/broadcom/genet/bcmmii.c | 18 ++++++++++++++++++ - 3 files changed, 22 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c -+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c -@@ -907,8 +907,10 @@ static void bcmgenet_power_up(struct bcm - } - - bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT); -- if (mode == GENET_POWER_PASSIVE) -+ if (mode == GENET_POWER_PASSIVE) { - bcmgenet_phy_power_set(priv->dev, true); -+ bcmgenet_mii_reset(priv->dev); -+ } - } - - /* ioctl handle special commands that are not present in ethtool. */ ---- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h -+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h -@@ -674,6 +674,7 @@ int bcmgenet_mii_init(struct net_device - int bcmgenet_mii_config(struct net_device *dev); - int bcmgenet_mii_probe(struct net_device *dev); - void bcmgenet_mii_exit(struct net_device *dev); -+void bcmgenet_mii_reset(struct net_device *dev); - void bcmgenet_phy_power_set(struct net_device *dev, bool enable); - void bcmgenet_mii_setup(struct net_device *dev); - ---- a/drivers/net/ethernet/broadcom/genet/bcmmii.c -+++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c -@@ -163,6 +163,7 @@ void bcmgenet_mii_setup(struct net_devic - phy_print_status(phydev); - } - -+ - static int bcmgenet_fixed_phy_link_update(struct net_device *dev, - struct fixed_phy_status *status) - { -@@ -172,6 +173,22 @@ static int bcmgenet_fixed_phy_link_updat - return 0; - } - -+/* Perform a voluntary PHY software reset, since the EPHY is very finicky about -+ * not doing it and will start corrupting packets -+ */ -+void bcmgenet_mii_reset(struct net_device *dev) -+{ -+ struct bcmgenet_priv *priv = netdev_priv(dev); -+ -+ if (GENET_IS_V4(priv)) -+ return; -+ -+ if (priv->phydev) { -+ phy_init_hw(priv->phydev); -+ phy_start_aneg(priv->phydev); -+ } -+} -+ - void bcmgenet_phy_power_set(struct net_device *dev, bool enable) - { - struct bcmgenet_priv *priv = netdev_priv(dev); -@@ -214,6 +231,7 @@ static void bcmgenet_internal_phy_setup( - reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT); - reg |= EXT_PWR_DN_EN_LD; - bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT); -+ bcmgenet_mii_reset(dev); - } - - static void bcmgenet_moca_phy_setup(struct bcmgenet_priv *priv) diff --git a/kernel/kernel/files/patches/mageia/stable-net-fix-a-race-in-dst_release.patch b/kernel/kernel/files/patches/mageia/stable-net-fix-a-race-in-dst_release.patch deleted file mode 100644 index a34a66ea..00000000 --- a/kernel/kernel/files/patches/mageia/stable-net-fix-a-race-in-dst_release.patch +++ /dev/null @@ -1,34 +0,0 @@ -From foo@baz Tue Nov 17 14:33:46 PST 2015 -From: Eric Dumazet -Date: Mon, 9 Nov 2015 17:51:23 -0800 -Subject: net: fix a race in dst_release() - -From: Eric Dumazet - -[ Upstream commit d69bbf88c8d0b367cf3e3a052f6daadf630ee566 ] - -Only cpu seeing dst refcount going to 0 can safely -dereference dst->flags. - -Otherwise an other cpu might already have freed the dst. - -Fixes: 27b75c95f10d ("net: avoid RCU for NOCACHE dst") -Reported-by: Greg Thelen -Signed-off-by: Eric Dumazet -Signed-off-by: David S. Miller -Signed-off-by: Greg Kroah-Hartman ---- - net/core/dst.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/net/core/dst.c -+++ b/net/core/dst.c -@@ -306,7 +306,7 @@ void dst_release(struct dst_entry *dst) - if (unlikely(newrefcnt < 0)) - net_warn_ratelimited("%s: dst:%p refcnt:%d\n", - __func__, dst, newrefcnt); -- if (unlikely(dst->flags & DST_NOCACHE) && !newrefcnt) -+ if (!newrefcnt && unlikely(dst->flags & DST_NOCACHE)) - call_rcu(&dst->rcu_head, dst_destroy_rcu); - } - } diff --git a/kernel/kernel/files/patches/mageia/stable-net-fix-prefsrc-lookups.patch b/kernel/kernel/files/patches/mageia/stable-net-fix-prefsrc-lookups.patch deleted file mode 100644 index 66d1c7ae..00000000 --- a/kernel/kernel/files/patches/mageia/stable-net-fix-prefsrc-lookups.patch +++ /dev/null @@ -1,55 +0,0 @@ -From foo@baz Tue Nov 17 14:33:46 PST 2015 -From: David Ahern -Date: Tue, 3 Nov 2015 15:59:28 -0800 -Subject: net: Fix prefsrc lookups - -From: David Ahern - -[ Upstream commit e1b8d903c6c3862160d2d5036806a94786c8fc4e ] - -A bug report (https://bugzilla.kernel.org/show_bug.cgi?id=107071) noted -that the follwoing ip command is failing with v4.3: - - $ ip route add 10.248.5.0/24 dev bond0.250 table vlan_250 src 10.248.5.154 - RTNETLINK answers: Invalid argument - -021dd3b8a142d changed the lookup of the given preferred source address to -use the table id passed in, but this assumes the local entries are in the -given table which is not necessarily true for non-VRF use cases. When -validating the preferred source fallback to the local table on failure. - -Fixes: 021dd3b8a142d ("net: Add routes to the table associated with the device") -Signed-off-by: David Ahern -Signed-off-by: David S. Miller -Signed-off-by: Greg Kroah-Hartman ---- - net/ipv4/fib_semantics.c | 13 ++++++++++--- - 1 file changed, 10 insertions(+), 3 deletions(-) - ---- a/net/ipv4/fib_semantics.c -+++ b/net/ipv4/fib_semantics.c -@@ -864,14 +864,21 @@ static bool fib_valid_prefsrc(struct fib - if (cfg->fc_type != RTN_LOCAL || !cfg->fc_dst || - fib_prefsrc != cfg->fc_dst) { - u32 tb_id = cfg->fc_table; -+ int rc; - - if (tb_id == RT_TABLE_MAIN) - tb_id = RT_TABLE_LOCAL; - -- if (inet_addr_type_table(cfg->fc_nlinfo.nl_net, -- fib_prefsrc, tb_id) != RTN_LOCAL) { -- return false; -+ rc = inet_addr_type_table(cfg->fc_nlinfo.nl_net, -+ fib_prefsrc, tb_id); -+ -+ if (rc != RTN_LOCAL && tb_id != RT_TABLE_LOCAL) { -+ rc = inet_addr_type_table(cfg->fc_nlinfo.nl_net, -+ fib_prefsrc, RT_TABLE_LOCAL); - } -+ -+ if (rc != RTN_LOCAL) -+ return false; - } - return true; - } diff --git a/kernel/kernel/files/patches/mageia/stable-packet-race-condition-in-packet_bind.patch b/kernel/kernel/files/patches/mageia/stable-packet-race-condition-in-packet_bind.patch deleted file mode 100644 index ae626668..00000000 --- a/kernel/kernel/files/patches/mageia/stable-packet-race-condition-in-packet_bind.patch +++ /dev/null @@ -1,231 +0,0 @@ -From foo@baz Tue Nov 17 14:33:46 PST 2015 -From: Francesco Ruggeri -Date: Thu, 5 Nov 2015 08:16:14 -0800 -Subject: packet: race condition in packet_bind - -From: Francesco Ruggeri - -[ Upstream commit 30f7ea1c2b5f5fb7462c5ae44fe2e40cb2d6a474 ] - -There is a race conditions between packet_notifier and packet_bind{_spkt}. - -It happens if packet_notifier(NETDEV_UNREGISTER) executes between the -time packet_bind{_spkt} takes a reference on the new netdevice and the -time packet_do_bind sets po->ifindex. -In this case the notification can be missed. -If this happens during a dev_change_net_namespace this can result in the -netdevice to be moved to the new namespace while the packet_sock in the -old namespace still holds a reference on it. When the netdevice is later -deleted in the new namespace the deletion hangs since the packet_sock -is not found in the new namespace' &net->packet.sklist. -It can be reproduced with the script below. - -This patch makes packet_do_bind check again for the presence of the -netdevice in the packet_sock's namespace after the synchronize_net -in unregister_prot_hook. -More in general it also uses the rcu lock for the duration of the bind -to stop dev_change_net_namespace/rollback_registered_many from -going past the synchronize_net following unlist_netdevice, so that -no NETDEV_UNREGISTER notifications can happen on the new netdevice -while the bind is executing. In order to do this some code from -packet_bind{_spkt} is consolidated into packet_do_dev. - -import socket, os, time, sys -proto=7 -realDev='em1' -vlanId=400 -if len(sys.argv) > 1: - vlanId=int(sys.argv[1]) -dev='vlan%d' % vlanId - -os.system('taskset -p 0x10 %d' % os.getpid()) - -s = socket.socket(socket.PF_PACKET, socket.SOCK_RAW, proto) -os.system('ip link add link %s name %s type vlan id %d' % - (realDev, dev, vlanId)) -os.system('ip netns add dummy') - -pid=os.fork() - -if pid == 0: - # dev should be moved while packet_do_bind is in synchronize net - os.system('taskset -p 0x20000 %d' % os.getpid()) - os.system('ip link set %s netns dummy' % dev) - os.system('ip netns exec dummy ip link del %s' % dev) - s.close() - sys.exit(0) - -time.sleep(.004) -try: - s.bind(('%s' % dev, proto+1)) -except: - print 'Could not bind socket' - s.close() - os.system('ip netns del dummy') - sys.exit(0) - -os.waitpid(pid, 0) -s.close() -os.system('ip netns del dummy') -sys.exit(0) - -Signed-off-by: Francesco Ruggeri -Signed-off-by: David S. Miller -Signed-off-by: Greg Kroah-Hartman ---- - net/packet/af_packet.c | 80 ++++++++++++++++++++++++++++++------------------- - 1 file changed, 49 insertions(+), 31 deletions(-) - ---- a/net/packet/af_packet.c -+++ b/net/packet/af_packet.c -@@ -2903,22 +2903,40 @@ static int packet_release(struct socket - * Attach a packet hook. - */ - --static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 proto) -+static int packet_do_bind(struct sock *sk, const char *name, int ifindex, -+ __be16 proto) - { - struct packet_sock *po = pkt_sk(sk); - struct net_device *dev_curr; - __be16 proto_curr; - bool need_rehook; -+ struct net_device *dev = NULL; -+ int ret = 0; -+ bool unlisted = false; - -- if (po->fanout) { -- if (dev) -- dev_put(dev); -- -+ if (po->fanout) - return -EINVAL; -- } - - lock_sock(sk); - spin_lock(&po->bind_lock); -+ rcu_read_lock(); -+ -+ if (name) { -+ dev = dev_get_by_name_rcu(sock_net(sk), name); -+ if (!dev) { -+ ret = -ENODEV; -+ goto out_unlock; -+ } -+ } else if (ifindex) { -+ dev = dev_get_by_index_rcu(sock_net(sk), ifindex); -+ if (!dev) { -+ ret = -ENODEV; -+ goto out_unlock; -+ } -+ } -+ -+ if (dev) -+ dev_hold(dev); - - proto_curr = po->prot_hook.type; - dev_curr = po->prot_hook.dev; -@@ -2926,14 +2944,29 @@ static int packet_do_bind(struct sock *s - need_rehook = proto_curr != proto || dev_curr != dev; - - if (need_rehook) { -- unregister_prot_hook(sk, true); -+ if (po->running) { -+ rcu_read_unlock(); -+ __unregister_prot_hook(sk, true); -+ rcu_read_lock(); -+ dev_curr = po->prot_hook.dev; -+ if (dev) -+ unlisted = !dev_get_by_index_rcu(sock_net(sk), -+ dev->ifindex); -+ } - - po->num = proto; - po->prot_hook.type = proto; -- po->prot_hook.dev = dev; - -- po->ifindex = dev ? dev->ifindex : 0; -- packet_cached_dev_assign(po, dev); -+ if (unlikely(unlisted)) { -+ dev_put(dev); -+ po->prot_hook.dev = NULL; -+ po->ifindex = -1; -+ packet_cached_dev_reset(po); -+ } else { -+ po->prot_hook.dev = dev; -+ po->ifindex = dev ? dev->ifindex : 0; -+ packet_cached_dev_assign(po, dev); -+ } - } - if (dev_curr) - dev_put(dev_curr); -@@ -2941,7 +2974,7 @@ static int packet_do_bind(struct sock *s - if (proto == 0 || !need_rehook) - goto out_unlock; - -- if (!dev || (dev->flags & IFF_UP)) { -+ if (!unlisted && (!dev || (dev->flags & IFF_UP))) { - register_prot_hook(sk); - } else { - sk->sk_err = ENETDOWN; -@@ -2950,9 +2983,10 @@ static int packet_do_bind(struct sock *s - } - - out_unlock: -+ rcu_read_unlock(); - spin_unlock(&po->bind_lock); - release_sock(sk); -- return 0; -+ return ret; - } - - /* -@@ -2964,8 +2998,6 @@ static int packet_bind_spkt(struct socke - { - struct sock *sk = sock->sk; - char name[15]; -- struct net_device *dev; -- int err = -ENODEV; - - /* - * Check legality -@@ -2975,19 +3007,13 @@ static int packet_bind_spkt(struct socke - return -EINVAL; - strlcpy(name, uaddr->sa_data, sizeof(name)); - -- dev = dev_get_by_name(sock_net(sk), name); -- if (dev) -- err = packet_do_bind(sk, dev, pkt_sk(sk)->num); -- return err; -+ return packet_do_bind(sk, name, 0, pkt_sk(sk)->num); - } - - static int packet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) - { - struct sockaddr_ll *sll = (struct sockaddr_ll *)uaddr; - struct sock *sk = sock->sk; -- struct net_device *dev = NULL; -- int err; -- - - /* - * Check legality -@@ -2998,16 +3024,8 @@ static int packet_bind(struct socket *so - if (sll->sll_family != AF_PACKET) - return -EINVAL; - -- if (sll->sll_ifindex) { -- err = -ENODEV; -- dev = dev_get_by_index(sock_net(sk), sll->sll_ifindex); -- if (dev == NULL) -- goto out; -- } -- err = packet_do_bind(sk, dev, sll->sll_protocol ? : pkt_sk(sk)->num); -- --out: -- return err; -+ return packet_do_bind(sk, NULL, sll->sll_ifindex, -+ sll->sll_protocol ? : pkt_sk(sk)->num); - } - - static struct proto packet_proto = { diff --git a/kernel/kernel/files/patches/mageia/stable-qmi_wwan-fix-entry-for-hp-lt4112-lte-hspa-gobi-4g-module.patch b/kernel/kernel/files/patches/mageia/stable-qmi_wwan-fix-entry-for-hp-lt4112-lte-hspa-gobi-4g-module.patch deleted file mode 100644 index 070c60b8..00000000 --- a/kernel/kernel/files/patches/mageia/stable-qmi_wwan-fix-entry-for-hp-lt4112-lte-hspa-gobi-4g-module.patch +++ /dev/null @@ -1,55 +0,0 @@ -From foo@baz Tue Nov 17 14:33:46 PST 2015 -From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= -Date: Sun, 1 Nov 2015 01:34:50 +0100 -Subject: qmi_wwan: fix entry for HP lt4112 LTE/HSPA+ Gobi 4G Module -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= - -[ Upstream commit 70910791731b5956171e1bfcad707766b8e18fee ] - -The lt4112 is a HP branded Huawei me906e modem. Like other Huawei -modems, it does not have a fixed interface to function mapping. -Instead it uses a Huawei specific scheme: functions are mapped by -subclass and protocol. - -However, the HP vendor ID is used for modems from many different -manufacturers using different schemes, so we cannot apply a generic -vendor rule like we do for the Huawei vendor ID. - -Replace the previous lt4112 entry pointing to an arbitrary interface -number with a device specific subclass + protocol match. - -Reported-and-tested-by: Muri Nicanor -Tested-by: Martin Hauke -Fixes: bb2bdeb83fb1 ("qmi_wwan: Add support for HP lt4112 LTE/HSPA+ Gobi 4G Modem") -Signed-off-by: Bjørn Mork -Signed-off-by: David S. Miller -Signed-off-by: Greg Kroah-Hartman ---- - drivers/net/usb/qmi_wwan.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - ---- a/drivers/net/usb/qmi_wwan.c -+++ b/drivers/net/usb/qmi_wwan.c -@@ -539,6 +539,10 @@ static const struct usb_device_id produc - USB_CDC_PROTO_NONE), - .driver_info = (unsigned long)&qmi_wwan_info, - }, -+ { /* HP lt4112 LTE/HSPA+ Gobi 4G Module (Huawei me906e) */ -+ USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0x581d, USB_CLASS_VENDOR_SPEC, 1, 7), -+ .driver_info = (unsigned long)&qmi_wwan_info, -+ }, - - /* 3. Combined interface devices matching on interface number */ - {QMI_FIXED_INTF(0x0408, 0xea42, 4)}, /* Yota / Megafon M100-1 */ -@@ -791,7 +795,6 @@ static const struct usb_device_id produc - {QMI_FIXED_INTF(0x413c, 0x81a9, 8)}, /* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card */ - {QMI_FIXED_INTF(0x413c, 0x81b1, 8)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card */ - {QMI_FIXED_INTF(0x03f0, 0x4e1d, 8)}, /* HP lt4111 LTE/EV-DO/HSPA+ Gobi 4G Module */ -- {QMI_FIXED_INTF(0x03f0, 0x581d, 4)}, /* HP lt4112 LTE/HSPA+ Gobi 4G Module (Huawei me906e) */ - - /* 4. Gobi 1000 devices */ - {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ diff --git a/kernel/kernel/files/patches/mageia/stable-sfc-push-partner-queue-for-skb-xmit_more.patch b/kernel/kernel/files/patches/mageia/stable-sfc-push-partner-queue-for-skb-xmit_more.patch deleted file mode 100644 index f75db22c..00000000 --- a/kernel/kernel/files/patches/mageia/stable-sfc-push-partner-queue-for-skb-xmit_more.patch +++ /dev/null @@ -1,137 +0,0 @@ -From foo@baz Tue Nov 17 14:33:46 PST 2015 -From: Martin Habets -Date: Mon, 2 Nov 2015 12:51:31 +0000 -Subject: sfc: push partner queue for skb->xmit_more - -From: Martin Habets - -[ Upstream commit b2663a4f30e85ec606b806f5135413e6d5c78d1e ] - -When the IP stack passes SKBs the sfc driver puts them in 2 different TX -queues (called partners), one for checksummed and one for not checksummed. -If the SKB has xmit_more set the driver will delay pushing the work to the -NIC. - -When later it does decide to push the buffers this patch ensures it also -pushes the partner queue, if that also has any delayed work. Before this -fix the work in the partner queue would be left for a long time and cause -a netdev watchdog. - -Fixes: 70b33fb ("sfc: add support for skb->xmit_more") -Reported-by: Jianlin Shi -Signed-off-by: Martin Habets -Signed-off-by: David S. Miller -Signed-off-by: Greg Kroah-Hartman ---- - drivers/net/ethernet/sfc/ef10.c | 4 +++- - drivers/net/ethernet/sfc/farch.c | 4 +++- - drivers/net/ethernet/sfc/net_driver.h | 2 ++ - drivers/net/ethernet/sfc/tx.c | 30 ++++++++++++++++++++++++++++-- - 4 files changed, 36 insertions(+), 4 deletions(-) - ---- a/drivers/net/ethernet/sfc/ef10.c -+++ b/drivers/net/ethernet/sfc/ef10.c -@@ -1849,7 +1849,9 @@ static void efx_ef10_tx_write(struct efx - unsigned int write_ptr; - efx_qword_t *txd; - -- BUG_ON(tx_queue->write_count == tx_queue->insert_count); -+ tx_queue->xmit_more_available = false; -+ if (unlikely(tx_queue->write_count == tx_queue->insert_count)) -+ return; - - do { - write_ptr = tx_queue->write_count & tx_queue->ptr_mask; ---- a/drivers/net/ethernet/sfc/farch.c -+++ b/drivers/net/ethernet/sfc/farch.c -@@ -321,7 +321,9 @@ void efx_farch_tx_write(struct efx_tx_qu - unsigned write_ptr; - unsigned old_write_count = tx_queue->write_count; - -- BUG_ON(tx_queue->write_count == tx_queue->insert_count); -+ tx_queue->xmit_more_available = false; -+ if (unlikely(tx_queue->write_count == tx_queue->insert_count)) -+ return; - - do { - write_ptr = tx_queue->write_count & tx_queue->ptr_mask; ---- a/drivers/net/ethernet/sfc/net_driver.h -+++ b/drivers/net/ethernet/sfc/net_driver.h -@@ -219,6 +219,7 @@ struct efx_tx_buffer { - * @tso_packets: Number of packets via the TSO xmit path - * @pushes: Number of times the TX push feature has been used - * @pio_packets: Number of times the TX PIO feature has been used -+ * @xmit_more_available: Are any packets waiting to be pushed to the NIC - * @empty_read_count: If the completion path has seen the queue as empty - * and the transmission path has not yet checked this, the value of - * @read_count bitwise-added to %EFX_EMPTY_COUNT_VALID; otherwise 0. -@@ -253,6 +254,7 @@ struct efx_tx_queue { - unsigned int tso_packets; - unsigned int pushes; - unsigned int pio_packets; -+ bool xmit_more_available; - /* Statistics to supplement MAC stats */ - unsigned long tx_packets; - ---- a/drivers/net/ethernet/sfc/tx.c -+++ b/drivers/net/ethernet/sfc/tx.c -@@ -431,8 +431,20 @@ finish_packet: - efx_tx_maybe_stop_queue(tx_queue); - - /* Pass off to hardware */ -- if (!skb->xmit_more || netif_xmit_stopped(tx_queue->core_txq)) -+ if (!skb->xmit_more || netif_xmit_stopped(tx_queue->core_txq)) { -+ struct efx_tx_queue *txq2 = efx_tx_queue_partner(tx_queue); -+ -+ /* There could be packets left on the partner queue if those -+ * SKBs had skb->xmit_more set. If we do not push those they -+ * could be left for a long time and cause a netdev watchdog. -+ */ -+ if (txq2->xmit_more_available) -+ efx_nic_push_buffers(txq2); -+ - efx_nic_push_buffers(tx_queue); -+ } else { -+ tx_queue->xmit_more_available = skb->xmit_more; -+ } - - tx_queue->tx_packets++; - -@@ -722,6 +734,7 @@ void efx_init_tx_queue(struct efx_tx_que - tx_queue->read_count = 0; - tx_queue->old_read_count = 0; - tx_queue->empty_read_count = 0 | EFX_EMPTY_COUNT_VALID; -+ tx_queue->xmit_more_available = false; - - /* Set up TX descriptor ring */ - efx_nic_init_tx(tx_queue); -@@ -747,6 +760,7 @@ void efx_fini_tx_queue(struct efx_tx_que - - ++tx_queue->read_count; - } -+ tx_queue->xmit_more_available = false; - netdev_tx_reset_queue(tx_queue->core_txq); - } - -@@ -1302,8 +1316,20 @@ static int efx_enqueue_skb_tso(struct ef - efx_tx_maybe_stop_queue(tx_queue); - - /* Pass off to hardware */ -- if (!skb->xmit_more || netif_xmit_stopped(tx_queue->core_txq)) -+ if (!skb->xmit_more || netif_xmit_stopped(tx_queue->core_txq)) { -+ struct efx_tx_queue *txq2 = efx_tx_queue_partner(tx_queue); -+ -+ /* There could be packets left on the partner queue if those -+ * SKBs had skb->xmit_more set. If we do not push those they -+ * could be left for a long time and cause a netdev watchdog. -+ */ -+ if (txq2->xmit_more_available) -+ efx_nic_push_buffers(txq2); -+ - efx_nic_push_buffers(tx_queue); -+ } else { -+ tx_queue->xmit_more_available = skb->xmit_more; -+ } - - tx_queue->tso_bursts++; - return NETDEV_TX_OK; diff --git a/kernel/kernel/files/patches/mageia/stable-sit-fix-sit0-percpu-double-allocations.patch b/kernel/kernel/files/patches/mageia/stable-sit-fix-sit0-percpu-double-allocations.patch deleted file mode 100644 index d523ffa4..00000000 --- a/kernel/kernel/files/patches/mageia/stable-sit-fix-sit0-percpu-double-allocations.patch +++ /dev/null @@ -1,96 +0,0 @@ -From foo@baz Tue Nov 17 14:33:46 PST 2015 -From: Eric Dumazet -Date: Mon, 2 Nov 2015 17:08:19 -0800 -Subject: sit: fix sit0 percpu double allocations - -From: Eric Dumazet - -[ Upstream commit 4ece9009774596ee3df0acba65a324b7ea79387c ] - -sit0 device allocates its percpu storage twice : -- One time in ipip6_tunnel_init() -- One time in ipip6_fb_tunnel_init() - -Thus we leak 48 bytes per possible cpu per network namespace dismantle. - -ipip6_fb_tunnel_init() can be much simpler and does not -return an error, and should be called after register_netdev() - -Note that ipip6_tunnel_clone_6rd() also needs to be called -after register_netdev() (calling ipip6_tunnel_init()) - -Fixes: ebe084aafb7e ("sit: Use ipip6_tunnel_init as the ndo_init function.") -Signed-off-by: Eric Dumazet -Reported-by: Dmitry Vyukov -Cc: Steffen Klassert -Signed-off-by: David S. Miller -Signed-off-by: Greg Kroah-Hartman ---- - net/ipv6/sit.c | 26 ++++---------------------- - 1 file changed, 4 insertions(+), 22 deletions(-) - ---- a/net/ipv6/sit.c -+++ b/net/ipv6/sit.c -@@ -1394,34 +1394,20 @@ static int ipip6_tunnel_init(struct net_ - return 0; - } - --static int __net_init ipip6_fb_tunnel_init(struct net_device *dev) -+static void __net_init ipip6_fb_tunnel_init(struct net_device *dev) - { - struct ip_tunnel *tunnel = netdev_priv(dev); - struct iphdr *iph = &tunnel->parms.iph; - struct net *net = dev_net(dev); - struct sit_net *sitn = net_generic(net, sit_net_id); - -- tunnel->dev = dev; -- tunnel->net = dev_net(dev); -- - iph->version = 4; - iph->protocol = IPPROTO_IPV6; - iph->ihl = 5; - iph->ttl = 64; - -- dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); -- if (!dev->tstats) -- return -ENOMEM; -- -- tunnel->dst_cache = alloc_percpu(struct ip_tunnel_dst); -- if (!tunnel->dst_cache) { -- free_percpu(dev->tstats); -- return -ENOMEM; -- } -- - dev_hold(dev); - rcu_assign_pointer(sitn->tunnels_wc[0], tunnel); -- return 0; - } - - static int ipip6_validate(struct nlattr *tb[], struct nlattr *data[]) -@@ -1831,23 +1817,19 @@ static int __net_init sit_init_net(struc - */ - sitn->fb_tunnel_dev->features |= NETIF_F_NETNS_LOCAL; - -- err = ipip6_fb_tunnel_init(sitn->fb_tunnel_dev); -- if (err) -- goto err_dev_free; -- -- ipip6_tunnel_clone_6rd(sitn->fb_tunnel_dev, sitn); - err = register_netdev(sitn->fb_tunnel_dev); - if (err) - goto err_reg_dev; - -+ ipip6_tunnel_clone_6rd(sitn->fb_tunnel_dev, sitn); -+ ipip6_fb_tunnel_init(sitn->fb_tunnel_dev); -+ - t = netdev_priv(sitn->fb_tunnel_dev); - - strcpy(t->parms.name, sitn->fb_tunnel_dev->name); - return 0; - - err_reg_dev: -- dev_put(sitn->fb_tunnel_dev); --err_dev_free: - ipip6_dev_free(sitn->fb_tunnel_dev); - err_alloc_dev: - return err; diff --git a/kernel/kernel/files/patches/mageia/stable-stmmac-correctly-report-ptp-capabilities.patch b/kernel/kernel/files/patches/mageia/stable-stmmac-correctly-report-ptp-capabilities.patch deleted file mode 100644 index 849d0292..00000000 --- a/kernel/kernel/files/patches/mageia/stable-stmmac-correctly-report-ptp-capabilities.patch +++ /dev/null @@ -1,39 +0,0 @@ -From foo@baz Tue Nov 17 14:33:46 PST 2015 -From: Phil Reid -Date: Fri, 30 Oct 2015 16:43:55 +0800 -Subject: stmmac: Correctly report PTP capabilities. - -From: Phil Reid - -[ Upstream commit e6dbe1eb2db0d7a14991c06278dd3030c45fb825 ] - -priv->hwts_*_en indicate if timestamping is enabled/disabled at run -time. But priv->dma_cap.time_stamp and priv->dma_cap.atime_stamp -indicates HW is support for PTPv1/PTPv2. - -Signed-off-by: Phil Reid -Acked-by: Richard Cochran -Signed-off-by: David S. Miller -Signed-off-by: Greg Kroah-Hartman ---- - drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c -@@ -721,10 +721,13 @@ static int stmmac_get_ts_info(struct net - { - struct stmmac_priv *priv = netdev_priv(dev); - -- if ((priv->hwts_tx_en) && (priv->hwts_rx_en)) { -+ if ((priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp)) { - -- info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE | -+ info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE | -+ SOF_TIMESTAMPING_TX_HARDWARE | -+ SOF_TIMESTAMPING_RX_SOFTWARE | - SOF_TIMESTAMPING_RX_HARDWARE | -+ SOF_TIMESTAMPING_SOFTWARE | - SOF_TIMESTAMPING_RAW_HARDWARE; - - if (priv->ptp_clock) diff --git a/kernel/kernel/files/patches/mageia/stable-tipc-linearize-arriving-name_distr-and-link_proto-buffers.patch b/kernel/kernel/files/patches/mageia/stable-tipc-linearize-arriving-name_distr-and-link_proto-buffers.patch deleted file mode 100644 index 1359a59c..00000000 --- a/kernel/kernel/files/patches/mageia/stable-tipc-linearize-arriving-name_distr-and-link_proto-buffers.patch +++ /dev/null @@ -1,51 +0,0 @@ -From foo@baz Tue Nov 17 14:33:46 PST 2015 -From: Jon Paul Maloy -Date: Wed, 28 Oct 2015 13:09:53 -0400 -Subject: tipc: linearize arriving NAME_DISTR and LINK_PROTO buffers - -From: Jon Paul Maloy - -[ Upstream commit 5cbb28a4bf65c7e4daa6c25b651fed8eb888c620 ] - -Testing of the new UDP bearer has revealed that reception of -NAME_DISTRIBUTOR, LINK_PROTOCOL/RESET and LINK_PROTOCOL/ACTIVATE -message buffers is not prepared for the case that those may be -non-linear. - -We now linearize all such buffers before they are delivered up to the -generic reception layer. - -In order for the commit to apply cleanly to 'net' and 'stable', we do -the change in the function tipc_udp_recv() for now. Later, we will post -a commit to 'net-next' moving the linearization to generic code, in -tipc_named_rcv() and tipc_link_proto_rcv(). - -Fixes: commit d0f91938bede ("tipc: add ip/udp media type") -Signed-off-by: Jon Maloy -Signed-off-by: David S. Miller -Signed-off-by: Greg Kroah-Hartman ---- - net/tipc/udp_media.c | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/net/tipc/udp_media.c -+++ b/net/tipc/udp_media.c -@@ -48,6 +48,7 @@ - #include - #include "core.h" - #include "bearer.h" -+#include "msg.h" - - /* IANA assigned UDP port */ - #define UDP_PORT_DEFAULT 6118 -@@ -222,6 +223,10 @@ static int tipc_udp_recv(struct sock *sk - { - struct udp_bearer *ub; - struct tipc_bearer *b; -+ int usr = msg_user(buf_msg(skb)); -+ -+ if ((usr == LINK_PROTOCOL) || (usr == NAME_DISTRIBUTOR)) -+ skb_linearize(skb); - - ub = rcu_dereference_sk_user_data(sk); - if (!ub) { diff --git a/kernel/kernel/files/patches/mageia/stable-tun_dst-fix-potential-null-dereference.patch b/kernel/kernel/files/patches/mageia/stable-tun_dst-fix-potential-null-dereference.patch deleted file mode 100644 index 8b4ebd84..00000000 --- a/kernel/kernel/files/patches/mageia/stable-tun_dst-fix-potential-null-dereference.patch +++ /dev/null @@ -1,41 +0,0 @@ -From foo@baz Tue Nov 17 14:33:46 PST 2015 -From: Tobias Klauser -Date: Wed, 4 Nov 2015 13:49:49 +0100 -Subject: tun_dst: Fix potential NULL dereference - -From: Tobias Klauser - -[ Upstream commit f63ce5b6fa5e9a0faf7a0e1ef2993a502878c78a ] - -In tun_dst_unclone() the return value of skb_metadata_dst() is checked -for being NULL after it is dereferenced. Fix this by moving the -dereference after the NULL check. - -Found by the Coverity scanner (CID 1338068). - -Fixes: fc4099f17240 ("openvswitch: Fix egress tunnel info.") -Cc: Pravin B Shelar -Signed-off-by: Tobias Klauser -Signed-off-by: David S. Miller -Signed-off-by: Greg Kroah-Hartman ---- - include/net/dst_metadata.h | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/include/net/dst_metadata.h -+++ b/include/net/dst_metadata.h -@@ -63,12 +63,13 @@ static inline struct metadata_dst *tun_r - static inline struct metadata_dst *tun_dst_unclone(struct sk_buff *skb) - { - struct metadata_dst *md_dst = skb_metadata_dst(skb); -- int md_size = md_dst->u.tun_info.options_len; -+ int md_size; - struct metadata_dst *new_md; - - if (!md_dst) - return ERR_PTR(-EINVAL); - -+ md_size = md_dst->u.tun_info.options_len; - new_md = metadata_dst_alloc(md_size, GFP_ATOMIC); - if (!new_md) - return ERR_PTR(-ENOMEM); diff --git a/kernel/kernel/files/patches/mageia/stable-usb-qcserial-add-sierra-wireless-mc74xx-em74xx.patch b/kernel/kernel/files/patches/mageia/stable-usb-qcserial-add-sierra-wireless-mc74xx-em74xx.patch deleted file mode 100644 index 510a2551..00000000 --- a/kernel/kernel/files/patches/mageia/stable-usb-qcserial-add-sierra-wireless-mc74xx-em74xx.patch +++ /dev/null @@ -1,34 +0,0 @@ -From f504ab1888026d15b5be8f9c262bf4ae9cacd177 Mon Sep 17 00:00:00 2001 -From: Bjørn Mork -Date: Thu, 22 Oct 2015 14:24:24 +0200 -Subject: USB: qcserial: add Sierra Wireless MC74xx/EM74xx -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -From: Bjørn Mork - -commit f504ab1888026d15b5be8f9c262bf4ae9cacd177 upstream. - -New device IDs shamelessly lifted from the vendor driver. - -Signed-off-by: Bjørn Mork -Acked-by: Johan Hovold -Signed-off-by: Greg Kroah-Hartman -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/usb/serial/qcserial.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/usb/serial/qcserial.c -+++ b/drivers/usb/serial/qcserial.c -@@ -153,6 +153,8 @@ static const struct usb_device_id id_tab - {DEVICE_SWI(0x1199, 0x9056)}, /* Sierra Wireless Modem */ - {DEVICE_SWI(0x1199, 0x9060)}, /* Sierra Wireless Modem */ - {DEVICE_SWI(0x1199, 0x9061)}, /* Sierra Wireless Modem */ -+ {DEVICE_SWI(0x1199, 0x9070)}, /* Sierra Wireless MC74xx/EM74xx */ -+ {DEVICE_SWI(0x1199, 0x9071)}, /* Sierra Wireless MC74xx/EM74xx */ - {DEVICE_SWI(0x413c, 0x81a2)}, /* Dell Wireless 5806 Gobi(TM) 4G LTE Mobile Broadband Card */ - {DEVICE_SWI(0x413c, 0x81a3)}, /* Dell Wireless 5570 HSPA+ (42Mbps) Mobile Broadband Card */ - {DEVICE_SWI(0x413c, 0x81a4)}, /* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card */ diff --git a/kernel/kernel/files/patches/mageia/x86-KVM-x86-work-around-infinite-loop-in-microcode-when-AC-is-delivered.patch b/kernel/kernel/files/patches/mageia/x86-KVM-x86-work-around-infinite-loop-in-microcode-when-AC-is-delivered.patch deleted file mode 100644 index 3476a4bf..00000000 --- a/kernel/kernel/files/patches/mageia/x86-KVM-x86-work-around-infinite-loop-in-microcode-when-AC-is-delivered.patch +++ /dev/null @@ -1,93 +0,0 @@ -From: Paolo Bonzini -Subject: [PATCH 1/3] KVM: x86: work around infinite loop in microcode when #AC is delivered -Date: Tue, 10 Nov 2015 13:22:52 +0100 - -From: Eric Northup - -It was found that a guest can DoS a host by triggering an infinite -stream of "alignment check" (#AC) exceptions. This causes the -microcode to enter an infinite loop where the core never receives -another interrupt. The host kernel panics pretty quickly due to the -effects (CVE-2015-5307). - -Signed-off-by: Eric Northup -Cc: stable@vger.kernel.org -Signed-off-by: Paolo Bonzini ---- - arch/x86/include/uapi/asm/svm.h | 1 + - arch/x86/kvm/svm.c | 8 ++++++++ - arch/x86/kvm/vmx.c | 5 ++++- - 3 files changed, 13 insertions(+), 1 deletion(-) - -diff --git a/arch/x86/include/uapi/asm/svm.h b/arch/x86/include/uapi/asm/svm.h -index b5d7640abc5d..8a4add8e4639 100644 ---- a/arch/x86/include/uapi/asm/svm.h -+++ b/arch/x86/include/uapi/asm/svm.h -@@ -100,6 +100,7 @@ - { SVM_EXIT_EXCP_BASE + UD_VECTOR, "UD excp" }, \ - { SVM_EXIT_EXCP_BASE + PF_VECTOR, "PF excp" }, \ - { SVM_EXIT_EXCP_BASE + NM_VECTOR, "NM excp" }, \ -+ { SVM_EXIT_EXCP_BASE + AC_VECTOR, "AC excp" }, \ - { SVM_EXIT_EXCP_BASE + MC_VECTOR, "MC excp" }, \ - { SVM_EXIT_INTR, "interrupt" }, \ - { SVM_EXIT_NMI, "nmi" }, \ -diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c -index f2ba91990b4e..183926483c3a 100644 ---- a/arch/x86/kvm/svm.c -+++ b/arch/x86/kvm/svm.c -@@ -1019,6 +1019,7 @@ static void init_vmcb(struct vcpu_svm *svm) - set_exception_intercept(svm, PF_VECTOR); - set_exception_intercept(svm, UD_VECTOR); - set_exception_intercept(svm, MC_VECTOR); -+ set_exception_intercept(svm, AC_VECTOR); - - set_intercept(svm, INTERCEPT_INTR); - set_intercept(svm, INTERCEPT_NMI); -@@ -1707,6 +1708,12 @@ static int ud_interception(struct vcpu_svm *svm) - return 1; - } - -+static int ac_interception(struct vcpu_svm *svm) -+{ -+ kvm_queue_exception_e(&svm->vcpu, AC_VECTOR, 0); -+ return 1; -+} -+ - static void svm_fpu_activate(struct kvm_vcpu *vcpu) - { - struct vcpu_svm *svm = to_svm(vcpu); -@@ -3270,6 +3277,7 @@ static int (*const svm_exit_handlers[])(struct vcpu_svm *svm) = { - [SVM_EXIT_EXCP_BASE + PF_VECTOR] = pf_interception, - [SVM_EXIT_EXCP_BASE + NM_VECTOR] = nm_interception, - [SVM_EXIT_EXCP_BASE + MC_VECTOR] = mc_interception, -+ [SVM_EXIT_EXCP_BASE + AC_VECTOR] = ac_interception, - [SVM_EXIT_INTR] = intr_interception, - [SVM_EXIT_NMI] = nmi_interception, - [SVM_EXIT_SMI] = nop_on_interception, -diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c -index b765b036a048..89aaedd2a91d 100644 ---- a/arch/x86/kvm/vmx.c -+++ b/arch/x86/kvm/vmx.c -@@ -1639,7 +1639,7 @@ static void update_exception_bitmap(struct kvm_vcpu *vcpu) - u32 eb; - - eb = (1u << PF_VECTOR) | (1u << UD_VECTOR) | (1u << MC_VECTOR) | -- (1u << NM_VECTOR) | (1u << DB_VECTOR); -+ (1u << NM_VECTOR) | (1u << DB_VECTOR) | (1u << AC_VECTOR); - if ((vcpu->guest_debug & - (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP)) == - (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP)) -@@ -5261,6 +5261,9 @@ static int handle_exception(struct kvm_vcpu *vcpu) - return handle_rmode_exception(vcpu, ex_no, error_code); - - switch (ex_no) { -+ case AC_VECTOR: -+ kvm_queue_exception_e(vcpu, AC_VECTOR, error_code); -+ return 1; - case DB_VECTOR: - dr6 = vmcs_readl(EXIT_QUALIFICATION); - if (!(vcpu->guest_debug & --- -1.8.3.1 - - diff --git a/kernel/kernel/pspec.xml b/kernel/kernel/pspec.xml index 92e6eb81..93227a6f 100644 --- a/kernel/kernel/pspec.xml +++ b/kernel/kernel/pspec.xml @@ -28,39 +28,20 @@ - - + patches/linux/patch-4.3.2.xz + - patches/mageia/stable-arm-8449-1-fix-bug-in-vdsomunge-swab32-macro.patch - patches/mageia/stable-usb-qcserial-add-sierra-wireless-mc74xx-em74xx.patch - patches/mageia/stable-tipc-linearize-arriving-name_distr-and-link_proto-buffers.patch - patches/mageia/stable-net-bcmgenet-software-reset-ephy-after-power-on.patch - patches/mageia/stable-ipv4-fix-to-not-remove-local-route-on-link-down.patch - patches/mageia/stable-ipv4-update-rtnh_f_linkdown-flag-on-up-event.patch - patches/mageia/stable-stmmac-correctly-report-ptp-capabilities.patch - patches/mageia/stable-ipmr-fix-possible-race-resulting-from-improper-usage-of-ip_inc_stats_bh-in-preemptible-context.patch - patches/mageia/stable-qmi_wwan-fix-entry-for-hp-lt4112-lte-hspa-gobi-4g-module.patch - patches/mageia/stable-sit-fix-sit0-percpu-double-allocations.patch - patches/mageia/stable-sfc-push-partner-queue-for-skb-xmit_more.patch - patches/mageia/stable-net-avoid-null-deref-in-inet_ctl_sock_destroy.patch - patches/mageia/stable-ipv6-clean-up-dev_snmp6-proc-entry-when-we-fail-to-initialize-inet6_dev.patch - patches/mageia/stable-ipv4-disable-bh-when-changing-ip-local-port-range.patch - patches/mageia/stable-net-fix-prefsrc-lookups.patch - patches/mageia/stable-tun_dst-fix-potential-null-dereference.patch - patches/mageia/stable-packet-race-condition-in-packet_bind.patch - patches/mageia/stable-bonding-fix-panic-on-non-arphrd_ether-enslave-failure.patch - patches/mageia/stable-net-fix-a-race-in-dst_release.patch patches/mageia/x86-pci-toshiba-equium-a60-assign-busses.patch patches/mageia/x86-boot-video-80x25-if-break.patch patches/mageia/x86-default_poweroff_up_machines.patch patches/mageia/x86-increase-default-minimum-vmalloc-area-by-64MB-to-192MB.patch patches/mageia/Revert-cpufreq-pcc-Enable-autoload-of-pcc-cpufreq-fo.patch - patches/mageia/x86-KVM-x86-work-around-infinite-loop-in-microcode-when-AC-is-delivered.patch patches/mageia/x86-KVM-svm-unconditionally-intercept-DB.patch patches/mageia/Revert-x86-efi-Request-desired-alignment-via-the-PE-.patch patches/mageia/Revert-x86-mm-mtrr-Remove-kernel-internal-MTRR-inter.patch patches/mageia/base-cacheinfo-silence-DT-warnings.patch + patches/mageia/certs-add-.gitignore-to-stop-git-nagging-about-x509_.patch patches/mageia/pci-add-ALI-M5229-ide-compatibility-mode-quirk.patch patches/mageia/pci-quirks-drop-devinit-exit.patch patches/mageia/acpi-CLEVO-M360S-disable_acpi_irq.patch @@ -101,6 +82,8 @@ patches/mageia/gpu-drm-mach64-linux-3.14-buildfix.patch patches/mageia/gpu-drm-mach64-3.17-buildfix.patch patches/mageia/gpu-drm-mach64-3.18-buildfix.patch + patches/mageia/gpu-drm-Fix-an-unwanted-master-inheritance-v2.patch + patches/mageia/gpu-drm-i915-Fix-RPS-pointer-passed-from-wait_ioctl-to-i915_wait_request.patch patches/mageia/input-i8042-quirks-for-Fujitsu-Lifebook-A544-and-Lif.patch patches/mageia/net-sis190-fix-list-usage.patch patches/mageia/net-netfilter-IFWLOG.patch @@ -117,6 +100,7 @@ patches/mageia/net-netfilter-ipset-Fix-hash-type-expire-release-empty-hash-bucket-block.patch patches/mageia/net-netfilter-Fix-removal-of-GRE-expectation-entries-created-by-PPTP.patch patches/mageia/net-wireless-rtlwifi-rtl8821ae-Fix-lockups-on-boot.patch + patches/mageia/net_43.mbox.patch patches/mageia/platform-x86-add-shuttle-wmi-driver.patch patches/mageia/platform-x86-shuttle-wmi-drop-devinit-exit.patch patches/mageia/platform-x86-shuttle-wmi-4.2-buildfix.patch @@ -209,7 +193,18 @@ - + + + 2015-12-12 + 4.3.2 + Version bump to 4.3.2 https://www.kernel.org/pub/linux/kernel/v4.x/ChangeLog-4.3.2 + security + + systemRestart + + Ertuğrul Erata + ertugrulerata@gmail.com + 2015-12-01 4.3.0