From 159c6ce823dd76fd64d4d8fe4271e18ac238c542 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 20 Feb 2017 17:14:52 +0100 Subject: [PATCH] 3.18 patches --- ...b-audio-add-quirk-for-syntek-stk1160.patch | 48 ++++ ...android-binder-add-strong-ref-checks.patch | 107 +++++++ ...setting-handle-in-flat-binder-struct.patch | 52 ++++ ...rm-8584-1-floppy-avoid-gcc-6-warning.patch | 43 +++ ...r-handling-in-exynos_drm_subdrv_open.patch | 46 +++ ...ev-color-map-copying-bounds-checking.patch | 82 ++++++ ...-potential-infoleak-in-older-kernels.patch | 67 +++++ ...aten-cs962-to-list-of-quirky-devices.patch | 41 +++ ...-lookup-for-sr-iov-virtual-functions.patch | 82 ++++++ ...wi6_proto-value-in-ip6gre_xmit_other.patch | 42 +++ ...c-and-a-deadlock-with-ipmr_get_route.patch | 161 +++++++++++ ...4-disable-bh-in-set_ping_group_range.patch | 39 +++ ...tly-add-local-routes-when-lo-goes-up.patch | 58 ++++ ...-tcp-add-a-missing-tcp_v6_restore_cb.patch | 20 +- ...cp-restore-ip6cb-for-pktoptions-skbs.patch | 98 +++++++ ...list-refcnt-propagation-to-fix-panic.patch | 272 ++++++++++++++++++ ...ve-rcu-locking-in-pktgen_change_name.patch | 92 ++++++ .../net-sctp-forbid-negative-length.patch | 80 ++++++ ...ter-direct-reclaim-from-netlink_dump.patch | 76 +++++ ...release-while-unregistering-a-netdev.patch | 37 +++ ...it-tso-and-csum-to-supported-devices.patch | 97 +++++++ ...nexport-children-before-chip-removal.patch | 83 ++++++ ...e-chunk-len-before-actually-using-it.patch | 59 ++++ ...elinux-fix-off-by-one-in-setprocattr.patch | 64 +++++ queue-3.18/series | 30 ++ ...smc91x-avoid-self-comparison-warning.patch | 43 +++ .../tcp-fix-a-compile-error-in-dbgundo.patch | 36 +++ ...fix-overflow-in-__tcp_retransmit_skb.patch | 39 +++ ...-checksum-calculation-on-mtu-probing.patch | 52 ++++ .../tty-vt-fix-bogus-division-in-csi_j.patch | 39 +++ ...are-detected-in-a-free-peb-ec-header.patch | 40 +++ ...the-lock-initialization-to-core-file.patch | 139 +++++++++ 32 files changed, 2255 insertions(+), 9 deletions(-) create mode 100644 queue-3.18/alsa-usb-audio-add-quirk-for-syntek-stk1160.patch create mode 100644 queue-3.18/android-binder-add-strong-ref-checks.patch create mode 100644 queue-3.18/android-binder-clear-binder-and-cookie-when-setting-handle-in-flat-binder-struct.patch create mode 100644 queue-3.18/arm-8584-1-floppy-avoid-gcc-6-warning.patch create mode 100644 queue-3.18/drm-exynos-fix-error-handling-in-exynos_drm_subdrv_open.patch create mode 100644 queue-3.18/fbdev-color-map-copying-bounds-checking.patch create mode 100644 queue-3.18/fix-potential-infoleak-in-older-kernels.patch create mode 100644 queue-3.18/hid-usbhid-add-aten-cs962-to-list-of-quirky-devices.patch create mode 100644 queue-3.18/iommu-vt-d-fix-iommu-lookup-for-sr-iov-virtual-functions.patch create mode 100644 queue-3.18/ip6_gre-fix-flowi6_proto-value-in-ip6gre_xmit_other.patch create mode 100644 queue-3.18/ipmr-ip6mr-fix-scheduling-while-atomic-and-a-deadlock-with-ipmr_get_route.patch create mode 100644 queue-3.18/ipv4-disable-bh-in-set_ping_group_range.patch create mode 100644 queue-3.18/ipv6-correctly-add-local-routes-when-lo-goes-up.patch create mode 100644 queue-3.18/ipv6-tcp-restore-ip6cb-for-pktoptions-skbs.patch create mode 100644 queue-3.18/net-add-netdev-all_adj_list-refcnt-propagation-to-fix-panic.patch create mode 100644 queue-3.18/net-pktgen-remove-rcu-locking-in-pktgen_change_name.patch create mode 100644 queue-3.18/net-sctp-forbid-negative-length.patch create mode 100644 queue-3.18/netlink-do-not-enter-direct-reclaim-from-netlink_dump.patch create mode 100644 queue-3.18/packet-call-fanout_release-while-unregistering-a-netdev.patch create mode 100644 queue-3.18/packet-on-direct_xmit-limit-tso-and-csum-to-supported-devices.patch create mode 100644 queue-3.18/pwm-unexport-children-before-chip-removal.patch create mode 100644 queue-3.18/sctp-validate-chunk-len-before-actually-using-it.patch create mode 100644 queue-3.18/selinux-fix-off-by-one-in-setprocattr.patch create mode 100644 queue-3.18/smc91x-avoid-self-comparison-warning.patch create mode 100644 queue-3.18/tcp-fix-a-compile-error-in-dbgundo.patch create mode 100644 queue-3.18/tcp-fix-overflow-in-__tcp_retransmit_skb.patch create mode 100644 queue-3.18/tcp-fix-wrong-checksum-calculation-on-mtu-probing.patch create mode 100644 queue-3.18/tty-vt-fix-bogus-division-in-csi_j.patch create mode 100644 queue-3.18/ubi-fastmap-scrub-peb-when-bitflips-are-detected-in-a-free-peb-ec-header.patch create mode 100644 queue-3.18/usb-chipidea-move-the-lock-initialization-to-core-file.patch diff --git a/queue-3.18/alsa-usb-audio-add-quirk-for-syntek-stk1160.patch b/queue-3.18/alsa-usb-audio-add-quirk-for-syntek-stk1160.patch new file mode 100644 index 00000000000..23699a2b97d --- /dev/null +++ b/queue-3.18/alsa-usb-audio-add-quirk-for-syntek-stk1160.patch @@ -0,0 +1,48 @@ +From bdc3478f90cd4d2928197f36629d5cf93b64dbe9 Mon Sep 17 00:00:00 2001 +From: Marcel Hasler +Date: Thu, 27 Oct 2016 00:42:27 +0200 +Subject: ALSA: usb-audio: Add quirk for Syntek STK1160 + +From: Marcel Hasler + +commit bdc3478f90cd4d2928197f36629d5cf93b64dbe9 upstream. + +The stk1160 chip needs QUIRK_AUDIO_ALIGN_TRANSFER. This patch resolves +the issue reported on the mailing list +(http://marc.info/?l=linux-sound&m=139223599126215&w=2) and also fixes +bug 180071 (https://bugzilla.kernel.org/show_bug.cgi?id=180071). + +Signed-off-by: Marcel Hasler +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/usb/quirks-table.h | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +--- a/sound/usb/quirks-table.h ++++ b/sound/usb/quirks-table.h +@@ -2959,6 +2959,23 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge + } + }, + ++/* Syntek STK1160 */ ++{ ++ .match_flags = USB_DEVICE_ID_MATCH_DEVICE | ++ USB_DEVICE_ID_MATCH_INT_CLASS | ++ USB_DEVICE_ID_MATCH_INT_SUBCLASS, ++ .idVendor = 0x05e1, ++ .idProduct = 0x0408, ++ .bInterfaceClass = USB_CLASS_AUDIO, ++ .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, ++ .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { ++ .vendor_name = "Syntek", ++ .product_name = "STK1160", ++ .ifnum = QUIRK_ANY_INTERFACE, ++ .type = QUIRK_AUDIO_ALIGN_TRANSFER ++ } ++}, ++ + /* Digidesign Mbox */ + { + /* Thanks to Clemens Ladisch */ diff --git a/queue-3.18/android-binder-add-strong-ref-checks.patch b/queue-3.18/android-binder-add-strong-ref-checks.patch new file mode 100644 index 00000000000..7f873d17cb9 --- /dev/null +++ b/queue-3.18/android-binder-add-strong-ref-checks.patch @@ -0,0 +1,107 @@ +From 0a3ffab93fe52530602fe47cd74802cffdb19c05 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= +Date: Mon, 24 Oct 2016 15:20:29 +0200 +Subject: ANDROID: binder: Add strong ref checks +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Arve Hjønnevåg + +commit 0a3ffab93fe52530602fe47cd74802cffdb19c05 upstream. + +Prevent using a binder_ref with only weak references where a strong +reference is required. + +Signed-off-by: Arve Hjønnevåg +Signed-off-by: Martijn Coenen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/android/binder.c | 30 +++++++++++++++++++++--------- + 1 file changed, 21 insertions(+), 9 deletions(-) + +--- a/drivers/staging/android/binder.c ++++ b/drivers/staging/android/binder.c +@@ -998,7 +998,7 @@ static int binder_dec_node(struct binder + + + static struct binder_ref *binder_get_ref(struct binder_proc *proc, +- uint32_t desc) ++ u32 desc, bool need_strong_ref) + { + struct rb_node *n = proc->refs_by_desc.rb_node; + struct binder_ref *ref; +@@ -1006,12 +1006,16 @@ static struct binder_ref *binder_get_ref + while (n) { + ref = rb_entry(n, struct binder_ref, rb_node_desc); + +- if (desc < ref->desc) ++ if (desc < ref->desc) { + n = n->rb_left; +- else if (desc > ref->desc) ++ } else if (desc > ref->desc) { + n = n->rb_right; +- else ++ } else if (need_strong_ref && !ref->strong) { ++ binder_user_error("tried to use weak ref as strong ref\n"); ++ return NULL; ++ } else { + return ref; ++ } + } + return NULL; + } +@@ -1281,7 +1285,10 @@ static void binder_transaction_buffer_re + } break; + case BINDER_TYPE_HANDLE: + case BINDER_TYPE_WEAK_HANDLE: { +- struct binder_ref *ref = binder_get_ref(proc, fp->handle); ++ struct binder_ref *ref; ++ ++ ref = binder_get_ref(proc, fp->handle, ++ fp->type == BINDER_TYPE_HANDLE); + + if (ref == NULL) { + pr_err("transaction release %d bad handle %d\n", +@@ -1375,7 +1382,7 @@ static void binder_transaction(struct bi + if (tr->target.handle) { + struct binder_ref *ref; + +- ref = binder_get_ref(proc, tr->target.handle); ++ ref = binder_get_ref(proc, tr->target.handle, true); + if (ref == NULL) { + binder_user_error("%d:%d got transaction to invalid handle\n", + proc->pid, thread->pid); +@@ -1568,7 +1575,10 @@ static void binder_transaction(struct bi + } break; + case BINDER_TYPE_HANDLE: + case BINDER_TYPE_WEAK_HANDLE: { +- struct binder_ref *ref = binder_get_ref(proc, fp->handle); ++ struct binder_ref *ref; ++ ++ ref = binder_get_ref(proc, fp->handle, ++ fp->type == BINDER_TYPE_HANDLE); + + if (ref == NULL) { + binder_user_error("%d:%d got transaction with invalid handle, %d\n", +@@ -1767,7 +1777,9 @@ static int binder_thread_write(struct bi + ref->desc); + } + } else +- ref = binder_get_ref(proc, target); ++ ref = binder_get_ref(proc, target, ++ cmd == BC_ACQUIRE || ++ cmd == BC_RELEASE); + if (ref == NULL) { + binder_user_error("%d:%d refcount change on invalid ref %d\n", + proc->pid, thread->pid, target); +@@ -1963,7 +1975,7 @@ static int binder_thread_write(struct bi + if (get_user(cookie, (binder_uintptr_t __user *)ptr)) + return -EFAULT; + ptr += sizeof(binder_uintptr_t); +- ref = binder_get_ref(proc, target); ++ ref = binder_get_ref(proc, target, false); + if (ref == NULL) { + binder_user_error("%d:%d %s invalid ref %d\n", + proc->pid, thread->pid, diff --git a/queue-3.18/android-binder-clear-binder-and-cookie-when-setting-handle-in-flat-binder-struct.patch b/queue-3.18/android-binder-clear-binder-and-cookie-when-setting-handle-in-flat-binder-struct.patch new file mode 100644 index 00000000000..0b35bf8274a --- /dev/null +++ b/queue-3.18/android-binder-clear-binder-and-cookie-when-setting-handle-in-flat-binder-struct.patch @@ -0,0 +1,52 @@ +From 4afb604e2d14d429ac9e1fd84b952602853b2df5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= +Date: Mon, 24 Oct 2016 15:20:30 +0200 +Subject: ANDROID: binder: Clear binder and cookie when setting handle in flat binder struct +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Arve Hjønnevåg + +commit 4afb604e2d14d429ac9e1fd84b952602853b2df5 upstream. + +Prevents leaking pointers between processes + +Signed-off-by: Arve Hjønnevåg +Signed-off-by: Martijn Coenen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/android/binder.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/staging/android/binder.c ++++ b/drivers/staging/android/binder.c +@@ -1563,7 +1563,9 @@ static void binder_transaction(struct bi + fp->type = BINDER_TYPE_HANDLE; + else + fp->type = BINDER_TYPE_WEAK_HANDLE; ++ fp->binder = 0; + fp->handle = ref->desc; ++ fp->cookie = 0; + binder_inc_ref(ref, fp->type == BINDER_TYPE_HANDLE, + &thread->todo); + +@@ -1608,7 +1610,9 @@ static void binder_transaction(struct bi + return_error = BR_FAILED_REPLY; + goto err_binder_get_ref_for_node_failed; + } ++ fp->binder = 0; + fp->handle = new_ref->desc; ++ fp->cookie = 0; + binder_inc_ref(new_ref, fp->type == BINDER_TYPE_HANDLE, NULL); + trace_binder_transaction_ref_to_ref(t, ref, + new_ref); +@@ -1655,6 +1659,7 @@ static void binder_transaction(struct bi + binder_debug(BINDER_DEBUG_TRANSACTION, + " fd %d -> %d\n", fp->handle, target_fd); + /* TODO: fput? */ ++ fp->binder = 0; + fp->handle = target_fd; + } break; + diff --git a/queue-3.18/arm-8584-1-floppy-avoid-gcc-6-warning.patch b/queue-3.18/arm-8584-1-floppy-avoid-gcc-6-warning.patch new file mode 100644 index 00000000000..e007ba9a080 --- /dev/null +++ b/queue-3.18/arm-8584-1-floppy-avoid-gcc-6-warning.patch @@ -0,0 +1,43 @@ +From dd665be0e243873343a28e18f9f345927b658daf Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Fri, 1 Jul 2016 18:02:22 +0100 +Subject: ARM: 8584/1: floppy: avoid gcc-6 warning + +From: Arnd Bergmann + +commit dd665be0e243873343a28e18f9f345927b658daf upstream. + +gcc-6.0 warns about comparisons between two identical expressions, +which is what we get in the floppy driver when writing to the FD_DOR +register: + +drivers/block/floppy.c: In function 'set_dor': +drivers/block/floppy.c:810:44: error: self-comparison always evaluates to true [-Werror=tautological-compare] + fd_outb(newdor, FD_DOR); + +It would be nice to use a static inline function instead of the +macro, to avoid the warning, but we cannot do that because the +FD_DOR definition is incomplete at this point. + +Adding a cast to (u32) is a harmless way to shut up the warning, +just not very nice. + +Signed-off-by: Arnd Bergmann +Signed-off-by: Russell King +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/include/asm/floppy.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/include/asm/floppy.h ++++ b/arch/arm/include/asm/floppy.h +@@ -17,7 +17,7 @@ + + #define fd_outb(val,port) \ + do { \ +- if ((port) == FD_DOR) \ ++ if ((port) == (u32)FD_DOR) \ + fd_setdor((val)); \ + else \ + outb((val),(port)); \ diff --git a/queue-3.18/drm-exynos-fix-error-handling-in-exynos_drm_subdrv_open.patch b/queue-3.18/drm-exynos-fix-error-handling-in-exynos_drm_subdrv_open.patch new file mode 100644 index 00000000000..e4ca7b64155 --- /dev/null +++ b/queue-3.18/drm-exynos-fix-error-handling-in-exynos_drm_subdrv_open.patch @@ -0,0 +1,46 @@ +From 55c4b906aa2aec3fa66310ec03c6842e34a04b2a Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Mon, 14 Mar 2016 15:22:25 +0100 +Subject: drm/exynos: fix error handling in exynos_drm_subdrv_open + +From: Arnd Bergmann + +commit 55c4b906aa2aec3fa66310ec03c6842e34a04b2a upstream. + +gcc-6 warns about a pointless loop in exynos_drm_subdrv_open: + +drivers/gpu/drm/exynos/exynos_drm_core.c: In function 'exynos_drm_subdrv_open': +drivers/gpu/drm/exynos/exynos_drm_core.c:104:199: error: self-comparison always evaluates to false [-Werror=tautological-compare] + list_for_each_entry_reverse(subdrv, &subdrv->list, list) { + +Here, the list_for_each_entry_reverse immediately terminates because +the subdrv pointer is compared to itself as the loop end condition. + +If we were to take the current subdrv pointer as the start of the +list (as we would do if list_for_each_entry_reverse() was not a macro), +we would iterate backwards over the &exynos_drm_subdrv_list anchor, +which would be even worse. + +Instead, we need to use list_for_each_entry_continue_reverse() +to go back over each subdrv that was successfully opened until +the first entry. + +Signed-off-by: Arnd Bergmann +Signed-off-by: Inki Dae +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/exynos/exynos_drm_core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpu/drm/exynos/exynos_drm_core.c ++++ b/drivers/gpu/drm/exynos/exynos_drm_core.c +@@ -141,7 +141,7 @@ int exynos_drm_subdrv_open(struct drm_de + return 0; + + err: +- list_for_each_entry_reverse(subdrv, &subdrv->list, list) { ++ list_for_each_entry_continue_reverse(subdrv, &exynos_drm_subdrv_list, list) { + if (subdrv->close) + subdrv->close(dev, subdrv->dev, file); + } diff --git a/queue-3.18/fbdev-color-map-copying-bounds-checking.patch b/queue-3.18/fbdev-color-map-copying-bounds-checking.patch new file mode 100644 index 00000000000..be9e7b23fb8 --- /dev/null +++ b/queue-3.18/fbdev-color-map-copying-bounds-checking.patch @@ -0,0 +1,82 @@ +From 2dc705a9930b4806250fbf5a76e55266e59389f2 Mon Sep 17 00:00:00 2001 +From: Kees Cook +Date: Tue, 24 Jan 2017 15:18:24 -0800 +Subject: fbdev: color map copying bounds checking + +From: Kees Cook + +commit 2dc705a9930b4806250fbf5a76e55266e59389f2 upstream. + +Copying color maps to userspace doesn't check the value of to->start, +which will cause kernel heap buffer OOB read due to signedness wraps. + +CVE-2016-8405 + +Link: http://lkml.kernel.org/r/20170105224249.GA50925@beast +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Kees Cook +Reported-by: Peter Pi (@heisecode) of Trend Micro +Cc: Min Chong +Cc: Dan Carpenter +Cc: Tomi Valkeinen +Cc: Bartlomiej Zolnierkiewicz +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/video/fbdev/core/fbcmap.c | 26 ++++++++++++++------------ + 1 file changed, 14 insertions(+), 12 deletions(-) + +--- a/drivers/video/fbdev/core/fbcmap.c ++++ b/drivers/video/fbdev/core/fbcmap.c +@@ -163,17 +163,18 @@ void fb_dealloc_cmap(struct fb_cmap *cma + + int fb_copy_cmap(const struct fb_cmap *from, struct fb_cmap *to) + { +- int tooff = 0, fromoff = 0; +- int size; ++ unsigned int tooff = 0, fromoff = 0; ++ size_t size; + + if (to->start > from->start) + fromoff = to->start - from->start; + else + tooff = from->start - to->start; +- size = to->len - tooff; +- if (size > (int) (from->len - fromoff)) +- size = from->len - fromoff; +- if (size <= 0) ++ if (fromoff >= from->len || tooff >= to->len) ++ return -EINVAL; ++ ++ size = min_t(size_t, to->len - tooff, from->len - fromoff); ++ if (size == 0) + return -EINVAL; + size *= sizeof(u16); + +@@ -187,17 +188,18 @@ int fb_copy_cmap(const struct fb_cmap *f + + int fb_cmap_to_user(const struct fb_cmap *from, struct fb_cmap_user *to) + { +- int tooff = 0, fromoff = 0; +- int size; ++ unsigned int tooff = 0, fromoff = 0; ++ size_t size; + + if (to->start > from->start) + fromoff = to->start - from->start; + else + tooff = from->start - to->start; +- size = to->len - tooff; +- if (size > (int) (from->len - fromoff)) +- size = from->len - fromoff; +- if (size <= 0) ++ if (fromoff >= from->len || tooff >= to->len) ++ return -EINVAL; ++ ++ size = min_t(size_t, to->len - tooff, from->len - fromoff); ++ if (size == 0) + return -EINVAL; + size *= sizeof(u16); + diff --git a/queue-3.18/fix-potential-infoleak-in-older-kernels.patch b/queue-3.18/fix-potential-infoleak-in-older-kernels.patch new file mode 100644 index 00000000000..6dd814488c2 --- /dev/null +++ b/queue-3.18/fix-potential-infoleak-in-older-kernels.patch @@ -0,0 +1,67 @@ +From dc1555e670c373bfa4ca2e1e2f839d5fe2b4501a Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Tue, 8 Nov 2016 11:17:00 +0100 +Subject: Fix potential infoleak in older kernels + +From: Linus Torvalds + +commit dc1555e670c373bfa4ca2e1e2f839d5fe2b4501a upstream. + +Not upstream as it is not needed there. + +So a patch something like this might be a safe way to fix the +potential infoleak in older kernels. + +THIS IS UNTESTED. It's a very obvious patch, though, so if it compiles +it probably works. It just initializes the output variable with 0 in +the inline asm description, instead of doing it in the exception +handler. + +It will generate slightly worse code (a few unnecessary ALU +operations), but it doesn't have any interactions with the exception +handler implementation. + + +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/include/asm/uaccess.h | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/arch/x86/include/asm/uaccess.h ++++ b/arch/x86/include/asm/uaccess.h +@@ -329,7 +329,7 @@ do { \ + #define __get_user_asm_u64(x, ptr, retval, errret) \ + __get_user_asm(x, ptr, retval, "q", "", "=r", errret) + #define __get_user_asm_ex_u64(x, ptr) \ +- __get_user_asm_ex(x, ptr, "q", "", "=r") ++ __get_user_asm_ex(x, ptr, "q", "", "=&r") + #endif + + #define __get_user_size(x, ptr, size, retval, errret) \ +@@ -372,13 +372,13 @@ do { \ + __chk_user_ptr(ptr); \ + switch (size) { \ + case 1: \ +- __get_user_asm_ex(x, ptr, "b", "b", "=q"); \ ++ __get_user_asm_ex(x, ptr, "b", "b", "=&q"); \ + break; \ + case 2: \ +- __get_user_asm_ex(x, ptr, "w", "w", "=r"); \ ++ __get_user_asm_ex(x, ptr, "w", "w", "=&r"); \ + break; \ + case 4: \ +- __get_user_asm_ex(x, ptr, "l", "k", "=r"); \ ++ __get_user_asm_ex(x, ptr, "l", "k", "=&r"); \ + break; \ + case 8: \ + __get_user_asm_ex_u64(x, ptr); \ +@@ -396,7 +396,7 @@ do { \ + " jmp 2b\n" \ + ".previous\n" \ + _ASM_EXTABLE_EX(1b, 3b) \ +- : ltype(x) : "m" (__m(addr))) ++ : ltype(x) : "m" (__m(addr)), "0" (0)) + + #define __put_user_nocheck(x, ptr, size) \ + ({ \ diff --git a/queue-3.18/hid-usbhid-add-aten-cs962-to-list-of-quirky-devices.patch b/queue-3.18/hid-usbhid-add-aten-cs962-to-list-of-quirky-devices.patch new file mode 100644 index 00000000000..caa1872bd45 --- /dev/null +++ b/queue-3.18/hid-usbhid-add-aten-cs962-to-list-of-quirky-devices.patch @@ -0,0 +1,41 @@ +From cf0ea4da4c7df11f7a508b2f37518e0f117f3791 Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Thu, 3 Nov 2016 12:31:41 +0100 +Subject: HID: usbhid: add ATEN CS962 to list of quirky devices + +From: Oliver Neukum + +commit cf0ea4da4c7df11f7a508b2f37518e0f117f3791 upstream. + +Like many similar devices it needs a quirk to work. +Issuing the request gets the device into an irrecoverable state. + +Signed-off-by: Oliver Neukum +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hid/hid-ids.h | 1 + + drivers/hid/usbhid/hid-quirks.c | 1 + + 2 files changed, 2 insertions(+) + +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -168,6 +168,7 @@ + #define USB_DEVICE_ID_ATEN_4PORTKVM 0x2205 + #define USB_DEVICE_ID_ATEN_4PORTKVMC 0x2208 + #define USB_DEVICE_ID_ATEN_CS682 0x2213 ++#define USB_DEVICE_ID_ATEN_CS692 0x8021 + + #define USB_VENDOR_ID_ATMEL 0x03eb + #define USB_DEVICE_ID_ATMEL_MULTITOUCH 0x211c +--- a/drivers/hid/usbhid/hid-quirks.c ++++ b/drivers/hid/usbhid/hid-quirks.c +@@ -61,6 +61,7 @@ static const struct hid_blacklist { + { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS682, HID_QUIRK_NOGET }, ++ { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS692, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FIGHTERSTICK, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_COMBATSTICK, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_ECLIPSE_YOKE, HID_QUIRK_NOGET }, diff --git a/queue-3.18/iommu-vt-d-fix-iommu-lookup-for-sr-iov-virtual-functions.patch b/queue-3.18/iommu-vt-d-fix-iommu-lookup-for-sr-iov-virtual-functions.patch new file mode 100644 index 00000000000..cf459a67d95 --- /dev/null +++ b/queue-3.18/iommu-vt-d-fix-iommu-lookup-for-sr-iov-virtual-functions.patch @@ -0,0 +1,82 @@ +From 1c387188c60f53b338c20eee32db055dfe022a9b Mon Sep 17 00:00:00 2001 +From: Ashok Raj +Date: Fri, 21 Oct 2016 15:32:05 -0700 +Subject: iommu/vt-d: Fix IOMMU lookup for SR-IOV Virtual Functions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ashok Raj + +commit 1c387188c60f53b338c20eee32db055dfe022a9b upstream. + +The VT-d specification (§8.3.3) says: + ‘Virtual Functions’ of a ‘Physical Function’ are under the scope + of the same remapping unit as the ‘Physical Function’. + +The BIOS is not required to list all the possible VFs in the scope +tables, and arguably *shouldn't* make any attempt to do so, since there +could be a huge number of them. + +This has been broken basically for ever — the VF is never going to match +against a specific unit's scope, so it ends up being assigned to the +INCLUDE_ALL IOMMU. Which was always actually correct by coincidence, but +now we're looking at Root-Complex integrated devices with SR-IOV support +it's going to start being wrong. + +Fix it to simply use pci_physfn() before doing the lookup for PCI devices. + +Cc: stable@vger.kernel.org +Signed-off-by: Sainath Grandhi +Signed-off-by: Ashok Raj +Signed-off-by: David Woodhouse +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iommu/dmar.c | 4 +++- + drivers/iommu/intel-iommu.c | 13 +++++++++++++ + 2 files changed, 16 insertions(+), 1 deletion(-) + +--- a/drivers/iommu/dmar.c ++++ b/drivers/iommu/dmar.c +@@ -317,7 +317,9 @@ static int dmar_pci_bus_notifier(struct + struct pci_dev *pdev = to_pci_dev(data); + struct dmar_pci_notify_info *info; + +- /* Only care about add/remove events for physical functions */ ++ /* Only care about add/remove events for physical functions. ++ * For VFs we actually do the lookup based on the corresponding ++ * PF in device_to_iommu() anyway. */ + if (pdev->is_virtfn) + return NOTIFY_DONE; + if (action != BUS_NOTIFY_ADD_DEVICE && action != BUS_NOTIFY_DEL_DEVICE) +--- a/drivers/iommu/intel-iommu.c ++++ b/drivers/iommu/intel-iommu.c +@@ -696,7 +696,13 @@ static struct intel_iommu *device_to_iom + int i; + + if (dev_is_pci(dev)) { ++ struct pci_dev *pf_pdev; ++ + pdev = to_pci_dev(dev); ++ /* VFs aren't listed in scope tables; we need to look up ++ * the PF instead to find the IOMMU. */ ++ pf_pdev = pci_physfn(pdev); ++ dev = &pf_pdev->dev; + segment = pci_domain_nr(pdev->bus); + } else if (ACPI_COMPANION(dev)) + dev = &ACPI_COMPANION(dev)->dev; +@@ -709,6 +715,13 @@ static struct intel_iommu *device_to_iom + for_each_active_dev_scope(drhd->devices, + drhd->devices_cnt, i, tmp) { + if (tmp == dev) { ++ /* For a VF use its original BDF# not that of the PF ++ * which we used for the IOMMU lookup. Strictly speaking ++ * we could do this for all PCI devices; we only need to ++ * get the BDF# from the scope table for ACPI matches. */ ++ if (pdev->is_virtfn) ++ goto got_pdev; ++ + *bus = drhd->devices[i].bus; + *devfn = drhd->devices[i].devfn; + goto out; diff --git a/queue-3.18/ip6_gre-fix-flowi6_proto-value-in-ip6gre_xmit_other.patch b/queue-3.18/ip6_gre-fix-flowi6_proto-value-in-ip6gre_xmit_other.patch new file mode 100644 index 00000000000..a4f401bca2e --- /dev/null +++ b/queue-3.18/ip6_gre-fix-flowi6_proto-value-in-ip6gre_xmit_other.patch @@ -0,0 +1,42 @@ +From foo@baz Mon Feb 20 16:34:36 CET 2017 +From: Lance Richardson +Date: Fri, 23 Sep 2016 15:50:29 -0400 +Subject: [PATCH 075/760] ip6_gre: fix flowi6_proto value in ip6gre_xmit_other() + +From: Lance Richardson + + +[ Upstream commit db32e4e49ce2b0e5fcc17803d011a401c0a637f6 ] + +Similar to commit 3be07244b733 ("ip6_gre: fix flowi6_proto value in +xmit path"), set flowi6_proto to IPPROTO_GRE for output route lookup. + +Up until now, ip6gre_xmit_other() has set flowi6_proto to a bogus value. +This affected output route lookup for packets sent on an ip6gretap device +in cases where routing was dependent on the value of flowi6_proto. + +Since the correct proto is already set in the tunnel flowi6 template via +commit 252f3f5a1189 ("ip6_gre: Set flowi6_proto as IPPROTO_GRE in xmit +path."), simply delete the line setting the incorrect flowi6_proto value. + +Suggested-by: Jiri Benc +Fixes: c12b395a4664 ("gre: Support GRE over IPv6") +Reviewed-by: Shmulik Ladkani +Signed-off-by: Lance Richardson +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/ip6_gre.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/net/ipv6/ip6_gre.c ++++ b/net/ipv6/ip6_gre.c +@@ -892,7 +892,6 @@ static int ip6gre_xmit_other(struct sk_b + encap_limit = t->parms.encap_limit; + + memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6)); +- fl6.flowi6_proto = skb->protocol; + + err = ip6gre_xmit2(skb, dev, 0, &fl6, encap_limit, &mtu); + diff --git a/queue-3.18/ipmr-ip6mr-fix-scheduling-while-atomic-and-a-deadlock-with-ipmr_get_route.patch b/queue-3.18/ipmr-ip6mr-fix-scheduling-while-atomic-and-a-deadlock-with-ipmr_get_route.patch new file mode 100644 index 00000000000..8810a8ff02f --- /dev/null +++ b/queue-3.18/ipmr-ip6mr-fix-scheduling-while-atomic-and-a-deadlock-with-ipmr_get_route.patch @@ -0,0 +1,161 @@ +From foo@baz Mon Feb 20 16:34:36 CET 2017 +From: Nikolay Aleksandrov +Date: Sun, 25 Sep 2016 23:08:31 +0200 +Subject: [PATCH 076/760] ipmr, ip6mr: fix scheduling while atomic and a deadlock with ipmr_get_route + +From: Nikolay Aleksandrov + + +[ Upstream commit 2cf750704bb6d7ed8c7d732e071dd1bc890ea5e8 ] + +Since the commit below the ipmr/ip6mr rtnl_unicast() code uses the portid +instead of the previous dst_pid which was copied from in_skb's portid. +Since the skb is new the portid is 0 at that point so the packets are sent +to the kernel and we get scheduling while atomic or a deadlock (depending +on where it happens) by trying to acquire rtnl two times. +Also since this is RTM_GETROUTE, it can be triggered by a normal user. + +Here's the sleeping while atomic trace: +[ 7858.212557] BUG: sleeping function called from invalid context at kernel/locking/mutex.c:620 +[ 7858.212748] in_atomic(): 1, irqs_disabled(): 0, pid: 0, name: swapper/0 +[ 7858.212881] 2 locks held by swapper/0/0: +[ 7858.213013] #0: (((&mrt->ipmr_expire_timer))){+.-...}, at: [] call_timer_fn+0x5/0x350 +[ 7858.213422] #1: (mfc_unres_lock){+.....}, at: [] ipmr_expire_process+0x25/0x130 +[ 7858.213807] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.8.0-rc7+ #179 +[ 7858.213934] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140531_083030-gandalf 04/01/2014 +[ 7858.214108] 0000000000000000 ffff88005b403c50 ffffffff813a7804 0000000000000000 +[ 7858.214412] ffffffff81a1338e ffff88005b403c78 ffffffff810a4a72 ffffffff81a1338e +[ 7858.214716] 000000000000026c 0000000000000000 ffff88005b403ca8 ffffffff810a4b9f +[ 7858.215251] Call Trace: +[ 7858.215412] [] dump_stack+0x85/0xc1 +[ 7858.215662] [] ___might_sleep+0x192/0x250 +[ 7858.215868] [] __might_sleep+0x6f/0x100 +[ 7858.216072] [] mutex_lock_nested+0x33/0x4d0 +[ 7858.216279] [] ? netlink_lookup+0x25f/0x460 +[ 7858.216487] [] rtnetlink_rcv+0x1b/0x40 +[ 7858.216687] [] netlink_unicast+0x19c/0x260 +[ 7858.216900] [] rtnl_unicast+0x20/0x30 +[ 7858.217128] [] ipmr_destroy_unres+0xa9/0xf0 +[ 7858.217351] [] ipmr_expire_process+0x8f/0x130 +[ 7858.217581] [] ? ipmr_net_init+0x180/0x180 +[ 7858.217785] [] ? ipmr_net_init+0x180/0x180 +[ 7858.217990] [] call_timer_fn+0xa5/0x350 +[ 7858.218192] [] ? call_timer_fn+0x5/0x350 +[ 7858.218415] [] ? ipmr_net_init+0x180/0x180 +[ 7858.218656] [] run_timer_softirq+0x260/0x640 +[ 7858.218865] [] ? __do_softirq+0xbb/0x54f +[ 7858.219068] [] __do_softirq+0xe8/0x54f +[ 7858.219269] [] irq_exit+0xb8/0xc0 +[ 7858.219463] [] smp_apic_timer_interrupt+0x42/0x50 +[ 7858.219678] [] apic_timer_interrupt+0x8c/0xa0 +[ 7858.219897] [] ? native_safe_halt+0x6/0x10 +[ 7858.220165] [] ? trace_hardirqs_on+0xd/0x10 +[ 7858.220373] [] default_idle+0x23/0x190 +[ 7858.220574] [] arch_cpu_idle+0xf/0x20 +[ 7858.220790] [] default_idle_call+0x4c/0x60 +[ 7858.221016] [] cpu_startup_entry+0x39b/0x4d0 +[ 7858.221257] [] rest_init+0x135/0x140 +[ 7858.221469] [] start_kernel+0x50e/0x51b +[ 7858.221670] [] ? early_idt_handler_array+0x120/0x120 +[ 7858.221894] [] x86_64_start_reservations+0x2a/0x2c +[ 7858.222113] [] x86_64_start_kernel+0x13b/0x14a + +Fixes: 2942e9005056 ("[RTNETLINK]: Use rtnl_unicast() for rtnetlink unicasts") +Signed-off-by: Nikolay Aleksandrov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/mroute.h | 2 +- + include/linux/mroute6.h | 2 +- + net/ipv4/ipmr.c | 3 ++- + net/ipv4/route.c | 3 ++- + net/ipv6/ip6mr.c | 5 +++-- + net/ipv6/route.c | 4 +++- + 6 files changed, 12 insertions(+), 7 deletions(-) + +--- a/include/linux/mroute.h ++++ b/include/linux/mroute.h +@@ -103,5 +103,5 @@ struct mfc_cache { + struct rtmsg; + extern int ipmr_get_route(struct net *net, struct sk_buff *skb, + __be32 saddr, __be32 daddr, +- struct rtmsg *rtm, int nowait); ++ struct rtmsg *rtm, int nowait, u32 portid); + #endif +--- a/include/linux/mroute6.h ++++ b/include/linux/mroute6.h +@@ -115,7 +115,7 @@ struct mfc6_cache { + + struct rtmsg; + extern int ip6mr_get_route(struct net *net, struct sk_buff *skb, +- struct rtmsg *rtm, int nowait); ++ struct rtmsg *rtm, int nowait, u32 portid); + + #ifdef CONFIG_IPV6_MROUTE + extern struct sock *mroute6_socket(struct net *net, struct sk_buff *skb); +--- a/net/ipv4/ipmr.c ++++ b/net/ipv4/ipmr.c +@@ -2188,7 +2188,7 @@ static int __ipmr_fill_mroute(struct mr_ + + int ipmr_get_route(struct net *net, struct sk_buff *skb, + __be32 saddr, __be32 daddr, +- struct rtmsg *rtm, int nowait) ++ struct rtmsg *rtm, int nowait, u32 portid) + { + struct mfc_cache *cache; + struct mr_table *mrt; +@@ -2233,6 +2233,7 @@ int ipmr_get_route(struct net *net, stru + return -ENOMEM; + } + ++ NETLINK_CB(skb2).portid = portid; + skb_push(skb2, sizeof(struct iphdr)); + skb_reset_network_header(skb2); + iph = ip_hdr(skb2); +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -2373,7 +2373,8 @@ static int rt_fill_info(struct net *net, + IPV4_DEVCONF_ALL(net, MC_FORWARDING)) { + int err = ipmr_get_route(net, skb, + fl4->saddr, fl4->daddr, +- r, nowait); ++ r, nowait, portid); ++ + if (err <= 0) { + if (!nowait) { + if (err == 0) +--- a/net/ipv6/ip6mr.c ++++ b/net/ipv6/ip6mr.c +@@ -2276,8 +2276,8 @@ static int __ip6mr_fill_mroute(struct mr + return 1; + } + +-int ip6mr_get_route(struct net *net, +- struct sk_buff *skb, struct rtmsg *rtm, int nowait) ++int ip6mr_get_route(struct net *net, struct sk_buff *skb, struct rtmsg *rtm, ++ int nowait, u32 portid) + { + int err; + struct mr6_table *mrt; +@@ -2322,6 +2322,7 @@ int ip6mr_get_route(struct net *net, + return -ENOMEM; + } + ++ NETLINK_CB(skb2).portid = portid; + skb_reset_transport_header(skb2); + + skb_put(skb2, sizeof(struct ipv6hdr)); +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -2612,7 +2612,9 @@ static int rt6_fill_node(struct net *net + if (iif) { + #ifdef CONFIG_IPV6_MROUTE + if (ipv6_addr_is_multicast(&rt->rt6i_dst.addr)) { +- int err = ip6mr_get_route(net, skb, rtm, nowait); ++ int err = ip6mr_get_route(net, skb, rtm, nowait, ++ portid); ++ + if (err <= 0) { + if (!nowait) { + if (err == 0) diff --git a/queue-3.18/ipv4-disable-bh-in-set_ping_group_range.patch b/queue-3.18/ipv4-disable-bh-in-set_ping_group_range.patch new file mode 100644 index 00000000000..3edcfd0b633 --- /dev/null +++ b/queue-3.18/ipv4-disable-bh-in-set_ping_group_range.patch @@ -0,0 +1,39 @@ +From foo@baz Mon Feb 20 16:34:36 CET 2017 +From: Eric Dumazet +Date: Thu, 20 Oct 2016 10:26:48 -0700 +Subject: [PATCH 091/760] ipv4: disable BH in set_ping_group_range() + +From: Eric Dumazet + + +[ Upstream commit a681574c99be23e4d20b769bf0e543239c364af5 ] + +In commit 4ee3bd4a8c746 ("ipv4: disable BH when changing ip local port +range") Cong added BH protection in set_local_port_range() but missed +that same fix was needed in set_ping_group_range() + +Fixes: b8f1a55639e6 ("udp: Add function to make source port for UDP tunnels") +Signed-off-by: Eric Dumazet +Reported-by: Eric Salo +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +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 +@@ -103,10 +103,10 @@ static void set_ping_group_range(struct + kgid_t *data = table->data; + struct net *net = + container_of(table->data, struct net, ipv4.ping_group_range.range); +- write_seqlock(&net->ipv4.ip_local_ports.lock); ++ write_seqlock_bh(&net->ipv4.ip_local_ports.lock); + data[0] = low; + data[1] = high; +- 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/queue-3.18/ipv6-correctly-add-local-routes-when-lo-goes-up.patch b/queue-3.18/ipv6-correctly-add-local-routes-when-lo-goes-up.patch new file mode 100644 index 00000000000..cdc583d5854 --- /dev/null +++ b/queue-3.18/ipv6-correctly-add-local-routes-when-lo-goes-up.patch @@ -0,0 +1,58 @@ +From foo@baz Mon Feb 20 16:34:36 CET 2017 +From: Nicolas Dichtel +Date: Wed, 12 Oct 2016 10:10:40 +0200 +Subject: [PATCH 086/760] ipv6: correctly add local routes when lo goes up + +From: Nicolas Dichtel + + +[ Upstream commit a220445f9f4382c36a53d8ef3e08165fa27f7e2c ] + +The goal of the patch is to fix this scenario: + ip link add dummy1 type dummy + ip link set dummy1 up + ip link set lo down ; ip link set lo up + +After that sequence, the local route to the link layer address of dummy1 is +not there anymore. + +When the loopback is set down, all local routes are deleted by +addrconf_ifdown()/rt6_ifdown(). At this time, the rt6_info entry still +exists, because the corresponding idev has a reference on it. After the rcu +grace period, dst_rcu_free() is called, and thus ___dst_free(), which will +set obsolete to DST_OBSOLETE_DEAD. + +In this case, init_loopback() is called before dst_rcu_free(), thus +obsolete is still sets to something <= 0. So, the function doesn't add the +route again. To avoid that race, let's check the rt6 refcnt instead. + +Fixes: 25fb6ca4ed9c ("net IPv6 : Fix broken IPv6 routing table after loopback down-up") +Fixes: a881ae1f625c ("ipv6: don't call addrconf_dst_alloc again when enable lo") +Fixes: 33d99113b110 ("ipv6: reallocate addrconf router for ipv6 address when lo device up") +Reported-by: Francesco Santoro +Reported-by: Samuel Gauthier +CC: Balakumaran Kannan +CC: Maruthi Thotad +CC: Sabrina Dubroca +CC: Hannes Frederic Sowa +CC: Weilong Chen +CC: Gao feng +Signed-off-by: Nicolas Dichtel +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/addrconf.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -2695,7 +2695,7 @@ static void init_loopback(struct net_dev + * lo device down, release this obsolete dst and + * reallocate a new router for ifa. + */ +- if (sp_ifa->rt->dst.obsolete > 0) { ++ if (!atomic_read(&sp_ifa->rt->rt6i_ref)) { + ip6_rt_put(sp_ifa->rt); + sp_ifa->rt = NULL; + } else { diff --git a/queue-3.18/ipv6-tcp-add-a-missing-tcp_v6_restore_cb.patch b/queue-3.18/ipv6-tcp-add-a-missing-tcp_v6_restore_cb.patch index 2325a54dea2..75fcdfa7090 100644 --- a/queue-3.18/ipv6-tcp-add-a-missing-tcp_v6_restore_cb.patch +++ b/queue-3.18/ipv6-tcp-add-a-missing-tcp_v6_restore_cb.patch @@ -22,12 +22,12 @@ Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- - net/ipv6/tcp_ipv6.c | 22 ++++++++++++---------- - 1 file changed, 12 insertions(+), 10 deletions(-) + net/ipv6/tcp_ipv6.c | 24 +++++++++++++----------- + 1 file changed, 13 insertions(+), 11 deletions(-) --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c -@@ -1049,6 +1049,15 @@ drop: +@@ -1049,6 +1049,16 @@ drop: return 0; /* don't send reset */ } @@ -35,6 +35,7 @@ Signed-off-by: Greg Kroah-Hartman +{ + /* We need to move header back to the beginning if xfrm6_policy_check() + * and tcp_v6_fill_cb() are going to be called again. ++ * ip6_datagram_recv_specific_ctl() also expects IP6CB to be there. + */ + memmove(IP6CB(skb), &TCP_SKB_CB(skb)->header.h6, + sizeof(struct inet6_skb_parm)); @@ -43,7 +44,7 @@ Signed-off-by: Greg Kroah-Hartman static struct sock *tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, struct request_sock *req, struct dst_entry *dst) -@@ -1180,8 +1189,10 @@ static struct sock *tcp_v6_syn_recv_sock +@@ -1180,8 +1190,10 @@ static struct sock *tcp_v6_syn_recv_sock sk_gfp_atomic(sk, GFP_ATOMIC)); consume_skb(ireq->pktopts); ireq->pktopts = NULL; @@ -55,19 +56,20 @@ Signed-off-by: Greg Kroah-Hartman } newnp->opt = NULL; newnp->mcast_oif = tcp_v6_iif(skb); -@@ -1414,15 +1425,6 @@ static void tcp_v6_fill_cb(struct sk_buf - TCP_SKB_CB(skb)->sacked = 0; +@@ -1250,16 +1262,6 @@ out: + return NULL; } -static void tcp_v6_restore_cb(struct sk_buff *skb) -{ - /* We need to move header back to the beginning if xfrm6_policy_check() - * and tcp_v6_fill_cb() are going to be called again. +- * ip6_datagram_recv_specific_ctl() also expects IP6CB to be there. - */ - memmove(IP6CB(skb), &TCP_SKB_CB(skb)->header.h6, - sizeof(struct inet6_skb_parm)); -} - - static int tcp_v6_rcv(struct sk_buff *skb) - { - const struct tcphdr *th; + /* The socket must have it's spinlock held when we get + * here. + * diff --git a/queue-3.18/ipv6-tcp-restore-ip6cb-for-pktoptions-skbs.patch b/queue-3.18/ipv6-tcp-restore-ip6cb-for-pktoptions-skbs.patch new file mode 100644 index 00000000000..68007abc006 --- /dev/null +++ b/queue-3.18/ipv6-tcp-restore-ip6cb-for-pktoptions-skbs.patch @@ -0,0 +1,98 @@ +From foo@baz Mon Feb 20 16:34:36 CET 2017 +From: Eric Dumazet +Date: Wed, 12 Oct 2016 19:01:45 +0200 +Subject: [PATCH 084/760] ipv6: tcp: restore IP6CB for pktoptions skbs + +From: Eric Dumazet + + +[ Upstream commit 8ce48623f0cf3d632e32448411feddccb693d351 ] + +Baozeng Ding reported following KASAN splat : + +BUG: KASAN: use-after-free in ip6_datagram_recv_specific_ctl+0x13f1/0x15c0 at addr ffff880029c84ec8 +Read of size 1 by task poc/25548 +Call Trace: + [] dump_stack+0x12e/0x185 /lib/dump_stack.c:15 + [< inline >] print_address_description /mm/kasan/report.c:204 + [] kasan_report_error+0x48b/0x4b0 /mm/kasan/report.c:283 + [< inline >] kasan_report /mm/kasan/report.c:303 + [] __asan_report_load1_noabort+0x3e/0x40 /mm/kasan/report.c:321 + [] ip6_datagram_recv_specific_ctl+0x13f1/0x15c0 /net/ipv6/datagram.c:687 + [] ip6_datagram_recv_ctl+0x33/0x40 + [] do_ipv6_getsockopt.isra.4+0xaec/0x2150 + [] ipv6_getsockopt+0x116/0x230 + [] tcp_getsockopt+0x82/0xd0 /net/ipv4/tcp.c:3035 + [] sock_common_getsockopt+0x95/0xd0 /net/core/sock.c:2647 + [< inline >] SYSC_getsockopt /net/socket.c:1776 + [] SyS_getsockopt+0x142/0x230 /net/socket.c:1758 + [] entry_SYSCALL_64_fastpath+0x23/0xc6 +Memory state around the buggy address: + ffff880029c84d80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ffff880029c84e00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +> ffff880029c84e80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ^ + ffff880029c84f00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ffff880029c84f80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + +He also provided a syzkaller reproducer. + +Issue is that ip6_datagram_recv_specific_ctl() expects to find IP6CB +data that was moved at a different place in tcp_v6_rcv() + +This patch moves tcp_v6_restore_cb() up and calls it from +tcp_v6_do_rcv() when np->pktoptions is set. + +Fixes: 971f10eca186 ("tcp: better TCP_SKB_CB layout to reduce cache line misses") +Signed-off-by: Eric Dumazet +Reported-by: Baozeng Ding +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/tcp_ipv6.c | 20 +++++++++++--------- + 1 file changed, 11 insertions(+), 9 deletions(-) + +--- a/net/ipv6/tcp_ipv6.c ++++ b/net/ipv6/tcp_ipv6.c +@@ -1250,6 +1250,16 @@ out: + return NULL; + } + ++static void tcp_v6_restore_cb(struct sk_buff *skb) ++{ ++ /* We need to move header back to the beginning if xfrm6_policy_check() ++ * and tcp_v6_fill_cb() are going to be called again. ++ * ip6_datagram_recv_specific_ctl() also expects IP6CB to be there. ++ */ ++ memmove(IP6CB(skb), &TCP_SKB_CB(skb)->header.h6, ++ sizeof(struct inet6_skb_parm)); ++} ++ + /* The socket must have it's spinlock held when we get + * here. + * +@@ -1381,6 +1391,7 @@ ipv6_pktoptions: + np->flow_label = ip6_flowlabel(ipv6_hdr(opt_skb)); + if (ipv6_opt_accepted(sk, opt_skb, &TCP_SKB_CB(opt_skb)->header.h6)) { + skb_set_owner_r(opt_skb, sk); ++ tcp_v6_restore_cb(opt_skb); + opt_skb = xchg(&np->pktoptions, opt_skb); + } else { + __kfree_skb(opt_skb); +@@ -1414,15 +1425,6 @@ static void tcp_v6_fill_cb(struct sk_buf + TCP_SKB_CB(skb)->sacked = 0; + } + +-static void tcp_v6_restore_cb(struct sk_buff *skb) +-{ +- /* We need to move header back to the beginning if xfrm6_policy_check() +- * and tcp_v6_fill_cb() are going to be called again. +- */ +- memmove(IP6CB(skb), &TCP_SKB_CB(skb)->header.h6, +- sizeof(struct inet6_skb_parm)); +-} +- + static int tcp_v6_rcv(struct sk_buff *skb) + { + const struct tcphdr *th; diff --git a/queue-3.18/net-add-netdev-all_adj_list-refcnt-propagation-to-fix-panic.patch b/queue-3.18/net-add-netdev-all_adj_list-refcnt-propagation-to-fix-panic.patch new file mode 100644 index 00000000000..8cea17a208e --- /dev/null +++ b/queue-3.18/net-add-netdev-all_adj_list-refcnt-propagation-to-fix-panic.patch @@ -0,0 +1,272 @@ +From foo@baz Mon Feb 20 16:34:36 CET 2017 +From: Andrew Collins +Date: Mon, 3 Oct 2016 13:43:02 -0600 +Subject: [PATCH 081/760] net: Add netdev all_adj_list refcnt propagation to fix panic + +From: Andrew Collins + + +[ Upstream commit 93409033ae653f1c9a949202fb537ab095b2092f ] + +This is a respin of a patch to fix a relatively easily reproducible kernel +panic related to the all_adj_list handling for netdevs in recent kernels. + +The following sequence of commands will reproduce the issue: + +ip link add link eth0 name eth0.100 type vlan id 100 +ip link add link eth0 name eth0.200 type vlan id 200 +ip link add name testbr type bridge +ip link set eth0.100 master testbr +ip link set eth0.200 master testbr +ip link add link testbr mac0 type macvlan +ip link delete dev testbr + +This creates an upper/lower tree of (excuse the poor ASCII art): + + /---eth0.100-eth0 +mac0-testbr- + \---eth0.200-eth0 + +When testbr is deleted, the all_adj_lists are walked, and eth0 is deleted twice from +the mac0 list. Unfortunately, during setup in __netdev_upper_dev_link, only one +reference to eth0 is added, so this results in a panic. + +This change adds reference count propagation so things are handled properly. + +Matthias Schiffer reported a similar crash in batman-adv: + +https://github.com/freifunk-gluon/gluon/issues/680 +https://www.open-mesh.org/issues/247 + +which this patch also seems to resolve. + +Signed-off-by: Andrew Collins +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + net/core/dev.c | 68 +++++++++++++++++++++++++++++++-------------------------- + 1 file changed, 37 insertions(+), 31 deletions(-) + +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -4893,6 +4893,7 @@ static inline bool netdev_adjacent_is_ne + + static int __netdev_adjacent_dev_insert(struct net_device *dev, + struct net_device *adj_dev, ++ u16 ref_nr, + struct list_head *dev_list, + void *private, bool master) + { +@@ -4902,7 +4903,7 @@ static int __netdev_adjacent_dev_insert( + adj = __netdev_find_adj(dev, adj_dev, dev_list); + + if (adj) { +- adj->ref_nr++; ++ adj->ref_nr += ref_nr; + return 0; + } + +@@ -4912,7 +4913,7 @@ static int __netdev_adjacent_dev_insert( + + adj->dev = adj_dev; + adj->master = master; +- adj->ref_nr = 1; ++ adj->ref_nr = ref_nr; + adj->private = private; + dev_hold(adj_dev); + +@@ -4951,6 +4952,7 @@ free_adj: + + static void __netdev_adjacent_dev_remove(struct net_device *dev, + struct net_device *adj_dev, ++ u16 ref_nr, + struct list_head *dev_list) + { + struct netdev_adjacent *adj; +@@ -4963,10 +4965,10 @@ static void __netdev_adjacent_dev_remove + BUG(); + } + +- if (adj->ref_nr > 1) { +- pr_debug("%s to %s ref_nr-- = %d\n", dev->name, adj_dev->name, +- adj->ref_nr-1); +- adj->ref_nr--; ++ if (adj->ref_nr > ref_nr) { ++ pr_debug("%s to %s ref_nr-%d = %d\n", dev->name, adj_dev->name, ++ ref_nr, adj->ref_nr-ref_nr); ++ adj->ref_nr -= ref_nr; + return; + } + +@@ -4985,21 +4987,22 @@ static void __netdev_adjacent_dev_remove + + static int __netdev_adjacent_dev_link_lists(struct net_device *dev, + struct net_device *upper_dev, ++ u16 ref_nr, + struct list_head *up_list, + struct list_head *down_list, + void *private, bool master) + { + int ret; + +- ret = __netdev_adjacent_dev_insert(dev, upper_dev, up_list, private, +- master); ++ ret = __netdev_adjacent_dev_insert(dev, upper_dev, ref_nr, up_list, ++ private, master); + if (ret) + return ret; + +- ret = __netdev_adjacent_dev_insert(upper_dev, dev, down_list, private, +- false); ++ ret = __netdev_adjacent_dev_insert(upper_dev, dev, ref_nr, down_list, ++ private, false); + if (ret) { +- __netdev_adjacent_dev_remove(dev, upper_dev, up_list); ++ __netdev_adjacent_dev_remove(dev, upper_dev, ref_nr, up_list); + return ret; + } + +@@ -5007,9 +5010,10 @@ static int __netdev_adjacent_dev_link_li + } + + static int __netdev_adjacent_dev_link(struct net_device *dev, +- struct net_device *upper_dev) ++ struct net_device *upper_dev, ++ u16 ref_nr) + { +- return __netdev_adjacent_dev_link_lists(dev, upper_dev, ++ return __netdev_adjacent_dev_link_lists(dev, upper_dev, ref_nr, + &dev->all_adj_list.upper, + &upper_dev->all_adj_list.lower, + NULL, false); +@@ -5017,17 +5021,19 @@ static int __netdev_adjacent_dev_link(st + + static void __netdev_adjacent_dev_unlink_lists(struct net_device *dev, + struct net_device *upper_dev, ++ u16 ref_nr, + struct list_head *up_list, + struct list_head *down_list) + { +- __netdev_adjacent_dev_remove(dev, upper_dev, up_list); +- __netdev_adjacent_dev_remove(upper_dev, dev, down_list); ++ __netdev_adjacent_dev_remove(dev, upper_dev, ref_nr, up_list); ++ __netdev_adjacent_dev_remove(upper_dev, dev, ref_nr, down_list); + } + + static void __netdev_adjacent_dev_unlink(struct net_device *dev, +- struct net_device *upper_dev) ++ struct net_device *upper_dev, ++ u16 ref_nr) + { +- __netdev_adjacent_dev_unlink_lists(dev, upper_dev, ++ __netdev_adjacent_dev_unlink_lists(dev, upper_dev, ref_nr, + &dev->all_adj_list.upper, + &upper_dev->all_adj_list.lower); + } +@@ -5036,17 +5042,17 @@ static int __netdev_adjacent_dev_link_ne + struct net_device *upper_dev, + void *private, bool master) + { +- int ret = __netdev_adjacent_dev_link(dev, upper_dev); ++ int ret = __netdev_adjacent_dev_link(dev, upper_dev, 1); + + if (ret) + return ret; + +- ret = __netdev_adjacent_dev_link_lists(dev, upper_dev, ++ ret = __netdev_adjacent_dev_link_lists(dev, upper_dev, 1, + &dev->adj_list.upper, + &upper_dev->adj_list.lower, + private, master); + if (ret) { +- __netdev_adjacent_dev_unlink(dev, upper_dev); ++ __netdev_adjacent_dev_unlink(dev, upper_dev, 1); + return ret; + } + +@@ -5056,8 +5062,8 @@ static int __netdev_adjacent_dev_link_ne + static void __netdev_adjacent_dev_unlink_neighbour(struct net_device *dev, + struct net_device *upper_dev) + { +- __netdev_adjacent_dev_unlink(dev, upper_dev); +- __netdev_adjacent_dev_unlink_lists(dev, upper_dev, ++ __netdev_adjacent_dev_unlink(dev, upper_dev, 1); ++ __netdev_adjacent_dev_unlink_lists(dev, upper_dev, 1, + &dev->adj_list.upper, + &upper_dev->adj_list.lower); + } +@@ -5098,7 +5104,7 @@ static int __netdev_upper_dev_link(struc + list_for_each_entry(j, &upper_dev->all_adj_list.upper, list) { + pr_debug("Interlinking %s with %s, non-neighbour\n", + i->dev->name, j->dev->name); +- ret = __netdev_adjacent_dev_link(i->dev, j->dev); ++ ret = __netdev_adjacent_dev_link(i->dev, j->dev, i->ref_nr); + if (ret) + goto rollback_mesh; + } +@@ -5108,7 +5114,7 @@ static int __netdev_upper_dev_link(struc + list_for_each_entry(i, &upper_dev->all_adj_list.upper, list) { + pr_debug("linking %s's upper device %s with %s\n", + upper_dev->name, i->dev->name, dev->name); +- ret = __netdev_adjacent_dev_link(dev, i->dev); ++ ret = __netdev_adjacent_dev_link(dev, i->dev, i->ref_nr); + if (ret) + goto rollback_upper_mesh; + } +@@ -5117,7 +5123,7 @@ static int __netdev_upper_dev_link(struc + list_for_each_entry(i, &dev->all_adj_list.lower, list) { + pr_debug("linking %s's lower device %s with %s\n", dev->name, + i->dev->name, upper_dev->name); +- ret = __netdev_adjacent_dev_link(i->dev, upper_dev); ++ ret = __netdev_adjacent_dev_link(i->dev, upper_dev, i->ref_nr); + if (ret) + goto rollback_lower_mesh; + } +@@ -5130,7 +5136,7 @@ rollback_lower_mesh: + list_for_each_entry(i, &dev->all_adj_list.lower, list) { + if (i == to_i) + break; +- __netdev_adjacent_dev_unlink(i->dev, upper_dev); ++ __netdev_adjacent_dev_unlink(i->dev, upper_dev, i->ref_nr); + } + + i = NULL; +@@ -5140,7 +5146,7 @@ rollback_upper_mesh: + list_for_each_entry(i, &upper_dev->all_adj_list.upper, list) { + if (i == to_i) + break; +- __netdev_adjacent_dev_unlink(dev, i->dev); ++ __netdev_adjacent_dev_unlink(dev, i->dev, i->ref_nr); + } + + i = j = NULL; +@@ -5152,7 +5158,7 @@ rollback_mesh: + list_for_each_entry(j, &upper_dev->all_adj_list.upper, list) { + if (i == to_i && j == to_j) + break; +- __netdev_adjacent_dev_unlink(i->dev, j->dev); ++ __netdev_adjacent_dev_unlink(i->dev, j->dev, i->ref_nr); + } + if (i == to_i) + break; +@@ -5228,16 +5234,16 @@ void netdev_upper_dev_unlink(struct net_ + */ + list_for_each_entry(i, &dev->all_adj_list.lower, list) + list_for_each_entry(j, &upper_dev->all_adj_list.upper, list) +- __netdev_adjacent_dev_unlink(i->dev, j->dev); ++ __netdev_adjacent_dev_unlink(i->dev, j->dev, i->ref_nr); + + /* remove also the devices itself from lower/upper device + * list + */ + list_for_each_entry(i, &dev->all_adj_list.lower, list) +- __netdev_adjacent_dev_unlink(i->dev, upper_dev); ++ __netdev_adjacent_dev_unlink(i->dev, upper_dev, i->ref_nr); + + list_for_each_entry(i, &upper_dev->all_adj_list.upper, list) +- __netdev_adjacent_dev_unlink(dev, i->dev); ++ __netdev_adjacent_dev_unlink(dev, i->dev, i->ref_nr); + + call_netdevice_notifiers(NETDEV_CHANGEUPPER, dev); + } diff --git a/queue-3.18/net-pktgen-remove-rcu-locking-in-pktgen_change_name.patch b/queue-3.18/net-pktgen-remove-rcu-locking-in-pktgen_change_name.patch new file mode 100644 index 00000000000..a510934e493 --- /dev/null +++ b/queue-3.18/net-pktgen-remove-rcu-locking-in-pktgen_change_name.patch @@ -0,0 +1,92 @@ +From foo@baz Mon Feb 20 16:34:36 CET 2017 +From: Eric Dumazet +Date: Sat, 15 Oct 2016 17:50:49 +0200 +Subject: [PATCH 087/760] net: pktgen: remove rcu locking in pktgen_change_name() + +From: Eric Dumazet + + +[ Upstream commit 9a0b1e8ba4061778897b544afc898de2163382f7 ] + +After Jesper commit back in linux-3.18, we trigger a lockdep +splat in proc_create_data() while allocating memory from +pktgen_change_name(). + +This patch converts t->if_lock to a mutex, since it is now only +used from control path, and adds proper locking to pktgen_change_name() + +1) pktgen_thread_lock to protect the outer loop (iterating threads) +2) t->if_lock to protect the inner loop (iterating devices) + +Note that before Jesper patch, pktgen_change_name() was lacking proper +protection, but lockdep was not able to detect the problem. + +Fixes: 8788370a1d4b ("pktgen: RCU-ify "if_list" to remove lock in next_to_run()") +Reported-by: John Sperbeck +Signed-off-by: Eric Dumazet +Cc: Jesper Dangaard Brouer +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + net/core/pktgen.c | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +--- a/net/core/pktgen.c ++++ b/net/core/pktgen.c +@@ -211,8 +211,8 @@ + #define T_REMDEV (1<<3) /* Remove one dev */ + + /* If lock -- protects updating of if_list */ +-#define if_lock(t) spin_lock(&(t->if_lock)); +-#define if_unlock(t) spin_unlock(&(t->if_lock)); ++#define if_lock(t) mutex_lock(&(t->if_lock)); ++#define if_unlock(t) mutex_unlock(&(t->if_lock)); + + /* Used to help with determining the pkts on receive */ + #define PKTGEN_MAGIC 0xbe9be955 +@@ -418,7 +418,7 @@ struct pktgen_net { + }; + + struct pktgen_thread { +- spinlock_t if_lock; /* for list of devices */ ++ struct mutex if_lock; /* for list of devices */ + struct list_head if_list; /* All device here */ + struct list_head th_list; + struct task_struct *tsk; +@@ -1952,11 +1952,13 @@ static void pktgen_change_name(const str + { + struct pktgen_thread *t; + ++ mutex_lock(&pktgen_thread_lock); ++ + list_for_each_entry(t, &pn->pktgen_threads, th_list) { + struct pktgen_dev *pkt_dev; + +- rcu_read_lock(); +- list_for_each_entry_rcu(pkt_dev, &t->if_list, list) { ++ if_lock(t); ++ list_for_each_entry(pkt_dev, &t->if_list, list) { + if (pkt_dev->odev != dev) + continue; + +@@ -1971,8 +1973,9 @@ static void pktgen_change_name(const str + dev->name); + break; + } +- rcu_read_unlock(); ++ if_unlock(t); + } ++ mutex_unlock(&pktgen_thread_lock); + } + + static int pktgen_device_event(struct notifier_block *unused, +@@ -3656,7 +3659,7 @@ static int __net_init pktgen_create_thre + return -ENOMEM; + } + +- spin_lock_init(&t->if_lock); ++ mutex_init(&t->if_lock); + t->cpu = cpu; + + INIT_LIST_HEAD(&t->if_list); diff --git a/queue-3.18/net-sctp-forbid-negative-length.patch b/queue-3.18/net-sctp-forbid-negative-length.patch new file mode 100644 index 00000000000..c5b42e08bd4 --- /dev/null +++ b/queue-3.18/net-sctp-forbid-negative-length.patch @@ -0,0 +1,80 @@ +From foo@baz Mon Feb 20 16:34:36 CET 2017 +From: Jiri Slaby +Date: Fri, 21 Oct 2016 14:13:24 +0200 +Subject: [PATCH 093/760] net: sctp, forbid negative length + +From: Jiri Slaby + + +[ Upstream commit a4b8e71b05c27bae6bad3bdecddbc6b68a3ad8cf ] + +Most of getsockopt handlers in net/sctp/socket.c check len against +sizeof some structure like: + if (len < sizeof(int)) + return -EINVAL; + +On the first look, the check seems to be correct. But since len is int +and sizeof returns size_t, int gets promoted to unsigned size_t too. So +the test returns false for negative lengths. Yes, (-1 < sizeof(long)) is +false. + +Fix this in sctp by explicitly checking len < 0 before any getsockopt +handler is called. + +Note that sctp_getsockopt_events already handled the negative case. +Since we added the < 0 check elsewhere, this one can be removed. + +If not checked, this is the result: +UBSAN: Undefined behaviour in ../mm/page_alloc.c:2722:19 +shift exponent 52 is too large for 32-bit type 'int' +CPU: 1 PID: 24535 Comm: syz-executor Not tainted 4.8.1-0-syzkaller #1 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.9.1-0-gb3ef39f-prebuilt.qemu-project.org 04/01/2014 + 0000000000000000 ffff88006d99f2a8 ffffffffb2f7bdea 0000000041b58ab3 + ffffffffb4363c14 ffffffffb2f7bcde ffff88006d99f2d0 ffff88006d99f270 + 0000000000000000 0000000000000000 0000000000000034 ffffffffb5096422 +Call Trace: + [] ? __ubsan_handle_shift_out_of_bounds+0x29c/0x300 +... + [] ? kmalloc_order+0x24/0x90 + [] ? kmalloc_order_trace+0x24/0x220 + [] ? __kmalloc+0x330/0x540 + [] ? sctp_getsockopt_local_addrs+0x174/0xca0 [sctp] + [] ? sctp_getsockopt+0x10d/0x1b0 [sctp] + [] ? sock_common_getsockopt+0xb9/0x150 + [] ? SyS_getsockopt+0x1a5/0x270 + +Signed-off-by: Jiri Slaby +Cc: Vlad Yasevich +Cc: Neil Horman +Cc: "David S. Miller" +Cc: linux-sctp@vger.kernel.org +Cc: netdev@vger.kernel.org +Acked-by: Neil Horman +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + net/sctp/socket.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -4385,7 +4385,7 @@ static int sctp_getsockopt_disable_fragm + static int sctp_getsockopt_events(struct sock *sk, int len, char __user *optval, + int __user *optlen) + { +- if (len <= 0) ++ if (len == 0) + return -EINVAL; + if (len > sizeof(struct sctp_event_subscribe)) + len = sizeof(struct sctp_event_subscribe); +@@ -5981,6 +5981,9 @@ static int sctp_getsockopt(struct sock * + if (get_user(len, optlen)) + return -EFAULT; + ++ if (len < 0) ++ return -EINVAL; ++ + lock_sock(sk); + + switch (optname) { diff --git a/queue-3.18/netlink-do-not-enter-direct-reclaim-from-netlink_dump.patch b/queue-3.18/netlink-do-not-enter-direct-reclaim-from-netlink_dump.patch new file mode 100644 index 00000000000..bc1a9e01c5e --- /dev/null +++ b/queue-3.18/netlink-do-not-enter-direct-reclaim-from-netlink_dump.patch @@ -0,0 +1,76 @@ +From foo@baz Mon Feb 20 16:34:36 CET 2017 +From: Eric Dumazet +Date: Thu, 6 Oct 2016 04:13:18 +0900 +Subject: [PATCH 083/760] netlink: do not enter direct reclaim from netlink_dump() + +From: Eric Dumazet + + +[ Upstream commit d35c99ff77ecb2eb239731b799386f3b3637a31e ] + +Since linux-3.15, netlink_dump() can use up to 16384 bytes skb +allocations. + +Due to struct skb_shared_info ~320 bytes overhead, we end up using +order-3 (on x86) page allocations, that might trigger direct reclaim and +add stress. + +The intent was really to attempt a large allocation but immediately +fallback to a smaller one (order-1 on x86) in case of memory stress. + +On recent kernels (linux-4.4), we can remove __GFP_DIRECT_RECLAIM to +meet the goal. Old kernels would need to remove __GFP_WAIT + +While we are at it, since we do an order-3 allocation, allow to use +all the allocated bytes instead of 16384 to reduce syscalls during +large dumps. + +iproute2 already uses 32KB recvmsg() buffer sizes. + +Alexei provided an initial patch downsizing to SKB_WITH_OVERHEAD(16384) + +Fixes: 9063e21fb026 ("netlink: autosize skb lengthes") +Signed-off-by: Eric Dumazet +Reported-by: Alexei Starovoitov +Cc: Greg Thelen +Reviewed-by: Greg Rose +Acked-by: Alexei Starovoitov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + net/netlink/af_netlink.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -2398,7 +2398,7 @@ static int netlink_recvmsg(struct kiocb + /* Record the max length of recvmsg() calls for future allocations */ + nlk->max_recvmsg_len = max(nlk->max_recvmsg_len, len); + nlk->max_recvmsg_len = min_t(size_t, nlk->max_recvmsg_len, +- 16384); ++ SKB_WITH_OVERHEAD(32768)); + + copied = data_skb->len; + if (len < copied) { +@@ -2656,9 +2656,8 @@ static int netlink_dump(struct sock *sk) + skb = netlink_alloc_skb(sk, + nlk->max_recvmsg_len, + nlk->portid, +- GFP_KERNEL | +- __GFP_NOWARN | +- __GFP_NORETRY); ++ (GFP_KERNEL & ~__GFP_WAIT) | ++ __GFP_NOWARN | __GFP_NORETRY); + /* available room should be exact amount to avoid MSG_TRUNC */ + if (skb) + skb_reserve(skb, skb_tailroom(skb) - +@@ -2666,7 +2665,7 @@ static int netlink_dump(struct sock *sk) + } + if (!skb) + skb = netlink_alloc_skb(sk, alloc_size, nlk->portid, +- GFP_KERNEL); ++ (GFP_KERNEL & ~__GFP_WAIT)); + if (!skb) + goto errout_skb; + netlink_skb_set_owner_r(skb, sk); diff --git a/queue-3.18/packet-call-fanout_release-while-unregistering-a-netdev.patch b/queue-3.18/packet-call-fanout_release-while-unregistering-a-netdev.patch new file mode 100644 index 00000000000..8bccc606e53 --- /dev/null +++ b/queue-3.18/packet-call-fanout_release-while-unregistering-a-netdev.patch @@ -0,0 +1,37 @@ +From foo@baz Mon Feb 20 16:34:36 CET 2017 +From: Anoob Soman +Date: Wed, 5 Oct 2016 15:12:54 +0100 +Subject: [PATCH 082/760] packet: call fanout_release, while UNREGISTERING a netdev + +From: Anoob Soman + + +[ Upstream commit 6664498280cf17a59c3e7cf1a931444c02633ed1 ] + +If a socket has FANOUT sockopt set, a new proto_hook is registered +as part of fanout_add(). When processing a NETDEV_UNREGISTER event in +af_packet, __fanout_unlink is called for all sockets, but prot_hook which was +registered as part of fanout_add is not removed. Call fanout_release, on a +NETDEV_UNREGISTER, which removes prot_hook and removes fanout from the +fanout_list. + +This fixes BUG_ON(!list_empty(&dev->ptype_specific)) in netdev_run_todo() + +Signed-off-by: Anoob Soman +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + net/packet/af_packet.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -3552,6 +3552,7 @@ static int packet_notifier(struct notifi + } + if (msg == NETDEV_UNREGISTER) { + packet_cached_dev_reset(po); ++ fanout_release(sk); + po->ifindex = -1; + if (po->prot_hook.dev) + dev_put(po->prot_hook.dev); diff --git a/queue-3.18/packet-on-direct_xmit-limit-tso-and-csum-to-supported-devices.patch b/queue-3.18/packet-on-direct_xmit-limit-tso-and-csum-to-supported-devices.patch new file mode 100644 index 00000000000..e3a7150385c --- /dev/null +++ b/queue-3.18/packet-on-direct_xmit-limit-tso-and-csum-to-supported-devices.patch @@ -0,0 +1,97 @@ +From foo@baz Mon Feb 20 16:34:36 CET 2017 +From: Willem de Bruijn +Date: Wed, 26 Oct 2016 11:23:07 -0400 +Subject: [PATCH 097/760] packet: on direct_xmit, limit tso and csum to supported devices + +From: Willem de Bruijn + + +[ Upstream commit 104ba78c98808ae837d1f63aae58c183db5505df ] + +When transmitting on a packet socket with PACKET_VNET_HDR and +PACKET_QDISC_BYPASS, validate device support for features requested +in vnet_hdr. + +Drop TSO packets sent to devices that do not support TSO or have the +feature disabled. Note that the latter currently do process those +packets correctly, regardless of not advertising the feature. + +Because of SKB_GSO_DODGY, it is not sufficient to test device features +with netif_needs_gso. Full validate_xmit_skb is needed. + +Switch to software checksum for non-TSO packets that request checksum +offload if that device feature is unsupported or disabled. Note that +similar to the TSO case, device drivers may perform checksum offload +correctly even when not advertising it. + +When switching to software checksum, packets hit skb_checksum_help, +which has two BUG_ON checksum not in linear segment. Packet sockets +always allocate at least up to csum_start + csum_off + 2 as linear. + +Tested by running github.com/wdebruij/kerneltools/psock_txring_vnet.c + + ethtool -K eth0 tso off tx on + psock_txring_vnet -d $dst -s $src -i eth0 -l 2000 -n 1 -q -v + psock_txring_vnet -d $dst -s $src -i eth0 -l 2000 -n 1 -q -v -N + + ethtool -K eth0 tx off + psock_txring_vnet -d $dst -s $src -i eth0 -l 1000 -n 1 -q -v -G + psock_txring_vnet -d $dst -s $src -i eth0 -l 1000 -n 1 -q -v -G -N + +v2: + - add EXPORT_SYMBOL_GPL(validate_xmit_skb_list) + +Fixes: d346a3fae3ff ("packet: introduce PACKET_QDISC_BYPASS socket option") +Signed-off-by: Willem de Bruijn +Acked-by: Eric Dumazet +Acked-by: Daniel Borkmann +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + net/core/dev.c | 1 + + net/packet/af_packet.c | 9 ++++----- + 2 files changed, 5 insertions(+), 5 deletions(-) + +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -2741,6 +2741,7 @@ struct sk_buff *validate_xmit_skb_list(s + } + return head; + } ++EXPORT_SYMBOL_GPL(validate_xmit_skb_list); + + static void qdisc_pkt_len_init(struct sk_buff *skb) + { +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -240,7 +240,7 @@ static void __fanout_link(struct sock *s + static int packet_direct_xmit(struct sk_buff *skb) + { + struct net_device *dev = skb->dev; +- netdev_features_t features; ++ struct sk_buff *orig_skb = skb; + struct netdev_queue *txq; + int ret = NETDEV_TX_BUSY; + +@@ -248,9 +248,8 @@ static int packet_direct_xmit(struct sk_ + !netif_carrier_ok(dev))) + goto drop; + +- features = netif_skb_features(skb); +- if (skb_needs_linearize(skb, features) && +- __skb_linearize(skb)) ++ skb = validate_xmit_skb_list(skb, dev); ++ if (skb != orig_skb) + goto drop; + + txq = skb_get_tx_queue(dev, skb); +@@ -270,7 +269,7 @@ static int packet_direct_xmit(struct sk_ + return ret; + drop: + atomic_long_inc(&dev->tx_dropped); +- kfree_skb(skb); ++ kfree_skb_list(skb); + return NET_XMIT_DROP; + } + diff --git a/queue-3.18/pwm-unexport-children-before-chip-removal.patch b/queue-3.18/pwm-unexport-children-before-chip-removal.patch new file mode 100644 index 00000000000..82f07476292 --- /dev/null +++ b/queue-3.18/pwm-unexport-children-before-chip-removal.patch @@ -0,0 +1,83 @@ +From 0733424c9ba9f42242409d1ece780777272f7ea1 Mon Sep 17 00:00:00 2001 +From: David Hsu +Date: Tue, 9 Aug 2016 14:57:46 -0700 +Subject: pwm: Unexport children before chip removal + +From: David Hsu + +commit 0733424c9ba9f42242409d1ece780777272f7ea1 upstream. + +Exported pwm channels aren't removed before the pwmchip and are +leaked. This results in invalid sysfs files. This fix removes +all exported pwm channels before chip removal. + +Signed-off-by: David Hsu +Fixes: 76abbdde2d95 ("pwm: Add sysfs interface") +Signed-off-by: Thierry Reding +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pwm/core.c | 2 ++ + drivers/pwm/sysfs.c | 18 ++++++++++++++++++ + include/linux/pwm.h | 5 +++++ + 3 files changed, 25 insertions(+) + +--- a/drivers/pwm/core.c ++++ b/drivers/pwm/core.c +@@ -293,6 +293,8 @@ int pwmchip_remove(struct pwm_chip *chip + unsigned int i; + int ret = 0; + ++ pwmchip_sysfs_unexport_children(chip); ++ + mutex_lock(&pwm_lock); + + for (i = 0; i < chip->npwm; i++) { +--- a/drivers/pwm/sysfs.c ++++ b/drivers/pwm/sysfs.c +@@ -340,6 +340,24 @@ void pwmchip_sysfs_unexport(struct pwm_c + } + } + ++void pwmchip_sysfs_unexport_children(struct pwm_chip *chip) ++{ ++ struct device *parent; ++ unsigned int i; ++ ++ parent = class_find_device(&pwm_class, NULL, chip, ++ pwmchip_sysfs_match); ++ if (!parent) ++ return; ++ ++ for (i = 0; i < chip->npwm; i++) { ++ struct pwm_device *pwm = &chip->pwms[i]; ++ ++ if (test_bit(PWMF_EXPORTED, &pwm->flags)) ++ pwm_unexport_child(parent, pwm); ++ } ++} ++ + static int __init pwm_sysfs_init(void) + { + return class_register(&pwm_class); +--- a/include/linux/pwm.h ++++ b/include/linux/pwm.h +@@ -299,6 +299,7 @@ static inline void pwm_add_table(struct + #ifdef CONFIG_PWM_SYSFS + void pwmchip_sysfs_export(struct pwm_chip *chip); + void pwmchip_sysfs_unexport(struct pwm_chip *chip); ++void pwmchip_sysfs_unexport_children(struct pwm_chip *chip); + #else + static inline void pwmchip_sysfs_export(struct pwm_chip *chip) + { +@@ -307,6 +308,10 @@ static inline void pwmchip_sysfs_export( + static inline void pwmchip_sysfs_unexport(struct pwm_chip *chip) + { + } ++ ++static inline void pwmchip_sysfs_unexport_children(struct pwm_chip *chip) ++{ ++} + #endif /* CONFIG_PWM_SYSFS */ + + #endif /* __LINUX_PWM_H */ diff --git a/queue-3.18/sctp-validate-chunk-len-before-actually-using-it.patch b/queue-3.18/sctp-validate-chunk-len-before-actually-using-it.patch new file mode 100644 index 00000000000..6c93f7642fc --- /dev/null +++ b/queue-3.18/sctp-validate-chunk-len-before-actually-using-it.patch @@ -0,0 +1,59 @@ +From foo@baz Mon Feb 20 16:34:36 CET 2017 +From: Marcelo Ricardo Leitner +Date: Tue, 25 Oct 2016 14:27:39 -0200 +Subject: [PATCH 096/760] sctp: validate chunk len before actually using it + +From: Marcelo Ricardo Leitner + + +[ Upstream commit bf911e985d6bbaa328c20c3e05f4eb03de11fdd6 ] + +Andrey Konovalov reported that KASAN detected that SCTP was using a slab +beyond the boundaries. It was caused because when handling out of the +blue packets in function sctp_sf_ootb() it was checking the chunk len +only after already processing the first chunk, validating only for the +2nd and subsequent ones. + +The fix is to just move the check upwards so it's also validated for the +1st chunk. + +Reported-by: Andrey Konovalov +Tested-by: Andrey Konovalov +Signed-off-by: Marcelo Ricardo Leitner +Reviewed-by: Xin Long +Acked-by: Neil Horman +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + net/sctp/sm_statefuns.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/net/sctp/sm_statefuns.c ++++ b/net/sctp/sm_statefuns.c +@@ -3426,6 +3426,12 @@ sctp_disposition_t sctp_sf_ootb(struct n + return sctp_sf_violation_chunklen(net, ep, asoc, type, arg, + commands); + ++ /* Report violation if chunk len overflows */ ++ ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length)); ++ if (ch_end > skb_tail_pointer(skb)) ++ return sctp_sf_violation_chunklen(net, ep, asoc, type, arg, ++ commands); ++ + /* Now that we know we at least have a chunk header, + * do things that are type appropriate. + */ +@@ -3457,12 +3463,6 @@ sctp_disposition_t sctp_sf_ootb(struct n + } + } + +- /* Report violation if chunk len overflows */ +- ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length)); +- if (ch_end > skb_tail_pointer(skb)) +- return sctp_sf_violation_chunklen(net, ep, asoc, type, arg, +- commands); +- + ch = (sctp_chunkhdr_t *) ch_end; + } while (ch_end < skb_tail_pointer(skb)); + diff --git a/queue-3.18/selinux-fix-off-by-one-in-setprocattr.patch b/queue-3.18/selinux-fix-off-by-one-in-setprocattr.patch new file mode 100644 index 00000000000..d6ab3bc7170 --- /dev/null +++ b/queue-3.18/selinux-fix-off-by-one-in-setprocattr.patch @@ -0,0 +1,64 @@ +From 0c461cb727d146c9ef2d3e86214f498b78b7d125 Mon Sep 17 00:00:00 2001 +From: Stephen Smalley +Date: Tue, 31 Jan 2017 11:54:04 -0500 +Subject: selinux: fix off-by-one in setprocattr + +From: Stephen Smalley + +commit 0c461cb727d146c9ef2d3e86214f498b78b7d125 upstream. + +SELinux tries to support setting/clearing of /proc/pid/attr attributes +from the shell by ignoring terminating newlines and treating an +attribute value that begins with a NUL or newline as an attempt to +clear the attribute. However, the test for clearing attributes has +always been wrong; it has an off-by-one error, and this could further +lead to reading past the end of the allocated buffer since commit +bb646cdb12e75d82258c2f2e7746d5952d3e321a ("proc_pid_attr_write(): +switch to memdup_user()"). Fix the off-by-one error. + +Even with this fix, setting and clearing /proc/pid/attr attributes +from the shell is not straightforward since the interface does not +support multiple write() calls (so shells that write the value and +newline separately will set and then immediately clear the attribute, +requiring use of echo -n to set the attribute), whereas trying to use +echo -n "" to clear the attribute causes the shell to skip the +write() call altogether since POSIX says that a zero-length write +causes no side effects. Thus, one must use echo -n to set and echo +without -n to clear, as in the following example: +$ echo -n unconfined_u:object_r:user_home_t:s0 > /proc/$$/attr/fscreate +$ cat /proc/$$/attr/fscreate +unconfined_u:object_r:user_home_t:s0 +$ echo "" > /proc/$$/attr/fscreate +$ cat /proc/$$/attr/fscreate + +Note the use of /proc/$$ rather than /proc/self, as otherwise +the cat command will read its own attribute value, not that of the shell. + +There are no users of this facility to my knowledge; possibly we +should just get rid of it. + +UPDATE: Upon further investigation it appears that a local process +with the process:setfscreate permission can cause a kernel panic as a +result of this bug. This patch fixes CVE-2017-2618. + +Signed-off-by: Stephen Smalley +[PM: added the update about CVE-2017-2618 to the commit description] +Signed-off-by: Paul Moore +Signed-off-by: James Morris +Signed-off-by: Greg Kroah-Hartman + +--- + security/selinux/hooks.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/security/selinux/hooks.c ++++ b/security/selinux/hooks.c +@@ -5594,7 +5594,7 @@ static int selinux_setprocattr(struct ta + return error; + + /* Obtain a SID for the context, if one was specified. */ +- if (size && str[1] && str[1] != '\n') { ++ if (size && str[0] && str[0] != '\n') { + if (str[size-1] == '\n') { + str[size-1] = 0; + size--; diff --git a/queue-3.18/series b/queue-3.18/series index fc445ebdcdb..a4459f9f94f 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -11,5 +11,35 @@ sit-fix-a-double-free-on-error-path.patch ping-fix-a-null-pointer-dereference.patch l2tp-do-not-use-udp_ioctl.patch ip6_gre-fix-ip6gre_err-invalid-reads.patch +ipv6-tcp-restore-ip6cb-for-pktoptions-skbs.patch ipv6-tcp-add-a-missing-tcp_v6_restore_cb.patch tcp-avoid-infinite-loop-in-tcp_splice_read.patch +iommu-vt-d-fix-iommu-lookup-for-sr-iov-virtual-functions.patch +usb-chipidea-move-the-lock-initialization-to-core-file.patch +tcp-fix-overflow-in-__tcp_retransmit_skb.patch +android-binder-add-strong-ref-checks.patch +android-binder-clear-binder-and-cookie-when-setting-handle-in-flat-binder-struct.patch +alsa-usb-audio-add-quirk-for-syntek-stk1160.patch +fix-potential-infoleak-in-older-kernels.patch +tty-vt-fix-bogus-division-in-csi_j.patch +arm-8584-1-floppy-avoid-gcc-6-warning.patch +drm-exynos-fix-error-handling-in-exynos_drm_subdrv_open.patch +smc91x-avoid-self-comparison-warning.patch +ubi-fastmap-scrub-peb-when-bitflips-are-detected-in-a-free-peb-ec-header.patch +pwm-unexport-children-before-chip-removal.patch +hid-usbhid-add-aten-cs962-to-list-of-quirky-devices.patch +selinux-fix-off-by-one-in-setprocattr.patch +fbdev-color-map-copying-bounds-checking.patch +tcp-fix-wrong-checksum-calculation-on-mtu-probing.patch +tcp-fix-a-compile-error-in-dbgundo.patch +ip6_gre-fix-flowi6_proto-value-in-ip6gre_xmit_other.patch +ipmr-ip6mr-fix-scheduling-while-atomic-and-a-deadlock-with-ipmr_get_route.patch +net-add-netdev-all_adj_list-refcnt-propagation-to-fix-panic.patch +packet-call-fanout_release-while-unregistering-a-netdev.patch +ipv6-correctly-add-local-routes-when-lo-goes-up.patch +net-pktgen-remove-rcu-locking-in-pktgen_change_name.patch +ipv4-disable-bh-in-set_ping_group_range.patch +net-sctp-forbid-negative-length.patch +sctp-validate-chunk-len-before-actually-using-it.patch +packet-on-direct_xmit-limit-tso-and-csum-to-supported-devices.patch +netlink-do-not-enter-direct-reclaim-from-netlink_dump.patch diff --git a/queue-3.18/smc91x-avoid-self-comparison-warning.patch b/queue-3.18/smc91x-avoid-self-comparison-warning.patch new file mode 100644 index 00000000000..ec1118a32e2 --- /dev/null +++ b/queue-3.18/smc91x-avoid-self-comparison-warning.patch @@ -0,0 +1,43 @@ +From e3ebd894f084255fde19116955ba7054858ff5d6 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Mon, 14 Mar 2016 23:45:12 +0100 +Subject: smc91x: avoid self-comparison warning + +From: Arnd Bergmann + +commit e3ebd894f084255fde19116955ba7054858ff5d6 upstream. + +The smc91x driver defines a macro that compares its argument to +itself, apparently to get a true result while using its argument +to avoid a warning about unused local variables. + +Unfortunately, this triggers a warning with gcc-6, as the comparison +is obviously useless: + +drivers/net/ethernet/smsc/smc91x.c: In function 'smc_hardware_send_pkt': +drivers/net/ethernet/smsc/smc91x.c:563:14: error: self-comparison always evaluates to true [-Werror=tautological-compare] + if (!smc_special_trylock(&lp->lock, flags)) { + +This replaces the macro with another one that behaves similarly, +with a cast to (void) to ensure the argument is used, and using +a literal 'true' as its value. + +Signed-off-by: Arnd Bergmann +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/ethernet/smsc/smc91x.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/smsc/smc91x.c ++++ b/drivers/net/ethernet/smsc/smc91x.c +@@ -535,7 +535,7 @@ static inline void smc_rcv(struct net_d + #define smc_special_lock(lock, flags) spin_lock_irqsave(lock, flags) + #define smc_special_unlock(lock, flags) spin_unlock_irqrestore(lock, flags) + #else +-#define smc_special_trylock(lock, flags) (flags == flags) ++#define smc_special_trylock(lock, flags) ((void)flags, true) + #define smc_special_lock(lock, flags) do { flags = 0; } while (0) + #define smc_special_unlock(lock, flags) do { flags = 0; } while (0) + #endif diff --git a/queue-3.18/tcp-fix-a-compile-error-in-dbgundo.patch b/queue-3.18/tcp-fix-a-compile-error-in-dbgundo.patch new file mode 100644 index 00000000000..d86b869ca1a --- /dev/null +++ b/queue-3.18/tcp-fix-a-compile-error-in-dbgundo.patch @@ -0,0 +1,36 @@ +From foo@baz Mon Feb 20 16:34:36 CET 2017 +From: Eric Dumazet +Date: Thu, 22 Sep 2016 17:54:00 -0700 +Subject: [PATCH 074/760] tcp: fix a compile error in DBGUNDO() + +From: Eric Dumazet + + +[ Upstream commit 019b1c9fe32a2a32c1153e31375f87ec3e591273 ] + +If DBGUNDO() is enabled (FASTRETRANS_DEBUG > 1), a compile +error will happen, since inet6_sk(sk)->daddr became sk->sk_v6_daddr + +Fixes: efe4208f47f9 ("ipv6: make lookups simpler and faster") +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp_input.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -2360,10 +2360,9 @@ static void DBGUNDO(struct sock *sk, con + } + #if IS_ENABLED(CONFIG_IPV6) + else if (sk->sk_family == AF_INET6) { +- struct ipv6_pinfo *np = inet6_sk(sk); + pr_debug("Undo %s %pI6/%u c%u l%u ss%u/%u p%u\n", + msg, +- &np->daddr, ntohs(inet->inet_dport), ++ &sk->sk_v6_daddr, ntohs(inet->inet_dport), + tp->snd_cwnd, tcp_left_out(tp), + tp->snd_ssthresh, tp->prior_ssthresh, + tp->packets_out); diff --git a/queue-3.18/tcp-fix-overflow-in-__tcp_retransmit_skb.patch b/queue-3.18/tcp-fix-overflow-in-__tcp_retransmit_skb.patch new file mode 100644 index 00000000000..a29cec2b848 --- /dev/null +++ b/queue-3.18/tcp-fix-overflow-in-__tcp_retransmit_skb.patch @@ -0,0 +1,39 @@ +From ffb4d6c8508657824bcef68a36b2a0f9d8c09d10 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Thu, 15 Sep 2016 08:12:33 -0700 +Subject: tcp: fix overflow in __tcp_retransmit_skb() + +From: Eric Dumazet + +commit ffb4d6c8508657824bcef68a36b2a0f9d8c09d10 upstream. + +If a TCP socket gets a large write queue, an overflow can happen +in a test in __tcp_retransmit_skb() preventing all retransmits. + +The flow then stalls and resets after timeouts. + +Tested: + +sysctl -w net.core.wmem_max=1000000000 +netperf -H dest -- -s 1000000000 + +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/ipv4/tcp_output.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -2481,7 +2481,8 @@ int __tcp_retransmit_skb(struct sock *sk + * copying overhead: fragmentation, tunneling, mangling etc. + */ + if (atomic_read(&sk->sk_wmem_alloc) > +- min(sk->sk_wmem_queued + (sk->sk_wmem_queued >> 2), sk->sk_sndbuf)) ++ min_t(u32, sk->sk_wmem_queued + (sk->sk_wmem_queued >> 2), ++ sk->sk_sndbuf)) + return -EAGAIN; + + if (skb_still_in_host_queue(sk, skb)) diff --git a/queue-3.18/tcp-fix-wrong-checksum-calculation-on-mtu-probing.patch b/queue-3.18/tcp-fix-wrong-checksum-calculation-on-mtu-probing.patch new file mode 100644 index 00000000000..cb8f091ebe3 --- /dev/null +++ b/queue-3.18/tcp-fix-wrong-checksum-calculation-on-mtu-probing.patch @@ -0,0 +1,52 @@ +From foo@baz Mon Feb 20 16:34:36 CET 2017 +From: Douglas Caetano dos Santos +Date: Thu, 22 Sep 2016 15:52:04 -0300 +Subject: [PATCH 073/760] tcp: fix wrong checksum calculation on MTU probing + +From: Douglas Caetano dos Santos + + +[ Upstream commit 2fe664f1fcf7c4da6891f95708a7a56d3c024354 ] + +With TCP MTU probing enabled and offload TX checksumming disabled, +tcp_mtu_probe() calculated the wrong checksum when a fragment being copied +into the probe's SKB had an odd length. This was caused by the direct use +of skb_copy_and_csum_bits() to calculate the checksum, as it pads the +fragment being copied, if needed. When this fragment was not the last, a +subsequent call used the previous checksum without considering this +padding. + +The effect was a stale connection in one way, as even retransmissions +wouldn't solve the problem, because the checksum was never recalculated for +the full SKB length. + +Signed-off-by: Douglas Caetano dos Santos +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp_output.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -1869,12 +1869,14 @@ static int tcp_mtu_probe(struct sock *sk + len = 0; + tcp_for_write_queue_from_safe(skb, next, sk) { + copy = min_t(int, skb->len, probe_size - len); +- if (nskb->ip_summed) ++ if (nskb->ip_summed) { + skb_copy_bits(skb, 0, skb_put(nskb, copy), copy); +- else +- nskb->csum = skb_copy_and_csum_bits(skb, 0, +- skb_put(nskb, copy), +- copy, nskb->csum); ++ } else { ++ __wsum csum = skb_copy_and_csum_bits(skb, 0, ++ skb_put(nskb, copy), ++ copy, 0); ++ nskb->csum = csum_block_add(nskb->csum, csum, len); ++ } + + if (skb->len <= copy) { + /* We've eaten all the data from this skb. diff --git a/queue-3.18/tty-vt-fix-bogus-division-in-csi_j.patch b/queue-3.18/tty-vt-fix-bogus-division-in-csi_j.patch new file mode 100644 index 00000000000..a7efbf0ac77 --- /dev/null +++ b/queue-3.18/tty-vt-fix-bogus-division-in-csi_j.patch @@ -0,0 +1,39 @@ +From 42acfc6615f47e465731c263bee0c799edb098f2 Mon Sep 17 00:00:00 2001 +From: Jiri Slaby +Date: Mon, 3 Oct 2016 11:00:17 +0200 +Subject: tty: vt, fix bogus division in csi_J +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jiri Slaby + +commit 42acfc6615f47e465731c263bee0c799edb098f2 upstream. + +In csi_J(3), the third parameter of scr_memsetw (vc_screenbuf_size) is +divided by 2 inappropriatelly. But scr_memsetw expects size, not +count, because it divides the size by 2 on its own before doing actual +memset-by-words. + +So remove the bogus division. + +Signed-off-by: Jiri Slaby +Cc: Petr Písař +Fixes: f8df13e0a9 (tty: Clean console safely) +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/vt/vt.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/tty/vt/vt.c ++++ b/drivers/tty/vt/vt.c +@@ -1169,7 +1169,7 @@ static void csi_J(struct vc_data *vc, in + break; + case 3: /* erase scroll-back buffer (and whole display) */ + scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char, +- vc->vc_screenbuf_size >> 1); ++ vc->vc_screenbuf_size); + set_origin(vc); + if (CON_IS_VISIBLE(vc)) + update_screen(vc); diff --git a/queue-3.18/ubi-fastmap-scrub-peb-when-bitflips-are-detected-in-a-free-peb-ec-header.patch b/queue-3.18/ubi-fastmap-scrub-peb-when-bitflips-are-detected-in-a-free-peb-ec-header.patch new file mode 100644 index 00000000000..419742019d1 --- /dev/null +++ b/queue-3.18/ubi-fastmap-scrub-peb-when-bitflips-are-detected-in-a-free-peb-ec-header.patch @@ -0,0 +1,40 @@ +From ecbfa8eabae9cd73522d1d3d15869703c263d859 Mon Sep 17 00:00:00 2001 +From: Boris Brezillon +Date: Fri, 16 Sep 2016 16:59:12 +0200 +Subject: UBI: fastmap: scrub PEB when bitflips are detected in a free PEB EC header + +From: Boris Brezillon + +commit ecbfa8eabae9cd73522d1d3d15869703c263d859 upstream. + +scan_pool() does not mark the PEB for scrubing when bitflips are +detected in the EC header of a free PEB (VID header region left to +0xff). +Make sure we scrub the PEB in this case. + +Signed-off-by: Boris Brezillon +Fixes: dbb7d2a88d2a ("UBI: Add fastmap core") +Signed-off-by: Richard Weinberger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mtd/ubi/fastmap.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/drivers/mtd/ubi/fastmap.c ++++ b/drivers/mtd/ubi/fastmap.c +@@ -446,10 +446,11 @@ static int scan_pool(struct ubi_device * + unsigned long long ec = be64_to_cpu(ech->ec); + unmap_peb(ai, pnum); + dbg_bld("Adding PEB to free: %i", pnum); ++ + if (err == UBI_IO_FF_BITFLIPS) +- add_aeb(ai, free, pnum, ec, 1); +- else +- add_aeb(ai, free, pnum, ec, 0); ++ scrub = 1; ++ ++ add_aeb(ai, free, pnum, ec, scrub); + continue; + } else if (err == 0 || err == UBI_IO_BITFLIPS) { + dbg_bld("Found non empty PEB:%i in pool", pnum); diff --git a/queue-3.18/usb-chipidea-move-the-lock-initialization-to-core-file.patch b/queue-3.18/usb-chipidea-move-the-lock-initialization-to-core-file.patch new file mode 100644 index 00000000000..5e1e74587c1 --- /dev/null +++ b/queue-3.18/usb-chipidea-move-the-lock-initialization-to-core-file.patch @@ -0,0 +1,139 @@ +From a5d906bb261cde5f881a949d3b0fbaa285dcc574 Mon Sep 17 00:00:00 2001 +From: Peter Chen +Date: Tue, 15 Nov 2016 18:05:33 +0800 +Subject: usb: chipidea: move the lock initialization to core file + +From: Peter Chen + +commit a5d906bb261cde5f881a949d3b0fbaa285dcc574 upstream. + +This can fix below dump when the lock is accessed at host +mode due to it is not initialized. + +[ 46.119638] INFO: trying to register non-static key. +[ 46.124643] the code is fine but needs lockdep annotation. +[ 46.130144] turning off the locking correctness validator. +[ 46.135659] CPU: 0 PID: 690 Comm: cat Not tainted 4.9.0-rc3-00079-g4b75f1d #1210 +[ 46.143075] Hardware name: Freescale i.MX6 SoloX (Device Tree) +[ 46.148923] Backtrace: +[ 46.151448] [] (dump_backtrace) from [] (show_stack+0x18/0x1c) +[ 46.159038] r7:edf52000 +[ 46.161412] r6:60000193 +[ 46.163967] r5:00000000 +[ 46.165035] r4:c0e25c2c + +[ 46.169109] [] (show_stack) from [] (dump_stack+0xb4/0xe8) +[ 46.176362] [] (dump_stack) from [] (register_lock_class+0x4fc/0x56c) +[ 46.184554] r10:c0e25d24 +[ 46.187014] r9:edf53e70 +[ 46.189569] r8:c1642444 +[ 46.190637] r7:ee9da024 +[ 46.193191] r6:00000000 +[ 46.194258] r5:00000000 +[ 46.196812] r4:00000000 +[ 46.199185] r3:00000001 + +[ 46.203259] [] (register_lock_class) from [] (__lock_acquire+0x80/0x10f0) +[ 46.211797] r10:c0e25d24 +[ 46.214257] r9:edf53e70 +[ 46.216813] r8:ee9da024 +[ 46.217880] r7:c1642444 +[ 46.220435] r6:edcd1800 +[ 46.221502] r5:60000193 +[ 46.224057] r4:00000000 + +[ 46.227953] [] (__lock_acquire) from [] (lock_acquire+0x74/0x94) +[ 46.235710] r10:00000001 +[ 46.238169] r9:edf53e70 +[ 46.240723] r8:edf53f80 +[ 46.241790] r7:00000001 +[ 46.244344] r6:00000001 +[ 46.245412] r5:60000193 +[ 46.247966] r4:00000000 + +[ 46.251866] [] (lock_acquire) from [] (_raw_spin_lock_irqsave+0x40/0x54) +[ 46.260319] r7:ee1c6a00 +[ 46.262691] r6:c062a570 +[ 46.265247] r5:20000113 +[ 46.266314] r4:ee9da014 + +[ 46.270393] [] (_raw_spin_lock_irqsave) from [] (ci_port_test_show+0x2c/0x70) +[ 46.279280] r6:eebd2000 +[ 46.281652] r5:ee9da010 +[ 46.284207] r4:ee9da014 + +[ 46.286810] [] (ci_port_test_show) from [] (seq_read+0x1ac/0x4f8) +[ 46.294655] r9:edf53e70 +[ 46.297028] r8:edf53f80 +[ 46.299583] r7:ee1c6a00 +[ 46.300650] r6:00000001 +[ 46.303205] r5:00000000 +[ 46.304273] r4:eebd2000 +[ 46.306850] [] (seq_read) from [] (full_proxy_read+0x54/0x6c) +[ 46.314348] r10:00000000 +[ 46.316808] r9:c0a6ad30 +[ 46.319363] r8:edf53f80 +[ 46.320430] r7:00020000 +[ 46.322986] r6:b6de3000 +[ 46.324053] r5:ee1c6a00 +[ 46.326607] r4:c0248b58 + +[ 46.330505] [] (full_proxy_read) from [] (__vfs_read+0x34/0x118) +[ 46.338262] r9:edf52000 +[ 46.340635] r8:c0107fc4 +[ 46.343190] r7:00020000 +[ 46.344257] r6:edf53f80 +[ 46.346812] r5:c039e810 +[ 46.347879] r4:ee1c6a00 +[ 46.350447] [] (__vfs_read) from [] (vfs_read+0x8c/0x11c) +[ 46.357597] r9:edf52000 +[ 46.359969] r8:c0107fc4 +[ 46.362524] r7:edf53f80 +[ 46.363592] r6:b6de3000 +[ 46.366147] r5:ee1c6a00 +[ 46.367214] r4:00020000 +[ 46.369782] [] (vfs_read) from [] (SyS_read+0x4c/0xa8) +[ 46.376672] r8:c0107fc4 +[ 46.379045] r7:00020000 +[ 46.381600] r6:b6de3000 +[ 46.382667] r5:ee1c6a00 +[ 46.385222] r4:ee1c6a00 + +[ 46.387817] [] (SyS_read) from [] (ret_fast_syscall+0x0/0x1c) +[ 46.395314] r7:00000003 +[ 46.397687] r6:b6de3000 +[ 46.400243] r5:00020000 +[ 46.401310] r4:00020000 + +Fixes: 26c696c678c4 ("USB: Chipidea: rename struct + ci13xxx variables from udc to ci") +Signed-off-by: Peter Chen +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/chipidea/core.c | 1 + + drivers/usb/chipidea/udc.c | 2 -- + 2 files changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/usb/chipidea/core.c ++++ b/drivers/usb/chipidea/core.c +@@ -594,6 +594,7 @@ static int ci_hdrc_probe(struct platform + return -ENOMEM; + } + ++ spin_lock_init(&ci->lock); + ci->dev = dev; + ci->platdata = dev_get_platdata(dev); + ci->imx28_write_fix = !!(ci->platdata->flags & +--- a/drivers/usb/chipidea/udc.c ++++ b/drivers/usb/chipidea/udc.c +@@ -1798,8 +1798,6 @@ static int udc_start(struct ci_hdrc *ci) + struct device *dev = ci->dev; + int retval = 0; + +- spin_lock_init(&ci->lock); +- + ci->gadget.ops = &usb_gadget_ops; + ci->gadget.speed = USB_SPEED_UNKNOWN; + ci->gadget.max_speed = USB_SPEED_HIGH; -- 2.47.3