From: Greg Kroah-Hartman Date: Wed, 24 Feb 2016 03:22:57 +0000 (-0800) Subject: 3.10-stable patches X-Git-Tag: v3.10.98~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8571f9c0622d4addf985c735a883ce53387f6727;p=thirdparty%2Fkernel%2Fstable-queue.git 3.10-stable patches added patches: aio-properly-check-iovec-sizes.patch alsa-seq-fix-double-port-list-deletion.patch arm-8517-1-icst-avoid-arithmetic-overflow-in-icst_hz.patch arm-8519-1-icst-try-other-dividends-than-1.patch btrfs-fix-hang-on-extent-buffer-lock-caused-by-the-inode_paths-ioctl.patch cifs-fix-erroneous-return-value.patch dma-debug-switch-check-from-_text-to-_stext.patch drivers-scsi-sg.c-mark-vma-as-vm_io-to-prevent-migration.patch ext4-fix-potential-integer-overflow.patch fix-a-memory-leak-in-scsi_host_dev_release.patch fuse-break-infinite-loop-in-fuse_fill_write_pages.patch futex-drop-refcount-if-requeue_pi-acquired-the-rtmutex.patch iio-ad5064-make-sure-ad5064_i2c_write-returns-0-on-success.patch iio-ad7793-fix-ad7785-product-id.patch iio-adis_buffer-fix-out-of-bounds-memory-access.patch iio-dac-mcp4725-set-iio-name-property-in-sysfs.patch iio-lpc32xx_adc-fix-warnings-caused-by-enabling-unprepared-clock.patch input-elantech-add-fujitsu-lifebook-u745-to-force-crc_enabled.patch input-elantech-mark-protocols-v2-and-v3-as-semi-mt.patch input-i8042-add-fujitsu-lifebook-u745-to-the-nomux-list.patch intel_scu_ipcutil-underflow-in-scu_reg_access.patch iommu-vt-d-fix-64-bit-accesses-to-32-bit-dmar_gsts_reg.patch ip6mr-call-del_timer_sync-in-ip6mr_free_table.patch iscsi-target-fix-potential-dead-lock-during-node-acl-delete.patch iscsi-target-fix-rx_login_comp-hang-after-login-failure.patch klist-fix-starting-point-removed-bug-in-klist-iterators.patch m32r-fix-m32104ut_defconfig-build-fail.patch memcg-only-free-spare-array-when-readers-are-done.patch mm-memory_hotplug.c-check-for-missing-sections-in-test_pages_in_a_zone.patch mm-soft-offline-check-return-value-in-second-__get_any_page-call.patch module-wrapper-for-symbol-name.patch nfs-fix-race-in-__update_open_stateid.patch perf-fix-inherited-events-vs.-tracepoint-filters.patch ptrace-use-fsuid-fsgid-effective-creds-for-fs-access-checks.patch pty-fix-possible-use-after-free-of-tty-driver_data.patch pty-make-sure-super_block-is-still-valid-in-final-dev-tty-close.patch radix-tree-fix-oops-after-radix_tree_iter_retry.patch radix-tree-fix-race-in-gang-lookup.patch scripts-bloat-o-meter-fix-python3-syntax-error.patch scsi-fix-crashes-in-sd-and-sr-runtime-pm.patch scsi-fix-null-pointer-dereference-in-runtime-pm.patch scsi-fix-soft-lockup-in-scsi_remove_target-on-module-removal.patch scsi-restart-list-search-after-unlock-in-scsi_remove_target.patch scsi_dh_rdac-always-retry-mode-select-on-command-lock-violation.patch scsi_sysfs-fix-queue_ramp_up_period-return-code.patch staging-speakup-use-tty_ldisc_ref-for-paste-kworker.patch tools-lib-traceevent-fix-output-of-llu-for-64-bit-values-read-on-32-bit-machines.patch tracing-fix-freak-link-error-caused-by-branch-tracer.patch udf-check-output-buffer-length-when-converting-name-to-cs0.patch udf-limit-the-maximum-number-of-indirect-extents-in-a-row.patch udf-prevent-buffer-overrun-with-multi-byte-characters.patch wan-x25-fix-use-after-free-in-x25_asy_open_tty.patch x86-asm-irq-stop-relying-on-magic-jmp-behavior-for-early_idt_handlers.patch xhci-fix-list-corruption-in-urb-dequeue-at-host-removal.patch --- diff --git a/queue-3.10/aio-properly-check-iovec-sizes.patch b/queue-3.10/aio-properly-check-iovec-sizes.patch new file mode 100644 index 00000000000..54e929e45d9 --- /dev/null +++ b/queue-3.10/aio-properly-check-iovec-sizes.patch @@ -0,0 +1,48 @@ +From greg@kroah.com Fri Feb 19 17:36:28 2016 +From: Greg KH +Date: Fri, 19 Feb 2016 17:36:21 -0800 +Subject: AIO: properly check iovec sizes + +From: Greg Kroah-Hartman + +In Linus's tree, the iovec code has been reworked massively, but in +older kernels the AIO layer should be checking this before passing the +request on to other layers. + +Many thanks to Ben Hawkes of Google Project Zero for pointing out the +issue. + +Reported-by: Ben Hawkes +Acked-by: Benjamin LaHaise +Tested-by: Willy Tarreau +[backported to 3.10 - willy] +Signed-off-by: Greg Kroah-Hartman + + +--- + fs/aio.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +--- a/fs/aio.c ++++ b/fs/aio.c +@@ -977,12 +977,17 @@ static ssize_t aio_setup_vectored_rw(int + + static ssize_t aio_setup_single_vector(int rw, struct kiocb *kiocb) + { +- if (unlikely(!access_ok(!rw, kiocb->ki_buf, kiocb->ki_nbytes))) +- return -EFAULT; ++ size_t len = kiocb->ki_nbytes; ++ ++ if (len > MAX_RW_COUNT) ++ len = MAX_RW_COUNT; ++ ++ if (unlikely(!access_ok(!rw, kiocb->ki_buf, len))) ++ return -EFAULT; + + kiocb->ki_iovec = &kiocb->ki_inline_vec; + kiocb->ki_iovec->iov_base = kiocb->ki_buf; +- kiocb->ki_iovec->iov_len = kiocb->ki_nbytes; ++ kiocb->ki_iovec->iov_len = len; + kiocb->ki_nr_segs = 1; + return 0; + } diff --git a/queue-3.10/alsa-seq-fix-double-port-list-deletion.patch b/queue-3.10/alsa-seq-fix-double-port-list-deletion.patch new file mode 100644 index 00000000000..e939029dde9 --- /dev/null +++ b/queue-3.10/alsa-seq-fix-double-port-list-deletion.patch @@ -0,0 +1,60 @@ +From 13d5e5d4725c64ec06040d636832e78453f477b7 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 16 Feb 2016 14:15:59 +0100 +Subject: ALSA: seq: Fix double port list deletion + +From: Takashi Iwai + +commit 13d5e5d4725c64ec06040d636832e78453f477b7 upstream. + +The commit [7f0973e973cd: ALSA: seq: Fix lockdep warnings due to +double mutex locks] split the management of two linked lists (source +and destination) into two individual calls for avoiding the AB/BA +deadlock. However, this may leave the possible double deletion of one +of two lists when the counterpart is being deleted concurrently. +It ends up with a list corruption, as revealed by syzkaller fuzzer. + +This patch fixes it by checking the list emptiness and skipping the +deletion and the following process. + +BugLink: http://lkml.kernel.org/r/CACT4Y+bay9qsrz6dQu31EcGaH9XwfW7o3oBzSQUG9fMszoh=Sg@mail.gmail.com +Fixes: 7f0973e973cd ('ALSA: seq: Fix lockdep warnings due to 'double mutex locks) +Reported-by: Dmitry Vyukov +Tested-by: Dmitry Vyukov +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/core/seq/seq_ports.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +--- a/sound/core/seq/seq_ports.c ++++ b/sound/core/seq/seq_ports.c +@@ -540,19 +540,22 @@ static void delete_and_unsubscribe_port( + bool is_src, bool ack) + { + struct snd_seq_port_subs_info *grp; ++ struct list_head *list; ++ bool empty; + + grp = is_src ? &port->c_src : &port->c_dest; ++ list = is_src ? &subs->src_list : &subs->dest_list; + down_write(&grp->list_mutex); + write_lock_irq(&grp->list_lock); +- if (is_src) +- list_del(&subs->src_list); +- else +- list_del(&subs->dest_list); ++ empty = list_empty(list); ++ if (!empty) ++ list_del_init(list); + grp->exclusive = 0; + write_unlock_irq(&grp->list_lock); + up_write(&grp->list_mutex); + +- unsubscribe_port(client, port, grp, &subs->info, ack); ++ if (!empty) ++ unsubscribe_port(client, port, grp, &subs->info, ack); + } + + /* connect two ports */ diff --git a/queue-3.10/arm-8517-1-icst-avoid-arithmetic-overflow-in-icst_hz.patch b/queue-3.10/arm-8517-1-icst-avoid-arithmetic-overflow-in-icst_hz.patch new file mode 100644 index 00000000000..05cf77d7d24 --- /dev/null +++ b/queue-3.10/arm-8517-1-icst-avoid-arithmetic-overflow-in-icst_hz.patch @@ -0,0 +1,74 @@ +From 5070fb14a0154f075c8b418e5bc58a620ae85a45 Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Mon, 8 Feb 2016 09:14:37 +0100 +Subject: ARM: 8517/1: ICST: avoid arithmetic overflow in icst_hz() + +From: Linus Walleij + +commit 5070fb14a0154f075c8b418e5bc58a620ae85a45 upstream. + +When trying to set the ICST 307 clock to 25174000 Hz I ran into +this arithmetic error: the icst_hz_to_vco() correctly figure out +DIVIDE=2, RDW=100 and VDW=99 yielding a frequency of +25174000 Hz out of the VCO. (I replicated the icst_hz() function +in a spreadsheet to verify this.) + +However, when I called icst_hz() on these VCO settings it would +instead return 4122709 Hz. This causes an error in the common +clock driver for ICST as the common clock framework will call +.round_rate() on the clock which will utilize icst_hz_to_vco() +followed by icst_hz() suggesting the erroneous frequency, and +then the clock gets set to this. + +The error did not manifest in the old clock framework since +this high frequency was only used by the CLCD, which calls +clk_set_rate() without first calling clk_round_rate() and since +the old clock framework would not call clk_round_rate() before +setting the frequency, the correct values propagated into +the VCO. + +After some experimenting I figured out that it was due to a simple +arithmetic overflow: the divisor for 24Mhz reference frequency +as reference becomes 24000000*2*(99+8)=0x132212400 and the "1" +in bit 32 overflows and is lost. + +But introducing an explicit 64-by-32 bit do_div() and casting +the divisor into (u64) we get the right frequency back, and the +right frequency gets set. + +Tested on the ARM Versatile. + +Cc: linux-clk@vger.kernel.org +Cc: Pawel Moll +Signed-off-by: Linus Walleij +Signed-off-by: Russell King +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/common/icst.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/arch/arm/common/icst.c ++++ b/arch/arm/common/icst.c +@@ -16,7 +16,7 @@ + */ + #include + #include +- ++#include + #include + + /* +@@ -29,7 +29,11 @@ EXPORT_SYMBOL(icst525_s2div); + + unsigned long icst_hz(const struct icst_params *p, struct icst_vco vco) + { +- return p->ref * 2 * (vco.v + 8) / ((vco.r + 2) * p->s2div[vco.s]); ++ u64 dividend = p->ref * 2 * (u64)(vco.v + 8); ++ u32 divisor = (vco.r + 2) * p->s2div[vco.s]; ++ ++ do_div(dividend, divisor); ++ return (unsigned long)dividend; + } + + EXPORT_SYMBOL(icst_hz); diff --git a/queue-3.10/arm-8519-1-icst-try-other-dividends-than-1.patch b/queue-3.10/arm-8519-1-icst-try-other-dividends-than-1.patch new file mode 100644 index 00000000000..0084d920466 --- /dev/null +++ b/queue-3.10/arm-8519-1-icst-try-other-dividends-than-1.patch @@ -0,0 +1,38 @@ +From e972c37459c813190461dabfeaac228e00aae259 Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Wed, 10 Feb 2016 09:25:17 +0100 +Subject: ARM: 8519/1: ICST: try other dividends than 1 + +From: Linus Walleij + +commit e972c37459c813190461dabfeaac228e00aae259 upstream. + +Since the dawn of time the ICST code has only supported divide +by one or hang in an eternal loop. Luckily we were always dividing +by one because the reference frequency for the systems using +the ICSTs is 24MHz and the [min,max] values for the PLL input +if [10,320] MHz for ICST307 and [6,200] for ICST525, so the loop +will always terminate immediately without assigning any divisor +for the reference frequency. + +But for the code to make sense, let's insert the missing i++ + +Reported-by: David Binderman +Signed-off-by: Linus Walleij +Signed-off-by: Russell King +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/common/icst.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/arm/common/icst.c ++++ b/arch/arm/common/icst.c +@@ -58,6 +58,7 @@ icst_hz_to_vco(const struct icst_params + + if (f > p->vco_min && f <= p->vco_max) + break; ++ i++; + } while (i < 8); + + if (i >= 8) diff --git a/queue-3.10/btrfs-fix-hang-on-extent-buffer-lock-caused-by-the-inode_paths-ioctl.patch b/queue-3.10/btrfs-fix-hang-on-extent-buffer-lock-caused-by-the-inode_paths-ioctl.patch new file mode 100644 index 00000000000..451df171b30 --- /dev/null +++ b/queue-3.10/btrfs-fix-hang-on-extent-buffer-lock-caused-by-the-inode_paths-ioctl.patch @@ -0,0 +1,181 @@ +From 0c0fe3b0fa45082cd752553fdb3a4b42503a118e Mon Sep 17 00:00:00 2001 +From: Filipe Manana +Date: Wed, 3 Feb 2016 19:17:27 +0000 +Subject: Btrfs: fix hang on extent buffer lock caused by the inode_paths ioctl + +From: Filipe Manana + +commit 0c0fe3b0fa45082cd752553fdb3a4b42503a118e upstream. + +While doing some tests I ran into an hang on an extent buffer's rwlock +that produced the following trace: + +[39389.800012] NMI watchdog: BUG: soft lockup - CPU#15 stuck for 22s! [fdm-stress:32166] +[39389.800016] NMI watchdog: BUG: soft lockup - CPU#14 stuck for 22s! [fdm-stress:32165] +[39389.800016] Modules linked in: btrfs dm_mod ppdev xor sha256_generic hmac raid6_pq drbg ansi_cprng aesni_intel i2c_piix4 acpi_cpufreq aes_x86_64 ablk_helper tpm_tis parport_pc i2c_core sg cryptd evdev psmouse lrw tpm parport gf128mul serio_raw pcspkr glue_helper processor button loop autofs4 ext4 crc16 mbcache jbd2 sd_mod sr_mod cdrom ata_generic virtio_scsi ata_piix libata virtio_pci virtio_ring crc32c_intel scsi_mod e1000 virtio floppy [last unloaded: btrfs] +[39389.800016] irq event stamp: 0 +[39389.800016] hardirqs last enabled at (0): [< (null)>] (null) +[39389.800016] hardirqs last disabled at (0): [] copy_process+0x638/0x1a35 +[39389.800016] softirqs last enabled at (0): [] copy_process+0x638/0x1a35 +[39389.800016] softirqs last disabled at (0): [< (null)>] (null) +[39389.800016] CPU: 14 PID: 32165 Comm: fdm-stress Not tainted 4.4.0-rc6-btrfs-next-18+ #1 +[39389.800016] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS by qemu-project.org 04/01/2014 +[39389.800016] task: ffff880175b1ca40 ti: ffff8800a185c000 task.ti: ffff8800a185c000 +[39389.800016] RIP: 0010:[] [] queued_spin_lock_slowpath+0x57/0x158 +[39389.800016] RSP: 0018:ffff8800a185fb80 EFLAGS: 00000202 +[39389.800016] RAX: 0000000000000101 RBX: ffff8801710c4e9c RCX: 0000000000000101 +[39389.800016] RDX: 0000000000000100 RSI: 0000000000000001 RDI: 0000000000000001 +[39389.800016] RBP: ffff8800a185fb98 R08: 0000000000000001 R09: 0000000000000000 +[39389.800016] R10: ffff8800a185fb68 R11: 6db6db6db6db6db7 R12: ffff8801710c4e98 +[39389.800016] R13: ffff880175b1ca40 R14: ffff8800a185fc10 R15: ffff880175b1ca40 +[39389.800016] FS: 00007f6d37fff700(0000) GS:ffff8802be9c0000(0000) knlGS:0000000000000000 +[39389.800016] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[39389.800016] CR2: 00007f6d300019b8 CR3: 0000000037c93000 CR4: 00000000001406e0 +[39389.800016] Stack: +[39389.800016] ffff8801710c4e98 ffff8801710c4e98 ffff880175b1ca40 ffff8800a185fbb0 +[39389.800016] ffffffff81091e11 ffff8801710c4e98 ffff8800a185fbc8 ffffffff81091895 +[39389.800016] ffff8801710c4e98 ffff8800a185fbe8 ffffffff81486c5c ffffffffa067288c +[39389.800016] Call Trace: +[39389.800016] [] queued_read_lock_slowpath+0x46/0x60 +[39389.800016] [] do_raw_read_lock+0x3e/0x41 +[39389.800016] [] _raw_read_lock+0x3d/0x44 +[39389.800016] [] ? btrfs_tree_read_lock+0x54/0x125 [btrfs] +[39389.800016] [] btrfs_tree_read_lock+0x54/0x125 [btrfs] +[39389.800016] [] ? btrfs_find_item+0xa7/0xd2 [btrfs] +[39389.800016] [] btrfs_ref_to_path+0xd6/0x174 [btrfs] +[39389.800016] [] inode_to_path+0x53/0xa2 [btrfs] +[39389.800016] [] paths_from_inode+0x117/0x2ec [btrfs] +[39389.800016] [] btrfs_ioctl+0xd5b/0x2793 [btrfs] +[39389.800016] [] ? arch_local_irq_save+0x9/0xc +[39389.800016] [] ? __this_cpu_preempt_check+0x13/0x15 +[39389.800016] [] ? arch_local_irq_save+0x9/0xc +[39389.800016] [] ? rcu_read_unlock+0x3e/0x5d +[39389.800016] [] do_vfs_ioctl+0x42b/0x4ea +[39389.800016] [] ? __fget_light+0x62/0x71 +[39389.800016] [] SyS_ioctl+0x57/0x79 +[39389.800016] [] entry_SYSCALL_64_fastpath+0x12/0x6f +[39389.800016] Code: b9 01 01 00 00 f7 c6 00 ff ff ff 75 32 83 fe 01 89 ca 89 f0 0f 45 d7 f0 0f b1 13 39 f0 74 04 89 c6 eb e2 ff ca 0f 84 fa 00 00 00 <8b> 03 84 c0 74 04 f3 90 eb f6 66 c7 03 01 00 e9 e6 00 00 00 e8 +[39389.800012] Modules linked in: btrfs dm_mod ppdev xor sha256_generic hmac raid6_pq drbg ansi_cprng aesni_intel i2c_piix4 acpi_cpufreq aes_x86_64 ablk_helper tpm_tis parport_pc i2c_core sg cryptd evdev psmouse lrw tpm parport gf128mul serio_raw pcspkr glue_helper processor button loop autofs4 ext4 crc16 mbcache jbd2 sd_mod sr_mod cdrom ata_generic virtio_scsi ata_piix libata virtio_pci virtio_ring crc32c_intel scsi_mod e1000 virtio floppy [last unloaded: btrfs] +[39389.800012] irq event stamp: 0 +[39389.800012] hardirqs last enabled at (0): [< (null)>] (null) +[39389.800012] hardirqs last disabled at (0): [] copy_process+0x638/0x1a35 +[39389.800012] softirqs last enabled at (0): [] copy_process+0x638/0x1a35 +[39389.800012] softirqs last disabled at (0): [< (null)>] (null) +[39389.800012] CPU: 15 PID: 32166 Comm: fdm-stress Tainted: G L 4.4.0-rc6-btrfs-next-18+ #1 +[39389.800012] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS by qemu-project.org 04/01/2014 +[39389.800012] task: ffff880179294380 ti: ffff880034a60000 task.ti: ffff880034a60000 +[39389.800012] RIP: 0010:[] [] queued_write_lock_slowpath+0x62/0x72 +[39389.800012] RSP: 0018:ffff880034a639f0 EFLAGS: 00000206 +[39389.800012] RAX: 0000000000000101 RBX: ffff8801710c4e98 RCX: 0000000000000000 +[39389.800012] RDX: 00000000000000ff RSI: 0000000000000000 RDI: ffff8801710c4e9c +[39389.800012] RBP: ffff880034a639f8 R08: 0000000000000001 R09: 0000000000000000 +[39389.800012] R10: ffff880034a639b0 R11: 0000000000001000 R12: ffff8801710c4e98 +[39389.800012] R13: 0000000000000001 R14: ffff880172cbc000 R15: ffff8801710c4e00 +[39389.800012] FS: 00007f6d377fe700(0000) GS:ffff8802be9e0000(0000) knlGS:0000000000000000 +[39389.800012] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[39389.800012] CR2: 00007f6d3d3c1000 CR3: 0000000037c93000 CR4: 00000000001406e0 +[39389.800012] Stack: +[39389.800012] ffff8801710c4e98 ffff880034a63a10 ffffffff81091963 ffff8801710c4e98 +[39389.800012] ffff880034a63a30 ffffffff81486f1b ffffffffa0672cb3 ffff8801710c4e00 +[39389.800012] ffff880034a63a78 ffffffffa0672cb3 ffff8801710c4e00 ffff880034a63a58 +[39389.800012] Call Trace: +[39389.800012] [] do_raw_write_lock+0x72/0x8c +[39389.800012] [] _raw_write_lock+0x3a/0x41 +[39389.800012] [] ? btrfs_tree_lock+0x119/0x251 [btrfs] +[39389.800012] [] btrfs_tree_lock+0x119/0x251 [btrfs] +[39389.800012] [] ? rcu_read_unlock+0x5b/0x5d [btrfs] +[39389.800012] [] ? btrfs_root_node+0xda/0xe6 [btrfs] +[39389.800012] [] btrfs_lock_root_node+0x22/0x42 [btrfs] +[39389.800012] [] btrfs_search_slot+0x1b8/0x758 [btrfs] +[39389.800012] [] ? time_hardirqs_on+0x15/0x28 +[39389.800012] [] btrfs_lookup_inode+0x31/0x95 [btrfs] +[39389.800012] [] ? trace_hardirqs_on+0xd/0xf +[39389.800012] [] ? mutex_lock_nested+0x397/0x3bc +[39389.800012] [] __btrfs_update_delayed_inode+0x59/0x1c0 [btrfs] +[39389.800012] [] __btrfs_commit_inode_delayed_items+0x194/0x5aa [btrfs] +[39389.800012] [] ? _raw_spin_unlock+0x31/0x44 +[39389.800012] [] __btrfs_run_delayed_items+0xa4/0x15c [btrfs] +[39389.800012] [] btrfs_run_delayed_items+0x11/0x13 [btrfs] +[39389.800012] [] btrfs_commit_transaction+0x234/0x96e [btrfs] +[39389.800012] [] btrfs_sync_fs+0x145/0x1ad [btrfs] +[39389.800012] [] btrfs_ioctl+0x11d2/0x2793 [btrfs] +[39389.800012] [] ? arch_local_irq_save+0x9/0xc +[39389.800012] [] ? __might_fault+0x4c/0xa7 +[39389.800012] [] ? __might_fault+0x4c/0xa7 +[39389.800012] [] ? arch_local_irq_save+0x9/0xc +[39389.800012] [] ? rcu_read_unlock+0x3e/0x5d +[39389.800012] [] do_vfs_ioctl+0x42b/0x4ea +[39389.800012] [] ? __fget_light+0x62/0x71 +[39389.800012] [] SyS_ioctl+0x57/0x79 +[39389.800012] [] entry_SYSCALL_64_fastpath+0x12/0x6f +[39389.800012] Code: f0 0f b1 13 85 c0 75 ef eb 2a f3 90 8a 03 84 c0 75 f8 f0 0f b0 13 84 c0 75 f0 ba ff 00 00 00 eb 0a f0 0f b1 13 ff c8 74 0b f3 90 <8b> 03 83 f8 01 75 f7 eb ed c6 43 04 00 5b 5d c3 0f 1f 44 00 00 + +This happens because in the code path executed by the inode_paths ioctl we +end up nesting two calls to read lock a leaf's rwlock when after the first +call to read_lock() and before the second call to read_lock(), another +task (running the delayed items as part of a transaction commit) has +already called write_lock() against the leaf's rwlock. This situation is +illustrated by the following diagram: + + Task A Task B + + btrfs_ref_to_path() btrfs_commit_transaction() + read_lock(&eb->lock); + + btrfs_run_delayed_items() + __btrfs_commit_inode_delayed_items() + __btrfs_update_delayed_inode() + btrfs_lookup_inode() + + write_lock(&eb->lock); + --> task waits for lock + + read_lock(&eb->lock); + --> makes this task hang + forever (and task B too + of course) + +So fix this by avoiding doing the nested read lock, which is easily +avoidable. This issue does not happen if task B calls write_lock() after +task A does the second call to read_lock(), however there does not seem +to exist anything in the documentation that mentions what is the expected +behaviour for recursive locking of rwlocks (leaving the idea that doing +so is not a good usage of rwlocks). + +Also, as a side effect necessary for this fix, make sure we do not +needlessly read lock extent buffers when the input path has skip_locking +set (used when called from send). + +Signed-off-by: Filipe Manana +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/backref.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/fs/btrfs/backref.c ++++ b/fs/btrfs/backref.c +@@ -1228,7 +1228,8 @@ char *btrfs_ref_to_path(struct btrfs_roo + read_extent_buffer(eb, dest + bytes_left, + name_off, name_len); + if (eb != eb_in) { +- btrfs_tree_read_unlock_blocking(eb); ++ if (!path->skip_locking) ++ btrfs_tree_read_unlock_blocking(eb); + free_extent_buffer(eb); + } + ret = inode_ref_info(parent, 0, fs_root, path, &found_key); +@@ -1247,9 +1248,10 @@ char *btrfs_ref_to_path(struct btrfs_roo + eb = path->nodes[0]; + /* make sure we can use eb after releasing the path */ + if (eb != eb_in) { +- atomic_inc(&eb->refs); +- btrfs_tree_read_lock(eb); +- btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK); ++ if (!path->skip_locking) ++ btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK); ++ path->nodes[0] = NULL; ++ path->locks[0] = 0; + } + btrfs_release_path(path); + iref = btrfs_item_ptr(eb, slot, struct btrfs_inode_ref); diff --git a/queue-3.10/cifs-fix-erroneous-return-value.patch b/queue-3.10/cifs-fix-erroneous-return-value.patch new file mode 100644 index 00000000000..99041c1652c --- /dev/null +++ b/queue-3.10/cifs-fix-erroneous-return-value.patch @@ -0,0 +1,31 @@ +From 4b550af519854421dfec9f7732cdddeb057134b2 Mon Sep 17 00:00:00 2001 +From: Anton Protopopov +Date: Wed, 10 Feb 2016 12:50:21 -0500 +Subject: cifs: fix erroneous return value + +From: Anton Protopopov + +commit 4b550af519854421dfec9f7732cdddeb057134b2 upstream. + +The setup_ntlmv2_rsp() function may return positive value ENOMEM instead +of -ENOMEM in case of kmalloc failure. + +Signed-off-by: Anton Protopopov +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/cifsencrypt.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/cifs/cifsencrypt.c ++++ b/fs/cifs/cifsencrypt.c +@@ -591,7 +591,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, c + + ses->auth_key.response = kmalloc(baselen + tilen, GFP_KERNEL); + if (!ses->auth_key.response) { +- rc = ENOMEM; ++ rc = -ENOMEM; + ses->auth_key.len = 0; + goto setup_ntlmv2_rsp_ret; + } diff --git a/queue-3.10/dma-debug-switch-check-from-_text-to-_stext.patch b/queue-3.10/dma-debug-switch-check-from-_text-to-_stext.patch new file mode 100644 index 00000000000..a9d1adc64a3 --- /dev/null +++ b/queue-3.10/dma-debug-switch-check-from-_text-to-_stext.patch @@ -0,0 +1,48 @@ +From ea535e418c01837d07b6c94e817540f50bfdadb0 Mon Sep 17 00:00:00 2001 +From: Laura Abbott +Date: Thu, 14 Jan 2016 15:16:50 -0800 +Subject: dma-debug: switch check from _text to _stext + +From: Laura Abbott + +commit ea535e418c01837d07b6c94e817540f50bfdadb0 upstream. + +In include/asm-generic/sections.h: + + /* + * Usage guidelines: + * _text, _data: architecture specific, don't use them in + * arch-independent code + * [_stext, _etext]: contains .text.* sections, may also contain + * .rodata.* + * and/or .init.* sections + +_text is not guaranteed across architectures. Architectures such as ARM +may reuse parts which are not actually text and erroneously trigger a bug. +Switch to using _stext which is guaranteed to contain text sections. + +Came out of https://lkml.kernel.org/g/<567B1176.4000106@redhat.com> + +Signed-off-by: Laura Abbott +Reviewed-by: Kees Cook +Cc: Russell King +Cc: Arnd Bergmann +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + lib/dma-debug.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/lib/dma-debug.c ++++ b/lib/dma-debug.c +@@ -962,7 +962,7 @@ static inline bool overlap(void *addr, u + + static void check_for_illegal_area(struct device *dev, void *addr, unsigned long len) + { +- if (overlap(addr, len, _text, _etext) || ++ if (overlap(addr, len, _stext, _etext) || + overlap(addr, len, __start_rodata, __end_rodata)) + err_printk(dev, NULL, "DMA-API: device driver maps memory from kernel text or rodata [addr=%p] [len=%lu]\n", addr, len); + } diff --git a/queue-3.10/drivers-scsi-sg.c-mark-vma-as-vm_io-to-prevent-migration.patch b/queue-3.10/drivers-scsi-sg.c-mark-vma-as-vm_io-to-prevent-migration.patch new file mode 100644 index 00000000000..1e2dda6d2aa --- /dev/null +++ b/queue-3.10/drivers-scsi-sg.c-mark-vma-as-vm_io-to-prevent-migration.patch @@ -0,0 +1,68 @@ +From 461c7fa126794157484dca48e88effa4963e3af3 Mon Sep 17 00:00:00 2001 +From: "Kirill A. Shutemov" +Date: Tue, 2 Feb 2016 16:57:35 -0800 +Subject: drivers/scsi/sg.c: mark VMA as VM_IO to prevent migration + +From: Kirill A. Shutemov + +commit 461c7fa126794157484dca48e88effa4963e3af3 upstream. + +Reduced testcase: + + #include + #include + #include + #include + + #define SIZE 0x2000 + + int main() + { + int fd; + void *p; + + fd = open("/dev/sg0", O_RDWR); + p = mmap(NULL, SIZE, PROT_EXEC, MAP_PRIVATE | MAP_LOCKED, fd, 0); + mbind(p, SIZE, 0, NULL, 0, MPOL_MF_MOVE); + return 0; + } + +We shouldn't try to migrate pages in sg VMA as we don't have a way to +update Sg_scatter_hold::pages accordingly from mm core. + +Let's mark the VMA as VM_IO to indicate to mm core that the VMA is not +migratable. + +Signed-off-by: Kirill A. Shutemov +Reported-by: Dmitry Vyukov +Acked-by: Vlastimil Babka +Cc: Doug Gilbert +Cc: David Rientjes +Cc: Naoya Horiguchi +Cc: "Kirill A. Shutemov" +Cc: Shiraz Hashim +Cc: Hugh Dickins +Cc: Sasha Levin +Cc: syzkaller +Cc: Kostya Serebryany +Cc: Alexander Potapenko +Cc: James Bottomley +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/sg.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/scsi/sg.c ++++ b/drivers/scsi/sg.c +@@ -1258,7 +1258,7 @@ sg_mmap(struct file *filp, struct vm_are + } + + sfp->mmap_called = 1; +- vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP; ++ vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP; + vma->vm_private_data = sfp; + vma->vm_ops = &sg_mmap_vm_ops; + return 0; diff --git a/queue-3.10/ext4-fix-potential-integer-overflow.patch b/queue-3.10/ext4-fix-potential-integer-overflow.patch new file mode 100644 index 00000000000..47c38bb543b --- /dev/null +++ b/queue-3.10/ext4-fix-potential-integer-overflow.patch @@ -0,0 +1,32 @@ +From 46901760b46064964b41015d00c140c83aa05bcf Mon Sep 17 00:00:00 2001 +From: Insu Yun +Date: Fri, 12 Feb 2016 01:15:59 -0500 +Subject: ext4: fix potential integer overflow + +From: Insu Yun + +commit 46901760b46064964b41015d00c140c83aa05bcf upstream. + +Since sizeof(ext_new_group_data) > sizeof(ext_new_flex_group_data), +integer overflow could be happened. +Therefore, need to fix integer overflow sanitization. + +Signed-off-by: Insu Yun +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/resize.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/ext4/resize.c ++++ b/fs/ext4/resize.c +@@ -181,7 +181,7 @@ static struct ext4_new_flex_group_data * + if (flex_gd == NULL) + goto out3; + +- if (flexbg_size >= UINT_MAX / sizeof(struct ext4_new_flex_group_data)) ++ if (flexbg_size >= UINT_MAX / sizeof(struct ext4_new_group_data)) + goto out2; + flex_gd->count = flexbg_size; + diff --git a/queue-3.10/fix-a-memory-leak-in-scsi_host_dev_release.patch b/queue-3.10/fix-a-memory-leak-in-scsi_host_dev_release.patch new file mode 100644 index 00000000000..c4a48bffdaa --- /dev/null +++ b/queue-3.10/fix-a-memory-leak-in-scsi_host_dev_release.patch @@ -0,0 +1,76 @@ +From b49493f99690c8eaacfbc635bafaad629ea2c036 Mon Sep 17 00:00:00 2001 +From: Bart Van Assche +Date: Wed, 18 Nov 2015 14:56:36 -0800 +Subject: Fix a memory leak in scsi_host_dev_release() + +From: Bart Van Assche + +commit b49493f99690c8eaacfbc635bafaad629ea2c036 upstream. + +Avoid that kmemleak reports the following memory leak if a +SCSI LLD calls scsi_host_alloc() and scsi_host_put() but neither +scsi_host_add() nor scsi_host_remove(). The following shell +command triggers that scenario: + +for ((i=0; i<2; i++)); do + srp_daemon -oac | + while read line; do + echo $line >/sys/class/infiniband_srp/srp-mlx4_0-1/add_target + done +done + +unreferenced object 0xffff88021b24a220 (size 8): + comm "srp_daemon", pid 56421, jiffies 4295006762 (age 4240.750s) + hex dump (first 8 bytes): + 68 6f 73 74 35 38 00 a5 host58.. + backtrace: + [] kmemleak_alloc+0x7a/0xc0 + [] __kmalloc_track_caller+0xfe/0x160 + [] kvasprintf+0x5b/0x90 + [] kvasprintf_const+0x8d/0xb0 + [] kobject_set_name_vargs+0x3c/0xa0 + [] dev_set_name+0x3c/0x40 + [] scsi_host_alloc+0x327/0x4b0 + [] srp_create_target+0x4e/0x8a0 [ib_srp] + [] dev_attr_store+0x1b/0x20 + [] sysfs_kf_write+0x4a/0x60 + [] kernfs_fop_write+0x14e/0x180 + [] __vfs_write+0x2f/0xf0 + [] vfs_write+0xa4/0x100 + [] SyS_write+0x54/0xc0 + [] entry_SYSCALL_64_fastpath+0x12/0x6f + +Signed-off-by: Bart Van Assche +Reviewed-by: Christoph Hellwig +Reviewed-by: Johannes Thumshirn +Reviewed-by: Sagi Grimberg +Reviewed-by: Lee Duncan +Cc: Christoph Hellwig +Cc: Hannes Reinecke +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/hosts.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/drivers/scsi/hosts.c ++++ b/drivers/scsi/hosts.c +@@ -305,6 +305,17 @@ static void scsi_host_dev_release(struct + kfree(queuedata); + } + ++ if (shost->shost_state == SHOST_CREATED) { ++ /* ++ * Free the shost_dev device name here if scsi_host_alloc() ++ * and scsi_host_put() have been called but neither ++ * scsi_host_add() nor scsi_host_remove() has been called. ++ * This avoids that the memory allocated for the shost_dev ++ * name is leaked. ++ */ ++ kfree(dev_name(&shost->shost_dev)); ++ } ++ + scsi_destroy_command_freelist(shost); + if (shost->bqt) + blk_free_tags(shost->bqt); diff --git a/queue-3.10/fuse-break-infinite-loop-in-fuse_fill_write_pages.patch b/queue-3.10/fuse-break-infinite-loop-in-fuse_fill_write_pages.patch new file mode 100644 index 00000000000..979e4c5ea2a --- /dev/null +++ b/queue-3.10/fuse-break-infinite-loop-in-fuse_fill_write_pages.patch @@ -0,0 +1,61 @@ +From 3ca8138f014a913f98e6ef40e939868e1e9ea876 Mon Sep 17 00:00:00 2001 +From: Roman Gushchin +Date: Mon, 12 Oct 2015 16:33:44 +0300 +Subject: fuse: break infinite loop in fuse_fill_write_pages() + +From: Roman Gushchin + +commit 3ca8138f014a913f98e6ef40e939868e1e9ea876 upstream. + +I got a report about unkillable task eating CPU. Further +investigation shows, that the problem is in the fuse_fill_write_pages() +function. If iov's first segment has zero length, we get an infinite +loop, because we never reach iov_iter_advance() call. + +Fix this by calling iov_iter_advance() before repeating an attempt to +copy data from userspace. + +A similar problem is described in 124d3b7041f ("fix writev regression: +pan hanging unkillable and un-straceable"). If zero-length segmend +is followed by segment with invalid address, +iov_iter_fault_in_readable() checks only first segment (zero-length), +iov_iter_copy_from_user_atomic() skips it, fails at second and +returns zero -> goto again without skipping zero-length segment. + +Patch calls iov_iter_advance() before goto again: we'll skip zero-length +segment at second iteraction and iov_iter_fault_in_readable() will detect +invalid address. + +Special thanks to Konstantin Khlebnikov, who helped a lot with the commit +description. + +Cc: Andrew Morton +Cc: Maxim Patlasov +Cc: Konstantin Khlebnikov +Signed-off-by: Roman Gushchin +Signed-off-by: Miklos Szeredi +Fixes: ea9b9907b82a ("fuse: implement perform_write") +Signed-off-by: Greg Kroah-Hartman + +--- + fs/fuse/file.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/fuse/file.c ++++ b/fs/fuse/file.c +@@ -993,6 +993,7 @@ static ssize_t fuse_fill_write_pages(str + + mark_page_accessed(page); + ++ iov_iter_advance(ii, tmp); + if (!tmp) { + unlock_page(page); + page_cache_release(page); +@@ -1005,7 +1006,6 @@ static ssize_t fuse_fill_write_pages(str + req->page_descs[req->num_pages].length = tmp; + req->num_pages++; + +- iov_iter_advance(ii, tmp); + count += tmp; + pos += tmp; + offset += tmp; diff --git a/queue-3.10/futex-drop-refcount-if-requeue_pi-acquired-the-rtmutex.patch b/queue-3.10/futex-drop-refcount-if-requeue_pi-acquired-the-rtmutex.patch new file mode 100644 index 00000000000..eeec417cb57 --- /dev/null +++ b/queue-3.10/futex-drop-refcount-if-requeue_pi-acquired-the-rtmutex.patch @@ -0,0 +1,43 @@ +From fb75a4282d0d9a3c7c44d940582c2d226cf3acfb Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +Date: Sat, 19 Dec 2015 20:07:38 +0000 +Subject: futex: Drop refcount if requeue_pi() acquired the rtmutex + +From: Thomas Gleixner + +commit fb75a4282d0d9a3c7c44d940582c2d226cf3acfb upstream. + +If the proxy lock in the requeue loop acquires the rtmutex for a +waiter then it acquired also refcount on the pi_state related to the +futex, but the waiter side does not drop the reference count. + +Add the missing free_pi_state() call. + +Signed-off-by: Thomas Gleixner +Cc: Peter Zijlstra +Cc: Darren Hart +Cc: Davidlohr Bueso +Cc: Bhuvanesh_Surachari@mentor.com +Cc: Andy Lowe +Link: http://lkml.kernel.org/r/20151219200607.178132067@linutronix.de +Signed-off-by: Thomas Gleixner +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/futex.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -2494,6 +2494,11 @@ static int futex_wait_requeue_pi(u32 __u + if (q.pi_state && (q.pi_state->owner != current)) { + spin_lock(q.lock_ptr); + ret = fixup_pi_state_owner(uaddr2, &q, current); ++ /* ++ * Drop the reference to the pi state which ++ * the requeue_pi() code acquired for us. ++ */ ++ free_pi_state(q.pi_state); + spin_unlock(q.lock_ptr); + } + } else { diff --git a/queue-3.10/iio-ad5064-make-sure-ad5064_i2c_write-returns-0-on-success.patch b/queue-3.10/iio-ad5064-make-sure-ad5064_i2c_write-returns-0-on-success.patch new file mode 100644 index 00000000000..2e56f09e182 --- /dev/null +++ b/queue-3.10/iio-ad5064-make-sure-ad5064_i2c_write-returns-0-on-success.patch @@ -0,0 +1,44 @@ +From 03fe472ef33b7f31fbd11d300dbb3fdab9c00fd4 Mon Sep 17 00:00:00 2001 +From: Michael Hennerich +Date: Tue, 13 Oct 2015 18:15:37 +0200 +Subject: iio:ad5064: Make sure ad5064_i2c_write() returns 0 on success + +From: Michael Hennerich + +commit 03fe472ef33b7f31fbd11d300dbb3fdab9c00fd4 upstream. + +i2c_master_send() returns the number of bytes transferred on success while +the ad5064 driver expects that the write() callback returns 0 on success. +Fix that by translating any non negative return value of i2c_master_send() +to 0. + +Fixes: commit 6a17a0768f77 ("iio:dac:ad5064: Add support for the ad5629r and ad5669r") +Signed-off-by: Michael Hennerich +Signed-off-by: Lars-Peter Clausen +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iio/dac/ad5064.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/drivers/iio/dac/ad5064.c ++++ b/drivers/iio/dac/ad5064.c +@@ -602,10 +602,16 @@ static int ad5064_i2c_write(struct ad506 + unsigned int addr, unsigned int val) + { + struct i2c_client *i2c = to_i2c_client(st->dev); ++ int ret; + + st->data.i2c[0] = (cmd << 4) | addr; + put_unaligned_be16(val, &st->data.i2c[1]); +- return i2c_master_send(i2c, st->data.i2c, 3); ++ ++ ret = i2c_master_send(i2c, st->data.i2c, 3); ++ if (ret < 0) ++ return ret; ++ ++ return 0; + } + + static int ad5064_i2c_probe(struct i2c_client *i2c, diff --git a/queue-3.10/iio-ad7793-fix-ad7785-product-id.patch b/queue-3.10/iio-ad7793-fix-ad7785-product-id.patch new file mode 100644 index 00000000000..fa8c01cddcc --- /dev/null +++ b/queue-3.10/iio-ad7793-fix-ad7785-product-id.patch @@ -0,0 +1,35 @@ +From 785171fd6cd7dcd7ada5a733b6a2d44ec566c3a0 Mon Sep 17 00:00:00 2001 +From: Lars-Peter Clausen +Date: Mon, 12 Oct 2015 14:56:28 +0200 +Subject: iio:ad7793: Fix ad7785 product ID + +From: Lars-Peter Clausen + +commit 785171fd6cd7dcd7ada5a733b6a2d44ec566c3a0 upstream. + +While the datasheet for the AD7785 lists 0xXB as the product ID the actual +product ID is 0xX3. + +Fix the product ID otherwise the driver will reject the device due to non +matching IDs. + +Fixes: e786cc26dcc5 ("staging:iio:ad7793: Implement stricter id checking") +Signed-off-by: Lars-Peter Clausen +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iio/adc/ad7793.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/iio/adc/ad7793.c ++++ b/drivers/iio/adc/ad7793.c +@@ -101,7 +101,7 @@ + #define AD7795_CH_AIN1M_AIN1M 8 /* AIN1(-) - AIN1(-) */ + + /* ID Register Bit Designations (AD7793_REG_ID) */ +-#define AD7785_ID 0xB ++#define AD7785_ID 0x3 + #define AD7792_ID 0xA + #define AD7793_ID 0xB + #define AD7794_ID 0xF diff --git a/queue-3.10/iio-adis_buffer-fix-out-of-bounds-memory-access.patch b/queue-3.10/iio-adis_buffer-fix-out-of-bounds-memory-access.patch new file mode 100644 index 00000000000..94e426695b3 --- /dev/null +++ b/queue-3.10/iio-adis_buffer-fix-out-of-bounds-memory-access.patch @@ -0,0 +1,40 @@ +From d590faf9e8f8509a0a0aa79c38e87fcc6b913248 Mon Sep 17 00:00:00 2001 +From: Lars-Peter Clausen +Date: Fri, 27 Nov 2015 14:55:56 +0100 +Subject: iio: adis_buffer: Fix out-of-bounds memory access + +From: Lars-Peter Clausen + +commit d590faf9e8f8509a0a0aa79c38e87fcc6b913248 upstream. + +The SPI tx and rx buffers are both supposed to be scan_bytes amount of +bytes large and a common allocation is used to allocate both buffers. This +puts the beginning of the tx buffer scan_bytes bytes after the rx buffer. +The initialization of the tx buffer pointer is done adding scan_bytes to +the beginning of the rx buffer, but since the rx buffer is of type __be16 +this will actually add two times as much and the tx buffer ends up pointing +after the allocated buffer. + +Fix this by using scan_count, which is scan_bytes / 2, instead of +scan_bytes when initializing the tx buffer pointer. + +Fixes: aacff892cbd5 ("staging:iio:adis: Preallocate transfer message") +Signed-off-by: Lars-Peter Clausen +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iio/imu/adis_buffer.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/iio/imu/adis_buffer.c ++++ b/drivers/iio/imu/adis_buffer.c +@@ -43,7 +43,7 @@ int adis_update_scan_mode(struct iio_dev + return -ENOMEM; + + rx = adis->buffer; +- tx = rx + indio_dev->scan_bytes; ++ tx = rx + scan_count; + + spi_message_init(&adis->msg); + diff --git a/queue-3.10/iio-dac-mcp4725-set-iio-name-property-in-sysfs.patch b/queue-3.10/iio-dac-mcp4725-set-iio-name-property-in-sysfs.patch new file mode 100644 index 00000000000..19b472cae99 --- /dev/null +++ b/queue-3.10/iio-dac-mcp4725-set-iio-name-property-in-sysfs.patch @@ -0,0 +1,32 @@ +From 97a249e98a72d6b79fb7350a8dd56b147e9d5bdb Mon Sep 17 00:00:00 2001 +From: Yong Li +Date: Wed, 6 Jan 2016 09:09:43 +0800 +Subject: iio: dac: mcp4725: set iio name property in sysfs + +From: Yong Li + +commit 97a249e98a72d6b79fb7350a8dd56b147e9d5bdb upstream. + +Without this change, the name entity for mcp4725 is missing in +/sys/bus/iio/devices/iio\:device*/name + +With this change, name is reported correctly + +Signed-off-by: Yong Li +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iio/dac/mcp4725.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/iio/dac/mcp4725.c ++++ b/drivers/iio/dac/mcp4725.c +@@ -166,6 +166,7 @@ static int mcp4725_probe(struct i2c_clie + data->client = client; + + indio_dev->dev.parent = &client->dev; ++ indio_dev->name = id->name; + indio_dev->info = &mcp4725_info; + indio_dev->channels = &mcp4725_channel; + indio_dev->num_channels = 1; diff --git a/queue-3.10/iio-lpc32xx_adc-fix-warnings-caused-by-enabling-unprepared-clock.patch b/queue-3.10/iio-lpc32xx_adc-fix-warnings-caused-by-enabling-unprepared-clock.patch new file mode 100644 index 00000000000..655447a4e48 --- /dev/null +++ b/queue-3.10/iio-lpc32xx_adc-fix-warnings-caused-by-enabling-unprepared-clock.patch @@ -0,0 +1,70 @@ +From 01bb70ae0b98d266fa3e860482c7ce22fa482a6e Mon Sep 17 00:00:00 2001 +From: Vladimir Zapolskiy +Date: Sat, 17 Oct 2015 21:44:38 +0300 +Subject: iio: lpc32xx_adc: fix warnings caused by enabling unprepared clock + +From: Vladimir Zapolskiy + +commit 01bb70ae0b98d266fa3e860482c7ce22fa482a6e upstream. + +If common clock framework is configured, the driver generates a warning, +which is fixed by this change: + + root@devkit3250:~# cat /sys/bus/iio/devices/iio\:device0/in_voltage0_raw + ------------[ cut here ]------------ + WARNING: CPU: 0 PID: 724 at drivers/clk/clk.c:727 clk_core_enable+0x2c/0xa4() + Modules linked in: sc16is7xx snd_soc_uda1380 + CPU: 0 PID: 724 Comm: cat Not tainted 4.3.0-rc2+ #198 + Hardware name: LPC32XX SoC (Flattened Device Tree) + Backtrace: + [<>] (dump_backtrace) from [<>] (show_stack+0x18/0x1c) + [<>] (show_stack) from [<>] (dump_stack+0x20/0x28) + [<>] (dump_stack) from [<>] (warn_slowpath_common+0x90/0xb8) + [<>] (warn_slowpath_common) from [<>] (warn_slowpath_null+0x24/0x2c) + [<>] (warn_slowpath_null) from [<>] (clk_core_enable+0x2c/0xa4) + [<>] (clk_core_enable) from [<>] (clk_enable+0x24/0x38) + [<>] (clk_enable) from [<>] (lpc32xx_read_raw+0x38/0x80) + [<>] (lpc32xx_read_raw) from [<>] (iio_read_channel_info+0x70/0x94) + [<>] (iio_read_channel_info) from [<>] (dev_attr_show+0x28/0x4c) + [<>] (dev_attr_show) from [<>] (sysfs_kf_seq_show+0x8c/0xf0) + [<>] (sysfs_kf_seq_show) from [<>] (kernfs_seq_show+0x2c/0x30) + [<>] (kernfs_seq_show) from [<>] (seq_read+0x1c8/0x440) + [<>] (seq_read) from [<>] (kernfs_fop_read+0x38/0x170) + [<>] (kernfs_fop_read) from [<>] (do_readv_writev+0x16c/0x238) + [<>] (do_readv_writev) from [<>] (vfs_readv+0x50/0x58) + [<>] (vfs_readv) from [<>] (default_file_splice_read+0x1a4/0x308) + [<>] (default_file_splice_read) from [<>] (do_splice_to+0x78/0x84) + [<>] (do_splice_to) from [<>] (splice_direct_to_actor+0xc8/0x1cc) + [<>] (splice_direct_to_actor) from [<>] (do_splice_direct+0xa0/0xb8) + [<>] (do_splice_direct) from [<>] (do_sendfile+0x1a8/0x30c) + [<>] (do_sendfile) from [<>] (SyS_sendfile64+0x104/0x10c) + [<>] (SyS_sendfile64) from [<>] (ret_fast_syscall+0x0/0x38) + +Signed-off-by: Vladimir Zapolskiy +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/iio/adc/lpc32xx_adc.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/staging/iio/adc/lpc32xx_adc.c ++++ b/drivers/staging/iio/adc/lpc32xx_adc.c +@@ -76,7 +76,7 @@ static int lpc32xx_read_raw(struct iio_d + + if (mask == IIO_CHAN_INFO_RAW) { + mutex_lock(&indio_dev->mlock); +- clk_enable(info->clk); ++ clk_prepare_enable(info->clk); + /* Measurement setup */ + __raw_writel(AD_INTERNAL | (chan->address) | AD_REFp | AD_REFm, + LPC32XX_ADC_SELECT(info->adc_base)); +@@ -84,7 +84,7 @@ static int lpc32xx_read_raw(struct iio_d + __raw_writel(AD_PDN_CTRL | AD_STROBE, + LPC32XX_ADC_CTRL(info->adc_base)); + wait_for_completion(&info->completion); /* set by ISR */ +- clk_disable(info->clk); ++ clk_disable_unprepare(info->clk); + *val = info->value; + mutex_unlock(&indio_dev->mlock); + diff --git a/queue-3.10/input-elantech-add-fujitsu-lifebook-u745-to-force-crc_enabled.patch b/queue-3.10/input-elantech-add-fujitsu-lifebook-u745-to-force-crc_enabled.patch new file mode 100644 index 00000000000..d2f7579a32c --- /dev/null +++ b/queue-3.10/input-elantech-add-fujitsu-lifebook-u745-to-force-crc_enabled.patch @@ -0,0 +1,37 @@ +From 60603950f836ef4e88daddf61a273b91e671db2d Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Fri, 6 Nov 2015 11:26:01 -0800 +Subject: Input: elantech - add Fujitsu Lifebook U745 to force crc_enabled + +From: Takashi Iwai + +commit 60603950f836ef4e88daddf61a273b91e671db2d upstream. + +Another Lifebook machine that needs the same quirk as other similar +models to make the driver working. + +Bugzilla: https://bugzilla.opensuse.org/show_bug.cgi?id=883192 +Signed-off-by: Takashi Iwai +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/input/mouse/elantech.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/input/mouse/elantech.c ++++ b/drivers/input/mouse/elantech.c +@@ -1357,6 +1357,13 @@ static const struct dmi_system_id no_hw_ + DMI_MATCH(DMI_PRODUCT_NAME, "U2442"), + }, + }, ++ { ++ /* Fujitsu LIFEBOOK U745 does not work with crc_enabled == 0 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U745"), ++ }, ++ }, + #endif + { } + }; diff --git a/queue-3.10/input-elantech-mark-protocols-v2-and-v3-as-semi-mt.patch b/queue-3.10/input-elantech-mark-protocols-v2-and-v3-as-semi-mt.patch new file mode 100644 index 00000000000..52deb2d7a89 --- /dev/null +++ b/queue-3.10/input-elantech-mark-protocols-v2-and-v3-as-semi-mt.patch @@ -0,0 +1,41 @@ +From 6544a1df11c48c8413071aac3316792e4678fbfb Mon Sep 17 00:00:00 2001 +From: Benjamin Tissoires +Date: Mon, 11 Jan 2016 17:35:38 -0800 +Subject: Input: elantech - mark protocols v2 and v3 as semi-mt + +From: Benjamin Tissoires + +commit 6544a1df11c48c8413071aac3316792e4678fbfb upstream. + +When using a protocol v2 or v3 hardware, elantech uses the function +elantech_report_semi_mt_data() to report data. This devices are rather +creepy because if num_finger is 3, (x2,y2) is (0,0). Yes, only one valid +touch is reported. + +Anyway, userspace (libinput) is now confused by these (0,0) touches, +and detect them as palm, and rejects them. + +Commit 3c0213d17a09 ("Input: elantech - fix semi-mt protocol for v3 HW") +was sufficient enough for xf86-input-synaptics and libinput before it has +palm rejection. Now we need to actually tell libinput that this device is +a semi-mt one and it should not rely on the actual values of the 2 touches. + +Signed-off-by: Benjamin Tissoires +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/input/mouse/elantech.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/input/mouse/elantech.c ++++ b/drivers/input/mouse/elantech.c +@@ -1081,7 +1081,7 @@ static int elantech_set_input_params(str + input_set_abs_params(dev, ABS_TOOL_WIDTH, ETP_WMIN_V2, + ETP_WMAX_V2, 0, 0); + } +- input_mt_init_slots(dev, 2, 0); ++ input_mt_init_slots(dev, 2, INPUT_MT_SEMI_MT); + input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0); + input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0); + break; diff --git a/queue-3.10/input-i8042-add-fujitsu-lifebook-u745-to-the-nomux-list.patch b/queue-3.10/input-i8042-add-fujitsu-lifebook-u745-to-the-nomux-list.patch new file mode 100644 index 00000000000..982c892a706 --- /dev/null +++ b/queue-3.10/input-i8042-add-fujitsu-lifebook-u745-to-the-nomux-list.patch @@ -0,0 +1,42 @@ +From dd0d0d4de582a6a61c032332c91f4f4cb2bab569 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Aur=C3=A9lien=20Francillon?= +Date: Sat, 2 Jan 2016 20:39:54 -0800 +Subject: Input: i8042 - add Fujitsu Lifebook U745 to the nomux list +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Aurélien Francillon + +commit dd0d0d4de582a6a61c032332c91f4f4cb2bab569 upstream. + +Without i8042.nomux=1 the Elantech touch pad is not working at all on +a Fujitsu Lifebook U745. This patch does not seem necessary for all +U745 (maybe because of different BIOS versions?). However, it was +verified that the patch does not break those (see opensuse bug 883192: +https://bugzilla.opensuse.org/show_bug.cgi?id=883192). + +Signed-off-by: Aurélien Francillon +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/input/serio/i8042-x86ia64io.h | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/input/serio/i8042-x86ia64io.h ++++ b/drivers/input/serio/i8042-x86ia64io.h +@@ -258,6 +258,13 @@ static const struct dmi_system_id __init + }, + }, + { ++ /* Fujitsu Lifebook U745 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U745"), ++ }, ++ }, ++ { + /* Fujitsu T70H */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), diff --git a/queue-3.10/intel_scu_ipcutil-underflow-in-scu_reg_access.patch b/queue-3.10/intel_scu_ipcutil-underflow-in-scu_reg_access.patch new file mode 100644 index 00000000000..6831d154e95 --- /dev/null +++ b/queue-3.10/intel_scu_ipcutil-underflow-in-scu_reg_access.patch @@ -0,0 +1,33 @@ +From b1d353ad3d5835b16724653b33c05124e1b5acf1 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Tue, 26 Jan 2016 12:24:25 +0300 +Subject: intel_scu_ipcutil: underflow in scu_reg_access() + +From: Dan Carpenter + +commit b1d353ad3d5835b16724653b33c05124e1b5acf1 upstream. + +"count" is controlled by the user and it can be negative. Let's prevent +that by making it unsigned. You have to have CAP_SYS_RAWIO to call this +function so the bug is not as serious as it could be. + +Fixes: 5369c02d951a ('intel_scu_ipc: Utility driver for intel scu ipc') +Signed-off-by: Dan Carpenter +Signed-off-by: Darren Hart +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/platform/x86/intel_scu_ipcutil.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/platform/x86/intel_scu_ipcutil.c ++++ b/drivers/platform/x86/intel_scu_ipcutil.c +@@ -49,7 +49,7 @@ struct scu_ipc_data { + + static int scu_reg_access(u32 cmd, struct scu_ipc_data *data) + { +- int count = data->count; ++ unsigned int count = data->count; + + if (count == 0 || count == 3 || count > 4) + return -EINVAL; diff --git a/queue-3.10/iommu-vt-d-fix-64-bit-accesses-to-32-bit-dmar_gsts_reg.patch b/queue-3.10/iommu-vt-d-fix-64-bit-accesses-to-32-bit-dmar_gsts_reg.patch new file mode 100644 index 00000000000..b5e9a68a893 --- /dev/null +++ b/queue-3.10/iommu-vt-d-fix-64-bit-accesses-to-32-bit-dmar_gsts_reg.patch @@ -0,0 +1,43 @@ +From fda3bec12d0979aae3f02ee645913d66fbc8a26e Mon Sep 17 00:00:00 2001 +From: CQ Tang +Date: Wed, 13 Jan 2016 21:15:03 +0000 +Subject: iommu/vt-d: Fix 64-bit accesses to 32-bit DMAR_GSTS_REG + +From: CQ Tang + +commit fda3bec12d0979aae3f02ee645913d66fbc8a26e upstream. + +This is a 32-bit register. Apparently harmless on real hardware, but +causing justified warnings in simulation. + +Signed-off-by: CQ Tang +Signed-off-by: David Woodhouse +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iommu/dmar.c | 2 +- + drivers/iommu/intel_irq_remapping.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/iommu/dmar.c ++++ b/drivers/iommu/dmar.c +@@ -968,7 +968,7 @@ void dmar_disable_qi(struct intel_iommu + + raw_spin_lock_irqsave(&iommu->register_lock, flags); + +- sts = dmar_readq(iommu->reg + DMAR_GSTS_REG); ++ sts = readl(iommu->reg + DMAR_GSTS_REG); + if (!(sts & DMA_GSTS_QIES)) + goto end; + +--- a/drivers/iommu/intel_irq_remapping.c ++++ b/drivers/iommu/intel_irq_remapping.c +@@ -495,7 +495,7 @@ static void iommu_disable_irq_remapping( + + raw_spin_lock_irqsave(&iommu->register_lock, flags); + +- sts = dmar_readq(iommu->reg + DMAR_GSTS_REG); ++ sts = readl(iommu->reg + DMAR_GSTS_REG); + if (!(sts & DMA_GSTS_IRES)) + goto end; + diff --git a/queue-3.10/ip6mr-call-del_timer_sync-in-ip6mr_free_table.patch b/queue-3.10/ip6mr-call-del_timer_sync-in-ip6mr_free_table.patch new file mode 100644 index 00000000000..abdc585d3ff --- /dev/null +++ b/queue-3.10/ip6mr-call-del_timer_sync-in-ip6mr_free_table.patch @@ -0,0 +1,33 @@ +From 7ba0c47c34a1ea5bc7a24ca67309996cce0569b5 Mon Sep 17 00:00:00 2001 +From: WANG Cong +Date: Tue, 31 Mar 2015 11:01:47 -0700 +Subject: ip6mr: call del_timer_sync() in ip6mr_free_table() + +From: WANG Cong + +commit 7ba0c47c34a1ea5bc7a24ca67309996cce0569b5 upstream. + +We need to wait for the flying timers, since we +are going to free the mrtable right after it. + +Cc: Hannes Frederic Sowa +Signed-off-by: Cong Wang +Signed-off-by: David S. Miller +Cc: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman + +--- + net/ipv6/ip6mr.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/ipv6/ip6mr.c ++++ b/net/ipv6/ip6mr.c +@@ -336,7 +336,7 @@ static struct mr6_table *ip6mr_new_table + + static void ip6mr_free_table(struct mr6_table *mrt) + { +- del_timer(&mrt->ipmr_expire_timer); ++ del_timer_sync(&mrt->ipmr_expire_timer); + mroute_clean_tables(mrt, true); + kfree(mrt); + } diff --git a/queue-3.10/iscsi-target-fix-potential-dead-lock-during-node-acl-delete.patch b/queue-3.10/iscsi-target-fix-potential-dead-lock-during-node-acl-delete.patch new file mode 100644 index 00000000000..6d555b94c0b --- /dev/null +++ b/queue-3.10/iscsi-target-fix-potential-dead-lock-during-node-acl-delete.patch @@ -0,0 +1,80 @@ +From 26a99c19f810b2593410899a5b304b21b47428a6 Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Tue, 19 Jan 2016 16:15:27 -0800 +Subject: iscsi-target: Fix potential dead-lock during node acl delete + +From: Nicholas Bellinger + +commit 26a99c19f810b2593410899a5b304b21b47428a6 upstream. + +This patch is a iscsi-target specific bug-fix for a dead-lock +that can occur during explicit struct se_node_acl->acl_group +se_session deletion via configfs rmdir(2), when iscsi-target +time2retain timer is still active. + +It changes iscsi-target to obtain se_portal_group->session_lock +internally using spin_in_locked() to check for the specific +se_node_acl configfs shutdown rmdir(2) case. + +Note this patch is intended for stable, and the subsequent +v4.5-rc patch converts target_core_tpg.c to use proper +se_sess->sess_kref reference counting for both se_node_acl +deletion + se_node_acl->queue_depth se_session restart. + +Reported-by:: Sagi Grimberg +Cc: Christoph Hellwig +Cc: Hannes Reinecke +Cc: Andy Grover +Cc: Mike Christie +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/iscsi/iscsi_target_configfs.c | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + +--- a/drivers/target/iscsi/iscsi_target_configfs.c ++++ b/drivers/target/iscsi/iscsi_target_configfs.c +@@ -1730,7 +1730,8 @@ static void lio_tpg_release_fabric_acl( + } + + /* +- * Called with spin_lock_bh(struct se_portal_group->session_lock) held.. ++ * Called with spin_lock_irq(struct se_portal_group->session_lock) held ++ * or not held. + * + * Also, this function calls iscsit_inc_session_usage_count() on the + * struct iscsi_session in question. +@@ -1738,19 +1739,32 @@ static void lio_tpg_release_fabric_acl( + static int lio_tpg_shutdown_session(struct se_session *se_sess) + { + struct iscsi_session *sess = se_sess->fabric_sess_ptr; ++ struct se_portal_group *se_tpg = se_sess->se_tpg; ++ bool local_lock = false; ++ ++ if (!spin_is_locked(&se_tpg->session_lock)) { ++ spin_lock_irq(&se_tpg->session_lock); ++ local_lock = true; ++ } + + spin_lock(&sess->conn_lock); + if (atomic_read(&sess->session_fall_back_to_erl0) || + atomic_read(&sess->session_logout) || + (sess->time2retain_timer_flags & ISCSI_TF_EXPIRED)) { + spin_unlock(&sess->conn_lock); ++ if (local_lock) ++ spin_unlock_irq(&sess->conn_lock); + return 0; + } + atomic_set(&sess->session_reinstatement, 1); + spin_unlock(&sess->conn_lock); + + iscsit_stop_time2retain_timer(sess); ++ spin_unlock_irq(&se_tpg->session_lock); ++ + iscsit_stop_session(sess, 1, 1); ++ if (!local_lock) ++ spin_lock_irq(&se_tpg->session_lock); + + return 1; + } diff --git a/queue-3.10/iscsi-target-fix-rx_login_comp-hang-after-login-failure.patch b/queue-3.10/iscsi-target-fix-rx_login_comp-hang-after-login-failure.patch new file mode 100644 index 00000000000..7f5e3afc7c6 --- /dev/null +++ b/queue-3.10/iscsi-target-fix-rx_login_comp-hang-after-login-failure.patch @@ -0,0 +1,79 @@ +From ca82c2bded29b38d36140bfa1e76a7bbfcade390 Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Thu, 5 Nov 2015 14:11:59 -0800 +Subject: iscsi-target: Fix rx_login_comp hang after login failure + +From: Nicholas Bellinger + +commit ca82c2bded29b38d36140bfa1e76a7bbfcade390 upstream. + +This patch addresses a case where iscsi_target_do_tx_login_io() +fails sending the last login response PDU, after the RX/TX +threads have already been started. + +The case centers around iscsi_target_rx_thread() not invoking +allow_signal(SIGINT) before the send_sig(SIGINT, ...) occurs +from the failure path, resulting in RX thread hanging +indefinately on iscsi_conn->rx_login_comp. + +Note this bug is a regression introduced by: + + commit e54198657b65625085834847ab6271087323ffea + Author: Nicholas Bellinger + Date: Wed Jul 22 23:14:19 2015 -0700 + + iscsi-target: Fix iscsit_start_kthreads failure OOPs + +To address this bug, complete ->rx_login_complete for good +measure in the failure path, and immediately return from +RX thread context if connection state did not actually reach +full feature phase (TARG_CONN_STATE_LOGGED_IN). + +Cc: Sagi Grimberg +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/iscsi/iscsi_target.c | 13 ++++++++++++- + drivers/target/iscsi/iscsi_target_nego.c | 1 + + 2 files changed, 13 insertions(+), 1 deletion(-) + +--- a/drivers/target/iscsi/iscsi_target.c ++++ b/drivers/target/iscsi/iscsi_target.c +@@ -3960,6 +3960,17 @@ reject: + return iscsit_add_reject(conn, ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf); + } + ++static bool iscsi_target_check_conn_state(struct iscsi_conn *conn) ++{ ++ bool ret; ++ ++ spin_lock_bh(&conn->state_lock); ++ ret = (conn->conn_state != TARG_CONN_STATE_LOGGED_IN); ++ spin_unlock_bh(&conn->state_lock); ++ ++ return ret; ++} ++ + int iscsi_target_rx_thread(void *arg) + { + int ret, rc; +@@ -3977,7 +3988,7 @@ int iscsi_target_rx_thread(void *arg) + * incoming iscsi/tcp socket I/O, and/or failing the connection. + */ + rc = wait_for_completion_interruptible(&conn->rx_login_comp); +- if (rc < 0) ++ if (rc < 0 || iscsi_target_check_conn_state(conn)) + return 0; + + if (conn->conn_transport->transport_type == ISCSI_INFINIBAND) { +--- a/drivers/target/iscsi/iscsi_target_nego.c ++++ b/drivers/target/iscsi/iscsi_target_nego.c +@@ -384,6 +384,7 @@ err: + if (login->login_complete) { + if (conn->rx_thread && conn->rx_thread_active) { + send_sig(SIGINT, conn->rx_thread, 1); ++ complete(&conn->rx_login_comp); + kthread_stop(conn->rx_thread); + } + if (conn->tx_thread && conn->tx_thread_active) { diff --git a/queue-3.10/klist-fix-starting-point-removed-bug-in-klist-iterators.patch b/queue-3.10/klist-fix-starting-point-removed-bug-in-klist-iterators.patch new file mode 100644 index 00000000000..e4363285413 --- /dev/null +++ b/queue-3.10/klist-fix-starting-point-removed-bug-in-klist-iterators.patch @@ -0,0 +1,64 @@ +From 00cd29b799e3449f0c68b1cc77cd4a5f95b42d17 Mon Sep 17 00:00:00 2001 +From: James Bottomley +Date: Wed, 13 Jan 2016 08:10:31 -0800 +Subject: klist: fix starting point removed bug in klist iterators + +From: James Bottomley + +commit 00cd29b799e3449f0c68b1cc77cd4a5f95b42d17 upstream. + +The starting node for a klist iteration is often passed in from +somewhere way above the klist infrastructure, meaning there's no +guarantee the node is still on the list. We've seen this in SCSI where +we use bus_find_device() to iterate through a list of devices. In the +face of heavy hotplug activity, the last device returned by +bus_find_device() can be removed before the next call. This leads to + +Dec 3 13:22:02 localhost kernel: WARNING: CPU: 2 PID: 28073 at include/linux/kref.h:47 klist_iter_init_node+0x3d/0x50() +Dec 3 13:22:02 localhost kernel: Modules linked in: scsi_debug x86_pkg_temp_thermal kvm_intel kvm irqbypass crc32c_intel joydev iTCO_wdt dcdbas ipmi_devintf acpi_power_meter iTCO_vendor_support ipmi_si imsghandler pcspkr wmi acpi_cpufreq tpm_tis tpm shpchp lpc_ich mfd_core nfsd nfs_acl lockd grace sunrpc tg3 ptp pps_core +Dec 3 13:22:02 localhost kernel: CPU: 2 PID: 28073 Comm: cat Not tainted 4.4.0-rc1+ #2 +Dec 3 13:22:02 localhost kernel: Hardware name: Dell Inc. PowerEdge R320/08VT7V, BIOS 2.0.22 11/19/2013 +Dec 3 13:22:02 localhost kernel: ffffffff81a20e77 ffff880613acfd18 ffffffff81321eef 0000000000000000 +Dec 3 13:22:02 localhost kernel: ffff880613acfd50 ffffffff8107ca52 ffff88061176b198 0000000000000000 +Dec 3 13:22:02 localhost kernel: ffffffff814542b0 ffff880610cfb100 ffff88061176b198 ffff880613acfd60 +Dec 3 13:22:02 localhost kernel: Call Trace: +Dec 3 13:22:02 localhost kernel: [] dump_stack+0x44/0x55 +Dec 3 13:22:02 localhost kernel: [] warn_slowpath_common+0x82/0xc0 +Dec 3 13:22:02 localhost kernel: [] ? proc_scsi_show+0x20/0x20 +Dec 3 13:22:02 localhost kernel: [] warn_slowpath_null+0x1a/0x20 +Dec 3 13:22:02 localhost kernel: [] klist_iter_init_node+0x3d/0x50 +Dec 3 13:22:02 localhost kernel: [] bus_find_device+0x51/0xb0 +Dec 3 13:22:02 localhost kernel: [] scsi_seq_next+0x2d/0x40 +[...] + +And an eventual crash. It can actually occur in any hotplug system +which has a device finder and a starting device. + +We can fix this globally by making sure the starting node for +klist_iter_init_node() is actually a member of the list before using it +(and by starting from the beginning if it isn't). + +Reported-by: Ewan D. Milne +Tested-by: Ewan D. Milne +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + lib/klist.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/lib/klist.c ++++ b/lib/klist.c +@@ -282,9 +282,9 @@ void klist_iter_init_node(struct klist * + struct klist_node *n) + { + i->i_klist = k; +- i->i_cur = n; +- if (n) +- kref_get(&n->n_ref); ++ i->i_cur = NULL; ++ if (n && kref_get_unless_zero(&n->n_ref)) ++ i->i_cur = n; + } + EXPORT_SYMBOL_GPL(klist_iter_init_node); + diff --git a/queue-3.10/m32r-fix-m32104ut_defconfig-build-fail.patch b/queue-3.10/m32r-fix-m32104ut_defconfig-build-fail.patch new file mode 100644 index 00000000000..bcd0632318d --- /dev/null +++ b/queue-3.10/m32r-fix-m32104ut_defconfig-build-fail.patch @@ -0,0 +1,44 @@ +From 601f1db653217f205ffa5fb33514b4e1711e56d1 Mon Sep 17 00:00:00 2001 +From: Sudip Mukherjee +Date: Thu, 14 Jan 2016 15:16:47 -0800 +Subject: m32r: fix m32104ut_defconfig build fail + +From: Sudip Mukherjee + +commit 601f1db653217f205ffa5fb33514b4e1711e56d1 upstream. + +The build of m32104ut_defconfig for m32r arch was failing for long long +time with the error: + + ERROR: "memory_start" [fs/udf/udf.ko] undefined! + ERROR: "memory_end" [fs/udf/udf.ko] undefined! + ERROR: "memory_end" [drivers/scsi/sg.ko] undefined! + ERROR: "memory_start" [drivers/scsi/sg.ko] undefined! + ERROR: "memory_end" [drivers/i2c/i2c-dev.ko] undefined! + ERROR: "memory_start" [drivers/i2c/i2c-dev.ko] undefined! + +As done in other architectures export the symbols to fix the error. + +Reported-by: Fengguang Wu +Signed-off-by: Sudip Mukherjee +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + arch/m32r/kernel/setup.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/arch/m32r/kernel/setup.c ++++ b/arch/m32r/kernel/setup.c +@@ -81,7 +81,10 @@ static struct resource code_resource = { + }; + + unsigned long memory_start; ++EXPORT_SYMBOL(memory_start); ++ + unsigned long memory_end; ++EXPORT_SYMBOL(memory_end); + + void __init setup_arch(char **); + int get_cpuinfo(char *); diff --git a/queue-3.10/memcg-only-free-spare-array-when-readers-are-done.patch b/queue-3.10/memcg-only-free-spare-array-when-readers-are-done.patch new file mode 100644 index 00000000000..d30c0b66262 --- /dev/null +++ b/queue-3.10/memcg-only-free-spare-array-when-readers-are-done.patch @@ -0,0 +1,58 @@ +From 6611d8d76132f86faa501de9451a89bf23fb2371 Mon Sep 17 00:00:00 2001 +From: Martijn Coenen +Date: Fri, 15 Jan 2016 16:57:49 -0800 +Subject: memcg: only free spare array when readers are done + +From: Martijn Coenen + +commit 6611d8d76132f86faa501de9451a89bf23fb2371 upstream. + +A spare array holding mem cgroup threshold events is kept around to make +sure we can always safely deregister an event and have an array to store +the new set of events in. + +In the scenario where we're going from 1 to 0 registered events, the +pointer to the primary array containing 1 event is copied to the spare +slot, and then the spare slot is freed because no events are left. +However, it is freed before calling synchronize_rcu(), which means +readers may still be accessing threshold->primary after it is freed. + +Fixed by only freeing after synchronize_rcu(). + +Signed-off-by: Martijn Coenen +Cc: Johannes Weiner +Acked-by: Michal Hocko +Cc: Vladimir Davydov +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/memcontrol.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +--- a/mm/memcontrol.c ++++ b/mm/memcontrol.c +@@ -5790,16 +5790,17 @@ static void mem_cgroup_usage_unregister_ + swap_buffers: + /* Swap primary and spare array */ + thresholds->spare = thresholds->primary; +- /* If all events are unregistered, free the spare array */ +- if (!new) { +- kfree(thresholds->spare); +- thresholds->spare = NULL; +- } + + rcu_assign_pointer(thresholds->primary, new); + + /* To be sure that nobody uses thresholds */ + synchronize_rcu(); ++ ++ /* If all events are unregistered, free the spare array */ ++ if (!new) { ++ kfree(thresholds->spare); ++ thresholds->spare = NULL; ++ } + unlock: + mutex_unlock(&memcg->thresholds_lock); + } diff --git a/queue-3.10/mm-memory_hotplug.c-check-for-missing-sections-in-test_pages_in_a_zone.patch b/queue-3.10/mm-memory_hotplug.c-check-for-missing-sections-in-test_pages_in_a_zone.patch new file mode 100644 index 00000000000..aa5992fcd22 --- /dev/null +++ b/queue-3.10/mm-memory_hotplug.c-check-for-missing-sections-in-test_pages_in_a_zone.patch @@ -0,0 +1,83 @@ +From 5f0f2887f4de9508dcf438deab28f1de8070c271 Mon Sep 17 00:00:00 2001 +From: Andrew Banman +Date: Tue, 29 Dec 2015 14:54:25 -0800 +Subject: mm/memory_hotplug.c: check for missing sections in test_pages_in_a_zone() + +From: Andrew Banman + +commit 5f0f2887f4de9508dcf438deab28f1de8070c271 upstream. + +test_pages_in_a_zone() does not account for the possibility of missing +sections in the given pfn range. pfn_valid_within always returns 1 when +CONFIG_HOLES_IN_ZONE is not set, allowing invalid pfns from missing +sections to pass the test, leading to a kernel oops. + +Wrap an additional pfn loop with PAGES_PER_SECTION granularity to check +for missing sections before proceeding into the zone-check code. + +This also prevents a crash from offlining memory devices with missing +sections. Despite this, it may be a good idea to keep the related patch +'[PATCH 3/3] drivers: memory: prohibit offlining of memory blocks with +missing sections' because missing sections in a memory block may lead to +other problems not covered by the scope of this fix. + +Signed-off-by: Andrew Banman +Acked-by: Alex Thorlton +Cc: Russ Anderson +Cc: Alex Thorlton +Cc: Yinghai Lu +Cc: Greg KH +Cc: Seth Jennings +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/memory_hotplug.c | 31 +++++++++++++++++++------------ + 1 file changed, 19 insertions(+), 12 deletions(-) + +--- a/mm/memory_hotplug.c ++++ b/mm/memory_hotplug.c +@@ -1209,23 +1209,30 @@ int is_mem_section_removable(unsigned lo + */ + static int test_pages_in_a_zone(unsigned long start_pfn, unsigned long end_pfn) + { +- unsigned long pfn; ++ unsigned long pfn, sec_end_pfn; + struct zone *zone = NULL; + struct page *page; + int i; +- for (pfn = start_pfn; ++ for (pfn = start_pfn, sec_end_pfn = SECTION_ALIGN_UP(start_pfn); + pfn < end_pfn; +- pfn += MAX_ORDER_NR_PAGES) { +- i = 0; +- /* This is just a CONFIG_HOLES_IN_ZONE check.*/ +- while ((i < MAX_ORDER_NR_PAGES) && !pfn_valid_within(pfn + i)) +- i++; +- if (i == MAX_ORDER_NR_PAGES) ++ pfn = sec_end_pfn + 1, sec_end_pfn += PAGES_PER_SECTION) { ++ /* Make sure the memory section is present first */ ++ if (!present_section_nr(pfn_to_section_nr(pfn))) + continue; +- page = pfn_to_page(pfn + i); +- if (zone && page_zone(page) != zone) +- return 0; +- zone = page_zone(page); ++ for (; pfn < sec_end_pfn && pfn < end_pfn; ++ pfn += MAX_ORDER_NR_PAGES) { ++ i = 0; ++ /* This is just a CONFIG_HOLES_IN_ZONE check.*/ ++ while ((i < MAX_ORDER_NR_PAGES) && ++ !pfn_valid_within(pfn + i)) ++ i++; ++ if (i == MAX_ORDER_NR_PAGES) ++ continue; ++ page = pfn_to_page(pfn + i); ++ if (zone && page_zone(page) != zone) ++ return 0; ++ zone = page_zone(page); ++ } + } + return 1; + } diff --git a/queue-3.10/mm-soft-offline-check-return-value-in-second-__get_any_page-call.patch b/queue-3.10/mm-soft-offline-check-return-value-in-second-__get_any_page-call.patch new file mode 100644 index 00000000000..592b362bcb7 --- /dev/null +++ b/queue-3.10/mm-soft-offline-check-return-value-in-second-__get_any_page-call.patch @@ -0,0 +1,78 @@ +From d96b339f453997f2f08c52da3f41423be48c978f Mon Sep 17 00:00:00 2001 +From: Naoya Horiguchi +Date: Fri, 15 Jan 2016 16:54:03 -0800 +Subject: mm: soft-offline: check return value in second __get_any_page() call + +From: Naoya Horiguchi + +commit d96b339f453997f2f08c52da3f41423be48c978f upstream. + +I saw the following BUG_ON triggered in a testcase where a process calls +madvise(MADV_SOFT_OFFLINE) on thps, along with a background process that +calls migratepages command repeatedly (doing ping-pong among different +NUMA nodes) for the first process: + + Soft offlining page 0x60000 at 0x700000600000 + __get_any_page: 0x60000 free buddy page + page:ffffea0001800000 count:0 mapcount:-127 mapping: (null) index:0x1 + flags: 0x1fffc0000000000() + page dumped because: VM_BUG_ON_PAGE(atomic_read(&page->_count) == 0) + ------------[ cut here ]------------ + kernel BUG at /src/linux-dev/include/linux/mm.h:342! + invalid opcode: 0000 [#1] SMP DEBUG_PAGEALLOC + Modules linked in: cfg80211 rfkill crc32c_intel serio_raw virtio_balloon i2c_piix4 virtio_blk virtio_net ata_generic pata_acpi + CPU: 3 PID: 3035 Comm: test_alloc_gene Tainted: G O 4.4.0-rc8-v4.4-rc8-160107-1501-00000-rc8+ #74 + Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 + task: ffff88007c63d5c0 ti: ffff88007c210000 task.ti: ffff88007c210000 + RIP: 0010:[] [] put_page+0x5c/0x60 + RSP: 0018:ffff88007c213e00 EFLAGS: 00010246 + Call Trace: + put_hwpoison_page+0x4e/0x80 + soft_offline_page+0x501/0x520 + SyS_madvise+0x6bc/0x6f0 + entry_SYSCALL_64_fastpath+0x12/0x6a + Code: 8b fc ff ff 5b 5d c3 48 89 df e8 b0 fa ff ff 48 89 df 31 f6 e8 c6 7d ff ff 5b 5d c3 48 c7 c6 08 54 a2 81 48 89 df e8 a4 c5 01 00 <0f> 0b 66 90 66 66 66 66 90 55 48 89 e5 41 55 41 54 53 48 8b 47 + RIP [] put_page+0x5c/0x60 + RSP + +The root cause resides in get_any_page() which retries to get a refcount +of the page to be soft-offlined. This function calls +put_hwpoison_page(), expecting that the target page is putback to LRU +list. But it can be also freed to buddy. So the second check need to +care about such case. + +Fixes: af8fae7c0886 ("mm/memory-failure.c: clean up soft_offline_page()") +Signed-off-by: Naoya Horiguchi +Cc: Sasha Levin +Cc: Aneesh Kumar K.V +Cc: Vlastimil Babka +Cc: Jerome Marchand +Cc: Andrea Arcangeli +Cc: Hugh Dickins +Cc: Dave Hansen +Cc: Mel Gorman +Cc: Rik van Riel +Cc: Steve Capper +Cc: Johannes Weiner +Cc: Michal Hocko +Cc: Christoph Lameter +Cc: David Rientjes +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/memory-failure.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/mm/memory-failure.c ++++ b/mm/memory-failure.c +@@ -1472,7 +1472,7 @@ static int get_any_page(struct page *pag + * Did it turn free? + */ + ret = __get_any_page(page, pfn, 0); +- if (!PageLRU(page)) { ++ if (ret == 1 && !PageLRU(page)) { + /* Drop page reference which is from __get_any_page() */ + put_page(page); + pr_info("soft_offline: %#lx: unknown non LRU page type %lx\n", diff --git a/queue-3.10/module-wrapper-for-symbol-name.patch b/queue-3.10/module-wrapper-for-symbol-name.patch new file mode 100644 index 00000000000..f49c2691a7a --- /dev/null +++ b/queue-3.10/module-wrapper-for-symbol-name.patch @@ -0,0 +1,92 @@ +From 2e7bac536106236104e9e339531ff0fcdb7b8147 Mon Sep 17 00:00:00 2001 +From: Rusty Russell +Date: Wed, 3 Feb 2016 16:55:26 +1030 +Subject: module: wrapper for symbol name. + +From: Rusty Russell + +commit 2e7bac536106236104e9e339531ff0fcdb7b8147 upstream. + +This trivial wrapper adds clarity and makes the following patch +smaller. + +Signed-off-by: Rusty Russell +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/module.c | 26 +++++++++++++++----------- + 1 file changed, 15 insertions(+), 11 deletions(-) + +--- a/kernel/module.c ++++ b/kernel/module.c +@@ -3398,6 +3398,11 @@ static inline int is_arm_mapping_symbol( + && (str[2] == '\0' || str[2] == '.'); + } + ++static const char *symname(struct module *mod, unsigned int symnum) ++{ ++ return mod->strtab + mod->symtab[symnum].st_name; ++} ++ + static const char *get_ksymbol(struct module *mod, + unsigned long addr, + unsigned long *size, +@@ -3420,15 +3425,15 @@ static const char *get_ksymbol(struct mo + + /* We ignore unnamed symbols: they're uninformative + * and inserted at a whim. */ ++ if (*symname(mod, i) == '\0' ++ || is_arm_mapping_symbol(symname(mod, i))) ++ continue; ++ + if (mod->symtab[i].st_value <= addr +- && mod->symtab[i].st_value > mod->symtab[best].st_value +- && *(mod->strtab + mod->symtab[i].st_name) != '\0' +- && !is_arm_mapping_symbol(mod->strtab + mod->symtab[i].st_name)) ++ && mod->symtab[i].st_value > mod->symtab[best].st_value) + best = i; + if (mod->symtab[i].st_value > addr +- && mod->symtab[i].st_value < nextval +- && *(mod->strtab + mod->symtab[i].st_name) != '\0' +- && !is_arm_mapping_symbol(mod->strtab + mod->symtab[i].st_name)) ++ && mod->symtab[i].st_value < nextval) + nextval = mod->symtab[i].st_value; + } + +@@ -3439,7 +3444,7 @@ static const char *get_ksymbol(struct mo + *size = nextval - mod->symtab[best].st_value; + if (offset) + *offset = addr - mod->symtab[best].st_value; +- return mod->strtab + mod->symtab[best].st_name; ++ return symname(mod, best); + } + + /* For kallsyms to ask for address resolution. NULL means not found. Careful +@@ -3540,8 +3545,7 @@ int module_get_kallsym(unsigned int symn + if (symnum < mod->num_symtab) { + *value = mod->symtab[symnum].st_value; + *type = mod->symtab[symnum].st_info; +- strlcpy(name, mod->strtab + mod->symtab[symnum].st_name, +- KSYM_NAME_LEN); ++ strlcpy(name, symname(mod, symnum), KSYM_NAME_LEN); + strlcpy(module_name, mod->name, MODULE_NAME_LEN); + *exported = is_exported(name, *value, mod); + preempt_enable(); +@@ -3558,7 +3562,7 @@ static unsigned long mod_find_symname(st + unsigned int i; + + for (i = 0; i < mod->num_symtab; i++) +- if (strcmp(name, mod->strtab+mod->symtab[i].st_name) == 0 && ++ if (strcmp(name, symname(mod, i)) == 0 && + mod->symtab[i].st_info != 'U') + return mod->symtab[i].st_value; + return 0; +@@ -3602,7 +3606,7 @@ int module_kallsyms_on_each_symbol(int ( + if (mod->state == MODULE_STATE_UNFORMED) + continue; + for (i = 0; i < mod->num_symtab; i++) { +- ret = fn(data, mod->strtab + mod->symtab[i].st_name, ++ ret = fn(data, symname(mod, i), + mod, mod->symtab[i].st_value); + if (ret != 0) + return ret; diff --git a/queue-3.10/nfs-fix-race-in-__update_open_stateid.patch b/queue-3.10/nfs-fix-race-in-__update_open_stateid.patch new file mode 100644 index 00000000000..c7415627af9 --- /dev/null +++ b/queue-3.10/nfs-fix-race-in-__update_open_stateid.patch @@ -0,0 +1,83 @@ +From 361cad3c89070aeb37560860ea8bfc092d545adc Mon Sep 17 00:00:00 2001 +From: Andrew Elble +Date: Wed, 2 Dec 2015 09:20:57 -0500 +Subject: nfs: Fix race in __update_open_stateid() + +From: Andrew Elble + +commit 361cad3c89070aeb37560860ea8bfc092d545adc upstream. + +We've seen this in a packet capture - I've intermixed what I +think was going on. The fix here is to grab the so_lock sooner. + +1964379 -> #1 open (for write) reply seqid=1 +1964393 -> #2 open (for read) reply seqid=2 + + __nfs4_close(), state->n_wronly-- + nfs4_state_set_mode_locked(), changes state->state = [R] + state->flags is [RW] + state->state is [R], state->n_wronly == 0, state->n_rdonly == 1 + +1964398 -> #3 open (for write) call -> because close is already running +1964399 -> downgrade (to read) call seqid=2 (close of #1) +1964402 -> #3 open (for write) reply seqid=3 + + __update_open_stateid() + nfs_set_open_stateid_locked(), changes state->flags + state->flags is [RW] + state->state is [R], state->n_wronly == 0, state->n_rdonly == 1 + new sequence number is exposed now via nfs4_stateid_copy() + + next step would be update_open_stateflags(), pending so_lock + +1964403 -> downgrade reply seqid=2, fails with OLD_STATEID (close of #1) + + nfs4_close_prepare() gets so_lock and recalcs flags -> send close + +1964405 -> downgrade (to read) call seqid=3 (close of #1 retry) + + __update_open_stateid() gets so_lock + * update_open_stateflags() updates state->n_wronly. + nfs4_state_set_mode_locked() updates state->state + + state->flags is [RW] + state->state is [RW], state->n_wronly == 1, state->n_rdonly == 1 + + * should have suppressed the preceding nfs4_close_prepare() from + sending open_downgrade + +1964406 -> write call +1964408 -> downgrade (to read) reply seqid=4 (close of #1 retry) + + nfs_clear_open_stateid_locked() + state->flags is [R] + state->state is [RW], state->n_wronly == 1, state->n_rdonly == 1 + +1964409 -> write reply (fails, openmode) + +Signed-off-by: Andrew Elble +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/nfs4proc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -1005,6 +1005,7 @@ static void __update_open_stateid(struct + * Protect the call to nfs4_state_set_mode_locked and + * serialise the stateid update + */ ++ spin_lock(&state->owner->so_lock); + write_seqlock(&state->seqlock); + if (deleg_stateid != NULL) { + nfs4_stateid_copy(&state->stateid, deleg_stateid); +@@ -1013,7 +1014,6 @@ static void __update_open_stateid(struct + if (open_stateid != NULL) + nfs_set_open_stateid_locked(state, open_stateid, fmode); + write_sequnlock(&state->seqlock); +- spin_lock(&state->owner->so_lock); + update_open_stateflags(state, fmode); + spin_unlock(&state->owner->so_lock); + } diff --git a/queue-3.10/perf-fix-inherited-events-vs.-tracepoint-filters.patch b/queue-3.10/perf-fix-inherited-events-vs.-tracepoint-filters.patch new file mode 100644 index 00000000000..e8ac454e41d --- /dev/null +++ b/queue-3.10/perf-fix-inherited-events-vs.-tracepoint-filters.patch @@ -0,0 +1,54 @@ +From b71b437eedaed985062492565d9d421d975ae845 Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra +Date: Mon, 2 Nov 2015 10:50:51 +0100 +Subject: perf: Fix inherited events vs. tracepoint filters +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Peter Zijlstra + +commit b71b437eedaed985062492565d9d421d975ae845 upstream. + +Arnaldo reported that tracepoint filters seem to misbehave (ie. not +apply) on inherited events. + +The fix is obvious; filters are only set on the actual (parent) +event, use the normal pattern of using this parent event for filters. +This is safe because each child event has a reference to it. + +Reported-by: Arnaldo Carvalho de Melo +Tested-by: Arnaldo Carvalho de Melo +Signed-off-by: Peter Zijlstra (Intel) +Cc: Adrian Hunter +Cc: Arnaldo Carvalho de Melo +Cc: David Ahern +Cc: Frédéric Weisbecker +Cc: Jiri Olsa +Cc: Jiri Olsa +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Steven Rostedt +Cc: Thomas Gleixner +Cc: Wang Nan +Link: http://lkml.kernel.org/r/20151102095051.GN17308@twins.programming.kicks-ass.net +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/events/core.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -5639,6 +5639,10 @@ static int perf_tp_filter_match(struct p + { + void *record = data->raw->data; + ++ /* only top level events have filters set */ ++ if (event->parent) ++ event = event->parent; ++ + if (likely(!event->filter) || filter_match_preds(event->filter, record)) + return 1; + return 0; diff --git a/queue-3.10/ptrace-use-fsuid-fsgid-effective-creds-for-fs-access-checks.patch b/queue-3.10/ptrace-use-fsuid-fsgid-effective-creds-for-fs-access-checks.patch new file mode 100644 index 00000000000..ba3bf977206 --- /dev/null +++ b/queue-3.10/ptrace-use-fsuid-fsgid-effective-creds-for-fs-access-checks.patch @@ -0,0 +1,378 @@ +From caaee6234d05a58c5b4d05e7bf766131b810a657 Mon Sep 17 00:00:00 2001 +From: Jann Horn +Date: Wed, 20 Jan 2016 15:00:04 -0800 +Subject: ptrace: use fsuid, fsgid, effective creds for fs access checks + +From: Jann Horn + +commit caaee6234d05a58c5b4d05e7bf766131b810a657 upstream. + +By checking the effective credentials instead of the real UID / permitted +capabilities, ensure that the calling process actually intended to use its +credentials. + +To ensure that all ptrace checks use the correct caller credentials (e.g. +in case out-of-tree code or newly added code omits the PTRACE_MODE_*CREDS +flag), use two new flags and require one of them to be set. + +The problem was that when a privileged task had temporarily dropped its +privileges, e.g. by calling setreuid(0, user_uid), with the intent to +perform following syscalls with the credentials of a user, it still passed +ptrace access checks that the user would not be able to pass. + +While an attacker should not be able to convince the privileged task to +perform a ptrace() syscall, this is a problem because the ptrace access +check is reused for things in procfs. + +In particular, the following somewhat interesting procfs entries only rely +on ptrace access checks: + + /proc/$pid/stat - uses the check for determining whether pointers + should be visible, useful for bypassing ASLR + /proc/$pid/maps - also useful for bypassing ASLR + /proc/$pid/cwd - useful for gaining access to restricted + directories that contain files with lax permissions, e.g. in + this scenario: + lrwxrwxrwx root root /proc/13020/cwd -> /root/foobar + drwx------ root root /root + drwxr-xr-x root root /root/foobar + -rw-r--r-- root root /root/foobar/secret + +Therefore, on a system where a root-owned mode 6755 binary changes its +effective credentials as described and then dumps a user-specified file, +this could be used by an attacker to reveal the memory layout of root's +processes or reveal the contents of files he is not allowed to access +(through /proc/$pid/cwd). + +[akpm@linux-foundation.org: fix warning] +Signed-off-by: Jann Horn +Acked-by: Kees Cook +Cc: Casey Schaufler +Cc: Oleg Nesterov +Cc: Ingo Molnar +Cc: James Morris +Cc: "Serge E. Hallyn" +Cc: Andy Shevchenko +Cc: Andy Lutomirski +Cc: Al Viro +Cc: "Eric W. Biederman" +Cc: Willy Tarreau +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/proc/array.c | 2 +- + fs/proc/base.c | 20 ++++++++++---------- + fs/proc/namespaces.c | 4 ++-- + include/linux/ptrace.h | 24 +++++++++++++++++++++++- + kernel/events/core.c | 2 +- + kernel/futex.c | 2 +- + kernel/futex_compat.c | 2 +- + kernel/kcmp.c | 4 ++-- + kernel/ptrace.c | 39 +++++++++++++++++++++++++++++++-------- + mm/process_vm_access.c | 2 +- + security/commoncap.c | 7 ++++++- + 11 files changed, 79 insertions(+), 29 deletions(-) + +--- a/fs/proc/array.c ++++ b/fs/proc/array.c +@@ -398,7 +398,7 @@ static int do_task_stat(struct seq_file + + state = *get_task_state(task); + vsize = eip = esp = 0; +- permitted = ptrace_may_access(task, PTRACE_MODE_READ | PTRACE_MODE_NOAUDIT); ++ permitted = ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS | PTRACE_MODE_NOAUDIT); + mm = get_task_mm(task); + if (mm) { + vsize = task_vsize(mm); +--- a/fs/proc/base.c ++++ b/fs/proc/base.c +@@ -239,7 +239,7 @@ out: + + static int proc_pid_auxv(struct task_struct *task, char *buffer) + { +- struct mm_struct *mm = mm_access(task, PTRACE_MODE_READ); ++ struct mm_struct *mm = mm_access(task, PTRACE_MODE_READ_FSCREDS); + int res = PTR_ERR(mm); + if (mm && !IS_ERR(mm)) { + unsigned int nwords = 0; +@@ -269,7 +269,7 @@ static int proc_pid_wchan(struct task_st + wchan = get_wchan(task); + + if (lookup_symbol_name(wchan, symname) < 0) +- if (!ptrace_may_access(task, PTRACE_MODE_READ)) ++ if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) + return 0; + else + return sprintf(buffer, "%lu", wchan); +@@ -283,7 +283,7 @@ static int lock_trace(struct task_struct + int err = mutex_lock_killable(&task->signal->cred_guard_mutex); + if (err) + return err; +- if (!ptrace_may_access(task, PTRACE_MODE_ATTACH)) { ++ if (!ptrace_may_access(task, PTRACE_MODE_ATTACH_FSCREDS)) { + mutex_unlock(&task->signal->cred_guard_mutex); + return -EPERM; + } +@@ -557,7 +557,7 @@ static int proc_fd_access_allowed(struct + */ + task = get_proc_task(inode); + if (task) { +- allowed = ptrace_may_access(task, PTRACE_MODE_READ); ++ allowed = ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS); + put_task_struct(task); + } + return allowed; +@@ -592,7 +592,7 @@ static bool has_pid_permissions(struct p + return true; + if (in_group_p(pid->pid_gid)) + return true; +- return ptrace_may_access(task, PTRACE_MODE_READ); ++ return ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS); + } + + +@@ -707,7 +707,7 @@ static int __mem_open(struct inode *inod + if (!task) + return -ESRCH; + +- mm = mm_access(task, mode); ++ mm = mm_access(task, mode | PTRACE_MODE_FSCREDS); + put_task_struct(task); + + if (IS_ERR(mm)) +@@ -1761,7 +1761,7 @@ static int map_files_d_revalidate(struct + if (!task) + goto out_notask; + +- mm = mm_access(task, PTRACE_MODE_READ); ++ mm = mm_access(task, PTRACE_MODE_READ_FSCREDS); + if (IS_ERR_OR_NULL(mm)) + goto out; + +@@ -1896,7 +1896,7 @@ static struct dentry *proc_map_files_loo + goto out; + + result = ERR_PTR(-EACCES); +- if (!ptrace_may_access(task, PTRACE_MODE_READ)) ++ if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) + goto out_put_task; + + result = ERR_PTR(-ENOENT); +@@ -1952,7 +1952,7 @@ proc_map_files_readdir(struct file *filp + goto out; + + ret = -EACCES; +- if (!ptrace_may_access(task, PTRACE_MODE_READ)) ++ if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) + goto out_put_task; + + ret = 0; +@@ -2488,7 +2488,7 @@ static int do_io_accounting(struct task_ + if (result) + return result; + +- if (!ptrace_may_access(task, PTRACE_MODE_READ)) { ++ if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) { + result = -EACCES; + goto out_unlock; + } +--- a/fs/proc/namespaces.c ++++ b/fs/proc/namespaces.c +@@ -125,7 +125,7 @@ static void *proc_ns_follow_link(struct + if (!task) + goto out; + +- if (!ptrace_may_access(task, PTRACE_MODE_READ)) ++ if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) + goto out_put_task; + + ns_path.dentry = proc_ns_get_dentry(sb, task, ei->ns.ns_ops); +@@ -158,7 +158,7 @@ static int proc_ns_readlink(struct dentr + if (!task) + goto out; + +- if (!ptrace_may_access(task, PTRACE_MODE_READ)) ++ if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) + goto out_put_task; + + len = -ENOENT; +--- a/include/linux/ptrace.h ++++ b/include/linux/ptrace.h +@@ -56,7 +56,29 @@ extern void exit_ptrace(struct task_stru + #define PTRACE_MODE_READ 0x01 + #define PTRACE_MODE_ATTACH 0x02 + #define PTRACE_MODE_NOAUDIT 0x04 +-/* Returns true on success, false on denial. */ ++#define PTRACE_MODE_FSCREDS 0x08 ++#define PTRACE_MODE_REALCREDS 0x10 ++ ++/* shorthands for READ/ATTACH and FSCREDS/REALCREDS combinations */ ++#define PTRACE_MODE_READ_FSCREDS (PTRACE_MODE_READ | PTRACE_MODE_FSCREDS) ++#define PTRACE_MODE_READ_REALCREDS (PTRACE_MODE_READ | PTRACE_MODE_REALCREDS) ++#define PTRACE_MODE_ATTACH_FSCREDS (PTRACE_MODE_ATTACH | PTRACE_MODE_FSCREDS) ++#define PTRACE_MODE_ATTACH_REALCREDS (PTRACE_MODE_ATTACH | PTRACE_MODE_REALCREDS) ++ ++/** ++ * ptrace_may_access - check whether the caller is permitted to access ++ * a target task. ++ * @task: target task ++ * @mode: selects type of access and caller credentials ++ * ++ * Returns true on success, false on denial. ++ * ++ * One of the flags PTRACE_MODE_FSCREDS and PTRACE_MODE_REALCREDS must ++ * be set in @mode to specify whether the access was requested through ++ * a filesystem syscall (should use effective capabilities and fsuid ++ * of the caller) or through an explicit syscall such as ++ * process_vm_writev or ptrace (and should use the real credentials). ++ */ + extern bool ptrace_may_access(struct task_struct *task, unsigned int mode); + + static inline int ptrace_reparented(struct task_struct *child) +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -2938,7 +2938,7 @@ find_lively_task_by_vpid(pid_t vpid) + + /* Reuse ptrace permission checks for now. */ + err = -EACCES; +- if (!ptrace_may_access(task, PTRACE_MODE_READ)) ++ if (!ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS)) + goto errout; + + return task; +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -2620,7 +2620,7 @@ SYSCALL_DEFINE3(get_robust_list, int, pi + } + + ret = -EPERM; +- if (!ptrace_may_access(p, PTRACE_MODE_READ)) ++ if (!ptrace_may_access(p, PTRACE_MODE_READ_REALCREDS)) + goto err_unlock; + + head = p->robust_list; +--- a/kernel/futex_compat.c ++++ b/kernel/futex_compat.c +@@ -155,7 +155,7 @@ COMPAT_SYSCALL_DEFINE3(get_robust_list, + } + + ret = -EPERM; +- if (!ptrace_may_access(p, PTRACE_MODE_READ)) ++ if (!ptrace_may_access(p, PTRACE_MODE_READ_REALCREDS)) + goto err_unlock; + + head = p->compat_robust_list; +--- a/kernel/kcmp.c ++++ b/kernel/kcmp.c +@@ -122,8 +122,8 @@ SYSCALL_DEFINE5(kcmp, pid_t, pid1, pid_t + &task2->signal->cred_guard_mutex); + if (ret) + goto err; +- if (!ptrace_may_access(task1, PTRACE_MODE_READ) || +- !ptrace_may_access(task2, PTRACE_MODE_READ)) { ++ if (!ptrace_may_access(task1, PTRACE_MODE_READ_REALCREDS) || ++ !ptrace_may_access(task2, PTRACE_MODE_READ_REALCREDS)) { + ret = -EPERM; + goto err_unlock; + } +--- a/kernel/ptrace.c ++++ b/kernel/ptrace.c +@@ -225,6 +225,14 @@ static int ptrace_has_cap(struct user_na + static int __ptrace_may_access(struct task_struct *task, unsigned int mode) + { + const struct cred *cred = current_cred(), *tcred; ++ int dumpable = 0; ++ kuid_t caller_uid; ++ kgid_t caller_gid; ++ ++ if (!(mode & PTRACE_MODE_FSCREDS) == !(mode & PTRACE_MODE_REALCREDS)) { ++ WARN(1, "denying ptrace access check without PTRACE_MODE_*CREDS\n"); ++ return -EPERM; ++ } + + /* May we inspect the given task? + * This check is used both for attaching with ptrace +@@ -234,18 +242,33 @@ static int __ptrace_may_access(struct ta + * because setting up the necessary parent/child relationship + * or halting the specified task is impossible. + */ +- int dumpable = 0; ++ + /* Don't let security modules deny introspection */ + if (same_thread_group(task, current)) + return 0; + rcu_read_lock(); ++ if (mode & PTRACE_MODE_FSCREDS) { ++ caller_uid = cred->fsuid; ++ caller_gid = cred->fsgid; ++ } else { ++ /* ++ * Using the euid would make more sense here, but something ++ * in userland might rely on the old behavior, and this ++ * shouldn't be a security problem since ++ * PTRACE_MODE_REALCREDS implies that the caller explicitly ++ * used a syscall that requests access to another process ++ * (and not a filesystem syscall to procfs). ++ */ ++ caller_uid = cred->uid; ++ caller_gid = cred->gid; ++ } + tcred = __task_cred(task); +- if (uid_eq(cred->uid, tcred->euid) && +- uid_eq(cred->uid, tcred->suid) && +- uid_eq(cred->uid, tcred->uid) && +- gid_eq(cred->gid, tcred->egid) && +- gid_eq(cred->gid, tcred->sgid) && +- gid_eq(cred->gid, tcred->gid)) ++ if (uid_eq(caller_uid, tcred->euid) && ++ uid_eq(caller_uid, tcred->suid) && ++ uid_eq(caller_uid, tcred->uid) && ++ gid_eq(caller_gid, tcred->egid) && ++ gid_eq(caller_gid, tcred->sgid) && ++ gid_eq(caller_gid, tcred->gid)) + goto ok; + if (ptrace_has_cap(tcred->user_ns, mode)) + goto ok; +@@ -312,7 +335,7 @@ static int ptrace_attach(struct task_str + goto out; + + task_lock(task); +- retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH); ++ retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH_REALCREDS); + task_unlock(task); + if (retval) + goto unlock_creds; +--- a/mm/process_vm_access.c ++++ b/mm/process_vm_access.c +@@ -298,7 +298,7 @@ static ssize_t process_vm_rw_core(pid_t + goto free_proc_pages; + } + +- mm = mm_access(task, PTRACE_MODE_ATTACH); ++ mm = mm_access(task, PTRACE_MODE_ATTACH_REALCREDS); + if (!mm || IS_ERR(mm)) { + rc = IS_ERR(mm) ? PTR_ERR(mm) : -ESRCH; + /* +--- a/security/commoncap.c ++++ b/security/commoncap.c +@@ -142,12 +142,17 @@ int cap_ptrace_access_check(struct task_ + { + int ret = 0; + const struct cred *cred, *child_cred; ++ const kernel_cap_t *caller_caps; + + rcu_read_lock(); + cred = current_cred(); + child_cred = __task_cred(child); ++ if (mode & PTRACE_MODE_FSCREDS) ++ caller_caps = &cred->cap_effective; ++ else ++ caller_caps = &cred->cap_permitted; + if (cred->user_ns == child_cred->user_ns && +- cap_issubset(child_cred->cap_permitted, cred->cap_permitted)) ++ cap_issubset(child_cred->cap_permitted, *caller_caps)) + goto out; + if (ns_capable(child_cred->user_ns, CAP_SYS_PTRACE)) + goto out; diff --git a/queue-3.10/pty-fix-possible-use-after-free-of-tty-driver_data.patch b/queue-3.10/pty-fix-possible-use-after-free-of-tty-driver_data.patch new file mode 100644 index 00000000000..e87e75dc8e7 --- /dev/null +++ b/queue-3.10/pty-fix-possible-use-after-free-of-tty-driver_data.patch @@ -0,0 +1,62 @@ +From 2831c89f42dcde440cfdccb9fee9f42d54bbc1ef Mon Sep 17 00:00:00 2001 +From: "Herton R. Krzesinski" +Date: Mon, 11 Jan 2016 12:07:43 -0200 +Subject: pty: fix possible use after free of tty->driver_data + +From: Herton R. Krzesinski + +commit 2831c89f42dcde440cfdccb9fee9f42d54bbc1ef upstream. + +This change fixes a bug for a corner case where we have the the last +release from a pty master/slave coming from a previously opened /dev/tty +file. When this happens, the tty->driver_data can be stale, due to all +ptmx or pts/N files having already been closed before (and thus the inode +related to these files, which tty->driver_data points to, being already +freed/destroyed). + +The fix here is to keep a reference on the opened master ptmx inode. +We maintain the inode referenced until the final pty_unix98_shutdown, +and only pass this inode to devpts_kill_index. + +Signed-off-by: Herton R. Krzesinski +Reviewed-by: Peter Hurley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/pty.c | 18 +++++++++++++++++- + 1 file changed, 17 insertions(+), 1 deletion(-) + +--- a/drivers/tty/pty.c ++++ b/drivers/tty/pty.c +@@ -623,7 +623,14 @@ static void pty_unix98_remove(struct tty + /* this is called once with whichever end is closed last */ + static void pty_unix98_shutdown(struct tty_struct *tty) + { +- devpts_kill_index(tty->driver_data, tty->index); ++ struct inode *ptmx_inode; ++ ++ if (tty->driver->subtype == PTY_TYPE_MASTER) ++ ptmx_inode = tty->driver_data; ++ else ++ ptmx_inode = tty->link->driver_data; ++ devpts_kill_index(ptmx_inode, tty->index); ++ iput(ptmx_inode); /* drop reference we acquired at ptmx_open */ + } + + static const struct tty_operations ptm_unix98_ops = { +@@ -714,6 +721,15 @@ static int ptmx_open(struct inode *inode + set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ + tty->driver_data = inode; + ++ /* ++ * In the case where all references to ptmx inode are dropped and we ++ * still have /dev/tty opened pointing to the master/slave pair (ptmx ++ * is closed/released before /dev/tty), we must make sure that the inode ++ * is still valid when we call the final pty_unix98_shutdown, thus we ++ * hold an additional reference to the ptmx inode ++ */ ++ ihold(inode); ++ + tty_add_file(tty, filp); + + slave_inode = devpts_pty_new(inode, diff --git a/queue-3.10/pty-make-sure-super_block-is-still-valid-in-final-dev-tty-close.patch b/queue-3.10/pty-make-sure-super_block-is-still-valid-in-final-dev-tty-close.patch new file mode 100644 index 00000000000..7af7610ad89 --- /dev/null +++ b/queue-3.10/pty-make-sure-super_block-is-still-valid-in-final-dev-tty-close.patch @@ -0,0 +1,111 @@ +From 1f55c718c290616889c04946864a13ef30f64929 Mon Sep 17 00:00:00 2001 +From: "Herton R. Krzesinski" +Date: Thu, 14 Jan 2016 17:56:58 -0200 +Subject: pty: make sure super_block is still valid in final /dev/tty close + +From: Herton R. Krzesinski + +commit 1f55c718c290616889c04946864a13ef30f64929 upstream. + +Considering current pty code and multiple devpts instances, it's possible +to umount a devpts file system while a program still has /dev/tty opened +pointing to a previosuly closed pty pair in that instance. In the case all +ptmx and pts/N files are closed, umount can be done. If the program closes +/dev/tty after umount is done, devpts_kill_index will use now an invalid +super_block, which was already destroyed in the umount operation after +running ->kill_sb. This is another "use after free" type of issue, but now +related to the allocated super_block instance. + +To avoid the problem (warning at ida_remove and potential crashes) for +this specific case, I added two functions in devpts which grabs additional +references to the super_block, which pty code now uses so it makes sure +the super block structure is still valid until pty shutdown is done. +I also moved the additional inode references to the same functions, which +also covered similar case with inode being freed before /dev/tty final +close/shutdown. + +Signed-off-by: Herton R. Krzesinski +Reviewed-by: Peter Hurley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/pty.c | 9 ++++++--- + fs/devpts/inode.c | 20 ++++++++++++++++++++ + include/linux/devpts_fs.h | 4 ++++ + 3 files changed, 30 insertions(+), 3 deletions(-) + +--- a/drivers/tty/pty.c ++++ b/drivers/tty/pty.c +@@ -630,7 +630,7 @@ static void pty_unix98_shutdown(struct t + else + ptmx_inode = tty->link->driver_data; + devpts_kill_index(ptmx_inode, tty->index); +- iput(ptmx_inode); /* drop reference we acquired at ptmx_open */ ++ devpts_del_ref(ptmx_inode); + } + + static const struct tty_operations ptm_unix98_ops = { +@@ -726,9 +726,12 @@ static int ptmx_open(struct inode *inode + * still have /dev/tty opened pointing to the master/slave pair (ptmx + * is closed/released before /dev/tty), we must make sure that the inode + * is still valid when we call the final pty_unix98_shutdown, thus we +- * hold an additional reference to the ptmx inode ++ * hold an additional reference to the ptmx inode. For the same /dev/tty ++ * last close case, we also need to make sure the super_block isn't ++ * destroyed (devpts instance unmounted), before /dev/tty is closed and ++ * on its release devpts_kill_index is called. + */ +- ihold(inode); ++ devpts_add_ref(inode); + + tty_add_file(tty, filp); + +--- a/fs/devpts/inode.c ++++ b/fs/devpts/inode.c +@@ -564,6 +564,26 @@ void devpts_kill_index(struct inode *ptm + mutex_unlock(&allocated_ptys_lock); + } + ++/* ++ * pty code needs to hold extra references in case of last /dev/tty close ++ */ ++ ++void devpts_add_ref(struct inode *ptmx_inode) ++{ ++ struct super_block *sb = pts_sb_from_inode(ptmx_inode); ++ ++ atomic_inc(&sb->s_active); ++ ihold(ptmx_inode); ++} ++ ++void devpts_del_ref(struct inode *ptmx_inode) ++{ ++ struct super_block *sb = pts_sb_from_inode(ptmx_inode); ++ ++ iput(ptmx_inode); ++ deactivate_super(sb); ++} ++ + /** + * devpts_pty_new -- create a new inode in /dev/pts/ + * @ptmx_inode: inode of the master +--- a/include/linux/devpts_fs.h ++++ b/include/linux/devpts_fs.h +@@ -19,6 +19,8 @@ + + int devpts_new_index(struct inode *ptmx_inode); + void devpts_kill_index(struct inode *ptmx_inode, int idx); ++void devpts_add_ref(struct inode *ptmx_inode); ++void devpts_del_ref(struct inode *ptmx_inode); + /* mknod in devpts */ + struct inode *devpts_pty_new(struct inode *ptmx_inode, dev_t device, int index, + void *priv); +@@ -32,6 +34,8 @@ void devpts_pty_kill(struct inode *inode + /* Dummy stubs in the no-pty case */ + static inline int devpts_new_index(struct inode *ptmx_inode) { return -EINVAL; } + static inline void devpts_kill_index(struct inode *ptmx_inode, int idx) { } ++static inline void devpts_add_ref(struct inode *ptmx_inode) { } ++static inline void devpts_del_ref(struct inode *ptmx_inode) { } + static inline struct inode *devpts_pty_new(struct inode *ptmx_inode, + dev_t device, int index, void *priv) + { diff --git a/queue-3.10/radix-tree-fix-oops-after-radix_tree_iter_retry.patch b/queue-3.10/radix-tree-fix-oops-after-radix_tree_iter_retry.patch new file mode 100644 index 00000000000..1a17c8729fd --- /dev/null +++ b/queue-3.10/radix-tree-fix-oops-after-radix_tree_iter_retry.patch @@ -0,0 +1,53 @@ +From 732042821cfa106b3c20b9780e4c60fee9d68900 Mon Sep 17 00:00:00 2001 +From: Konstantin Khlebnikov +Date: Fri, 5 Feb 2016 15:37:01 -0800 +Subject: radix-tree: fix oops after radix_tree_iter_retry + +From: Konstantin Khlebnikov + +commit 732042821cfa106b3c20b9780e4c60fee9d68900 upstream. + +Helper radix_tree_iter_retry() resets next_index to the current index. +In following radix_tree_next_slot current chunk size becomes zero. This +isn't checked and it tries to dereference null pointer in slot. + +Tagged iterator is fine because retry happens only at slot 0 where tag +bitmask in iter->tags is filled with single bit. + +Fixes: 46437f9a554f ("radix-tree: fix race in gang lookup") +Signed-off-by: Konstantin Khlebnikov +Cc: Matthew Wilcox +Cc: Hugh Dickins +Cc: Ohad Ben-Cohen +Cc: Jeremiah Mahler +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/radix-tree.h | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/include/linux/radix-tree.h ++++ b/include/linux/radix-tree.h +@@ -343,7 +343,7 @@ void **radix_tree_iter_retry(struct radi + * @iter: pointer to radix tree iterator + * Returns: current chunk size + */ +-static __always_inline unsigned ++static __always_inline long + radix_tree_chunk_size(struct radix_tree_iter *iter) + { + return iter->next_index - iter->index; +@@ -377,9 +377,9 @@ radix_tree_next_slot(void **slot, struct + return slot + offset + 1; + } + } else { +- unsigned size = radix_tree_chunk_size(iter) - 1; ++ long size = radix_tree_chunk_size(iter); + +- while (size--) { ++ while (--size > 0) { + slot++; + iter->index++; + if (likely(*slot)) diff --git a/queue-3.10/radix-tree-fix-race-in-gang-lookup.patch b/queue-3.10/radix-tree-fix-race-in-gang-lookup.patch new file mode 100644 index 00000000000..a1f21be8d2e --- /dev/null +++ b/queue-3.10/radix-tree-fix-race-in-gang-lookup.patch @@ -0,0 +1,91 @@ +From 46437f9a554fbe3e110580ca08ab703b59f2f95a Mon Sep 17 00:00:00 2001 +From: Matthew Wilcox +Date: Tue, 2 Feb 2016 16:57:52 -0800 +Subject: radix-tree: fix race in gang lookup + +From: Matthew Wilcox + +commit 46437f9a554fbe3e110580ca08ab703b59f2f95a upstream. + +If the indirect_ptr bit is set on a slot, that indicates we need to redo +the lookup. Introduce a new function radix_tree_iter_retry() which +forces the loop to retry the lookup by setting 'slot' to NULL and +turning the iterator back to point at the problematic entry. + +This is a pretty rare problem to hit at the moment; the lookup has to +race with a grow of the radix tree from a height of 0. The consequences +of hitting this race are that gang lookup could return a pointer to a +radix_tree_node instead of a pointer to whatever the user had inserted +in the tree. + +Fixes: cebbd29e1c2f ("radix-tree: rewrite gang lookup using iterator") +Signed-off-by: Matthew Wilcox +Cc: Hugh Dickins +Cc: Ohad Ben-Cohen +Cc: Konstantin Khlebnikov +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/radix-tree.h | 16 ++++++++++++++++ + lib/radix-tree.c | 12 ++++++++++-- + 2 files changed, 26 insertions(+), 2 deletions(-) + +--- a/include/linux/radix-tree.h ++++ b/include/linux/radix-tree.h +@@ -322,6 +322,22 @@ void **radix_tree_next_chunk(struct radi + struct radix_tree_iter *iter, unsigned flags); + + /** ++ * radix_tree_iter_retry - retry this chunk of the iteration ++ * @iter: iterator state ++ * ++ * If we iterate over a tree protected only by the RCU lock, a race ++ * against deletion or creation may result in seeing a slot for which ++ * radix_tree_deref_retry() returns true. If so, call this function ++ * and continue the iteration. ++ */ ++static inline __must_check ++void **radix_tree_iter_retry(struct radix_tree_iter *iter) ++{ ++ iter->next_index = iter->index; ++ return NULL; ++} ++ ++/** + * radix_tree_chunk_size - get current chunk size + * + * @iter: pointer to radix tree iterator +--- a/lib/radix-tree.c ++++ b/lib/radix-tree.c +@@ -1015,9 +1015,13 @@ radix_tree_gang_lookup(struct radix_tree + return 0; + + radix_tree_for_each_slot(slot, root, &iter, first_index) { +- results[ret] = indirect_to_ptr(rcu_dereference_raw(*slot)); ++ results[ret] = rcu_dereference_raw(*slot); + if (!results[ret]) + continue; ++ if (radix_tree_is_indirect_ptr(results[ret])) { ++ slot = radix_tree_iter_retry(&iter); ++ continue; ++ } + if (++ret == max_items) + break; + } +@@ -1094,9 +1098,13 @@ radix_tree_gang_lookup_tag(struct radix_ + return 0; + + radix_tree_for_each_tagged(slot, root, &iter, first_index, tag) { +- results[ret] = indirect_to_ptr(rcu_dereference_raw(*slot)); ++ results[ret] = rcu_dereference_raw(*slot); + if (!results[ret]) + continue; ++ if (radix_tree_is_indirect_ptr(results[ret])) { ++ slot = radix_tree_iter_retry(&iter); ++ continue; ++ } + if (++ret == max_items) + break; + } diff --git a/queue-3.10/scripts-bloat-o-meter-fix-python3-syntax-error.patch b/queue-3.10/scripts-bloat-o-meter-fix-python3-syntax-error.patch new file mode 100644 index 00000000000..114bb503a03 --- /dev/null +++ b/queue-3.10/scripts-bloat-o-meter-fix-python3-syntax-error.patch @@ -0,0 +1,46 @@ +From 72214a24a7677d4c7501eecc9517ed681b5f2db2 Mon Sep 17 00:00:00 2001 +From: Sergey Senozhatsky +Date: Thu, 14 Jan 2016 15:16:53 -0800 +Subject: scripts/bloat-o-meter: fix python3 syntax error + +From: Sergey Senozhatsky + +commit 72214a24a7677d4c7501eecc9517ed681b5f2db2 upstream. + +In Python3+ print is a function so the old syntax is not correct +anymore: + + $ ./scripts/bloat-o-meter vmlinux.o vmlinux.o.old + File "./scripts/bloat-o-meter", line 61 + print "add/remove: %s/%s grow/shrink: %s/%s up/down: %s/%s (%s)" % \ + ^ + SyntaxError: invalid syntax + +Fix by calling print as a function. + +Tested on python 2.7.11, 3.5.1 + +Signed-off-by: Sergey Senozhatsky +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + scripts/bloat-o-meter | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/scripts/bloat-o-meter ++++ b/scripts/bloat-o-meter +@@ -55,8 +55,8 @@ for name in common: + delta.sort() + delta.reverse() + +-print "add/remove: %s/%s grow/shrink: %s/%s up/down: %s/%s (%s)" % \ +- (add, remove, grow, shrink, up, -down, up-down) +-print "%-40s %7s %7s %+7s" % ("function", "old", "new", "delta") ++print("add/remove: %s/%s grow/shrink: %s/%s up/down: %s/%s (%s)" % \ ++ (add, remove, grow, shrink, up, -down, up-down)) ++print("%-40s %7s %7s %+7s" % ("function", "old", "new", "delta")) + for d, n in delta: +- if d: print "%-40s %7s %7s %+7d" % (n, old.get(n,"-"), new.get(n,"-"), d) ++ if d: print("%-40s %7s %7s %+7d" % (n, old.get(n,"-"), new.get(n,"-"), d)) diff --git a/queue-3.10/scsi-fix-crashes-in-sd-and-sr-runtime-pm.patch b/queue-3.10/scsi-fix-crashes-in-sd-and-sr-runtime-pm.patch new file mode 100644 index 00000000000..48dc62f0d0e --- /dev/null +++ b/queue-3.10/scsi-fix-crashes-in-sd-and-sr-runtime-pm.patch @@ -0,0 +1,80 @@ +From 13b4389143413a1f18127c07f72c74cad5b563e8 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Wed, 20 Jan 2016 11:26:01 -0500 +Subject: SCSI: fix crashes in sd and sr runtime PM + +From: Alan Stern + +commit 13b4389143413a1f18127c07f72c74cad5b563e8 upstream. + +Runtime suspend during driver probe and removal can cause problems. +The driver's runtime_suspend or runtime_resume callbacks may invoked +before the driver has finished binding to the device or after the +driver has unbound from the device. + +This problem shows up with the sd and sr drivers, and can cause disk +or CD/DVD drives to become unusable as a result. The fix is simple. +The drivers store a pointer to the scsi_disk or scsi_cd structure as +their private device data when probing is finished, so we simply have +to be sure to clear the private data during removal and test it during +runtime suspend/resume. + +This fixes . + +Signed-off-by: Alan Stern +Reported-by: Paul Menzel +Reported-by: Erich Schubert +Reported-by: Alexandre Rossi +Tested-by: Paul Menzel +Tested-by: Erich Schubert +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/sd.c | 7 +++++-- + drivers/scsi/sr.c | 4 ++++ + 2 files changed, 9 insertions(+), 2 deletions(-) + +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -3090,8 +3090,8 @@ static int sd_suspend(struct device *dev + struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); + int ret = 0; + +- if (!sdkp) +- return 0; /* this can happen */ ++ if (!sdkp) /* E.g.: runtime suspend following sd_remove() */ ++ return 0; + + if (sdkp->WCE) { + sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n"); +@@ -3115,6 +3115,9 @@ static int sd_resume(struct device *dev) + struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); + int ret = 0; + ++ if (!sdkp) /* E.g.: runtime resume at the start of sd_probe() */ ++ return 0; ++ + if (!sdkp->device->manage_start_stop) + goto done; + +--- a/drivers/scsi/sr.c ++++ b/drivers/scsi/sr.c +@@ -142,6 +142,9 @@ static int sr_runtime_suspend(struct dev + { + struct scsi_cd *cd = dev_get_drvdata(dev); + ++ if (!cd) /* E.g.: runtime suspend following sr_remove() */ ++ return 0; ++ + if (cd->media_present) + return -EBUSY; + else +@@ -1006,6 +1009,7 @@ static int sr_remove(struct device *dev) + + blk_queue_prep_rq(cd->device->request_queue, scsi_prep_fn); + del_gendisk(cd->disk); ++ dev_set_drvdata(dev, NULL); + + mutex_lock(&sr_ref_mutex); + kref_put(&cd->kref, sr_kref_release); diff --git a/queue-3.10/scsi-fix-null-pointer-dereference-in-runtime-pm.patch b/queue-3.10/scsi-fix-null-pointer-dereference-in-runtime-pm.patch new file mode 100644 index 00000000000..862ff765a8b --- /dev/null +++ b/queue-3.10/scsi-fix-null-pointer-dereference-in-runtime-pm.patch @@ -0,0 +1,85 @@ +From 4fd41a8552afc01054d9d9fc7f1a63c324867d27 Mon Sep 17 00:00:00 2001 +From: Ken Xue +Date: Tue, 1 Dec 2015 14:45:46 +0800 +Subject: SCSI: Fix NULL pointer dereference in runtime PM + +From: Ken Xue + +commit 4fd41a8552afc01054d9d9fc7f1a63c324867d27 upstream. + +The routines in scsi_pm.c assume that if a runtime-PM callback is +invoked for a SCSI device, it can only mean that the device's driver +has asked the block layer to handle the runtime power management (by +calling blk_pm_runtime_init(), which among other things sets q->dev). + +However, this assumption turns out to be wrong for things like the ses +driver. Normally ses devices are not allowed to do runtime PM, but +userspace can override this setting. If this happens, the kernel gets +a NULL pointer dereference when blk_post_runtime_resume() tries to use +the uninitialized q->dev pointer. + +This patch fixes the problem by checking q->dev in block layer before +handle runtime PM. Since ses doesn't define any PM callbacks and call +blk_pm_runtime_init(), the crash won't occur. + +This fixes Bugzilla #101371. +https://bugzilla.kernel.org/show_bug.cgi?id=101371 + +More discussion can be found from below link. +http://marc.info/?l=linux-scsi&m=144163730531875&w=2 + +Signed-off-by: Ken Xue +Acked-by: Alan Stern +Cc: Xiangliang Yu +Cc: James E.J. Bottomley +Cc: Jens Axboe +Cc: Michael Terry +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + block/blk-core.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +--- a/block/blk-core.c ++++ b/block/blk-core.c +@@ -3097,6 +3097,9 @@ int blk_pre_runtime_suspend(struct reque + { + int ret = 0; + ++ if (!q->dev) ++ return ret; ++ + spin_lock_irq(q->queue_lock); + if (q->nr_pending) { + ret = -EBUSY; +@@ -3124,6 +3127,9 @@ EXPORT_SYMBOL(blk_pre_runtime_suspend); + */ + void blk_post_runtime_suspend(struct request_queue *q, int err) + { ++ if (!q->dev) ++ return; ++ + spin_lock_irq(q->queue_lock); + if (!err) { + q->rpm_status = RPM_SUSPENDED; +@@ -3148,6 +3154,9 @@ EXPORT_SYMBOL(blk_post_runtime_suspend); + */ + void blk_pre_runtime_resume(struct request_queue *q) + { ++ if (!q->dev) ++ return; ++ + spin_lock_irq(q->queue_lock); + q->rpm_status = RPM_RESUMING; + spin_unlock_irq(q->queue_lock); +@@ -3170,6 +3179,9 @@ EXPORT_SYMBOL(blk_pre_runtime_resume); + */ + void blk_post_runtime_resume(struct request_queue *q, int err) + { ++ if (!q->dev) ++ return; ++ + spin_lock_irq(q->queue_lock); + if (!err) { + q->rpm_status = RPM_ACTIVE; diff --git a/queue-3.10/scsi-fix-soft-lockup-in-scsi_remove_target-on-module-removal.patch b/queue-3.10/scsi-fix-soft-lockup-in-scsi_remove_target-on-module-removal.patch new file mode 100644 index 00000000000..93d83ccbcdf --- /dev/null +++ b/queue-3.10/scsi-fix-soft-lockup-in-scsi_remove_target-on-module-removal.patch @@ -0,0 +1,81 @@ +From 90a88d6ef88edcfc4f644dddc7eef4ea41bccf8b Mon Sep 17 00:00:00 2001 +From: James Bottomley +Date: Wed, 10 Feb 2016 08:03:26 -0800 +Subject: scsi: fix soft lockup in scsi_remove_target() on module removal + +From: James Bottomley + +commit 90a88d6ef88edcfc4f644dddc7eef4ea41bccf8b upstream. + +This softlockup is currently happening: + +[ 444.088002] NMI watchdog: BUG: soft lockup - CPU#1 stuck for 22s! [kworker/1:1:29] +[ 444.088002] Modules linked in: lpfc(-) qla2x00tgt(O) qla2xxx_scst(O) scst_vdisk(O) scsi_transport_fc libcrc32c scst(O) dlm configfs nfsd lockd grace nfs_acl auth_rpcgss sunrpc ed +d snd_pcm_oss snd_mixer_oss snd_seq snd_seq_device dm_mod iTCO_wdt snd_hda_codec_realtek snd_hda_codec_generic gpio_ich iTCO_vendor_support ppdev snd_hda_intel snd_hda_codec snd_hda +_core snd_hwdep tg3 snd_pcm snd_timer libphy lpc_ich parport_pc ptp acpi_cpufreq snd pps_core fjes parport i2c_i801 ehci_pci tpm_tis tpm sr_mod cdrom soundcore floppy hwmon sg 8250_ +fintek pcspkr i915 drm_kms_helper uhci_hcd ehci_hcd drm fb_sys_fops sysimgblt sysfillrect syscopyarea i2c_algo_bit usbcore button video usb_common fan ata_generic ata_piix libata th +ermal +[ 444.088002] CPU: 1 PID: 29 Comm: kworker/1:1 Tainted: G O 4.4.0-rc5-2.g1e923a3-default #1 +[ 444.088002] Hardware name: FUJITSU SIEMENS ESPRIMO E /D2164-A1, BIOS 5.00 R1.10.2164.A1 05/08/2006 +[ 444.088002] Workqueue: fc_wq_4 fc_rport_final_delete [scsi_transport_fc] +[ 444.088002] task: f6266ec0 ti: f6268000 task.ti: f6268000 +[ 444.088002] EIP: 0060:[] EFLAGS: 00000286 CPU: 1 +[ 444.088002] EIP is at _raw_spin_unlock_irqrestore+0x14/0x20 +[ 444.088002] EAX: 00000286 EBX: f20d3800 ECX: 00000002 EDX: 00000286 +[ 444.088002] ESI: f50ba800 EDI: f2146848 EBP: f6269ec8 ESP: f6269ec8 +[ 444.088002] DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 +[ 444.088002] CR0: 8005003b CR2: 08f96600 CR3: 363ae000 CR4: 000006d0 +[ 444.088002] Stack: +[ 444.088002] f6269eec c066b0f7 00000286 f2146848 f50ba808 f50ba800 f50ba800 f2146a90 +[ 444.088002] f2146848 f6269f08 f8f0a4ed f3141000 f2146800 f2146a90 f619fa00 00000040 +[ 444.088002] f6269f40 c026cb25 00000001 166c6392 00000061 f6757140 f6136340 00000004 +[ 444.088002] Call Trace: +[ 444.088002] [] scsi_remove_target+0x167/0x1c0 +[ 444.088002] [] fc_rport_final_delete+0x9d/0x1e0 [scsi_transport_fc] +[ 444.088002] [] process_one_work+0x155/0x3e0 +[ 444.088002] [] worker_thread+0x37/0x490 +[ 444.088002] [] kthread+0x9b/0xb0 +[ 444.088002] [] ret_from_kernel_thread+0x21/0x40 + +What appears to be happening is that something has pinned the target +so it can't go into STARGET_DEL via final release and the loop in +scsi_remove_target spins endlessly until that happens. + +The fix for this soft lockup is to not keep looping over a device that +we've called remove on but which hasn't gone into DEL state. This +patch will retain a simplistic memory of the last target and not keep +looping over it. + +Reported-by: Sebastian Herbszt +Tested-by: Sebastian Herbszt +Fixes: 40998193560dab6c3ce8d25f4fa58a23e252ef38 +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/scsi_sysfs.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/scsi/scsi_sysfs.c ++++ b/drivers/scsi/scsi_sysfs.c +@@ -1030,16 +1030,18 @@ static void __scsi_remove_target(struct + void scsi_remove_target(struct device *dev) + { + struct Scsi_Host *shost = dev_to_shost(dev->parent); +- struct scsi_target *starget; ++ struct scsi_target *starget, *last_target = NULL; + unsigned long flags; + + restart: + spin_lock_irqsave(shost->host_lock, flags); + list_for_each_entry(starget, &shost->__targets, siblings) { +- if (starget->state == STARGET_DEL) ++ if (starget->state == STARGET_DEL || ++ starget == last_target) + continue; + if (starget->dev.parent == dev || &starget->dev == dev) { + kref_get(&starget->reap_ref); ++ last_target = starget; + spin_unlock_irqrestore(shost->host_lock, flags); + __scsi_remove_target(starget); + scsi_target_reap(starget); diff --git a/queue-3.10/scsi-restart-list-search-after-unlock-in-scsi_remove_target.patch b/queue-3.10/scsi-restart-list-search-after-unlock-in-scsi_remove_target.patch new file mode 100644 index 00000000000..f1a64f39c1f --- /dev/null +++ b/queue-3.10/scsi-restart-list-search-after-unlock-in-scsi_remove_target.patch @@ -0,0 +1,85 @@ +From 40998193560dab6c3ce8d25f4fa58a23e252ef38 Mon Sep 17 00:00:00 2001 +From: Christoph Hellwig +Date: Mon, 19 Oct 2015 16:35:46 +0200 +Subject: scsi: restart list search after unlock in scsi_remove_target + +From: Christoph Hellwig + +commit 40998193560dab6c3ce8d25f4fa58a23e252ef38 upstream. + +When dropping a lock while iterating a list we must restart the search +as other threads could have manipulated the list under us. Without this +we can get stuck in an endless loop. This bug was introduced by + +commit bc3f02a795d3b4faa99d37390174be2a75d091bd +Author: Dan Williams +Date: Tue Aug 28 22:12:10 2012 -0700 + + [SCSI] scsi_remove_target: fix softlockup regression on hot remove + +Which was itself trying to fix a reported soft lockup issue + +http://thread.gmane.org/gmane.linux.kernel/1348679 + +However, we believe even with this revert of the original patch, the soft +lockup problem has been fixed by + +commit f2495e228fce9f9cec84367547813cbb0d6db15a +Author: James Bottomley +Date: Tue Jan 21 07:01:41 2014 -0800 + + [SCSI] dual scan thread bug fix + +Thanks go to Dan Williams for tracking all this +prior history down. + +Reported-by: Johannes Thumshirn +Signed-off-by: Christoph Hellwig +Tested-by: Johannes Thumshirn +Reviewed-by: Johannes Thumshirn +Fixes: bc3f02a795d3b4faa99d37390174be2a75d091bd +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/scsi_sysfs.c | 16 ++++------------ + 1 file changed, 4 insertions(+), 12 deletions(-) + +--- a/drivers/scsi/scsi_sysfs.c ++++ b/drivers/scsi/scsi_sysfs.c +@@ -1030,31 +1030,23 @@ static void __scsi_remove_target(struct + void scsi_remove_target(struct device *dev) + { + struct Scsi_Host *shost = dev_to_shost(dev->parent); +- struct scsi_target *starget, *last = NULL; ++ struct scsi_target *starget; + unsigned long flags; + +- /* remove targets being careful to lookup next entry before +- * deleting the last +- */ ++restart: + spin_lock_irqsave(shost->host_lock, flags); + list_for_each_entry(starget, &shost->__targets, siblings) { + if (starget->state == STARGET_DEL) + continue; + if (starget->dev.parent == dev || &starget->dev == dev) { +- /* assuming new targets arrive at the end */ + kref_get(&starget->reap_ref); + spin_unlock_irqrestore(shost->host_lock, flags); +- if (last) +- scsi_target_reap(last); +- last = starget; + __scsi_remove_target(starget); +- spin_lock_irqsave(shost->host_lock, flags); ++ scsi_target_reap(starget); ++ goto restart; + } + } + spin_unlock_irqrestore(shost->host_lock, flags); +- +- if (last) +- scsi_target_reap(last); + } + EXPORT_SYMBOL(scsi_remove_target); + diff --git a/queue-3.10/scsi_dh_rdac-always-retry-mode-select-on-command-lock-violation.patch b/queue-3.10/scsi_dh_rdac-always-retry-mode-select-on-command-lock-violation.patch new file mode 100644 index 00000000000..1d89c1db063 --- /dev/null +++ b/queue-3.10/scsi_dh_rdac-always-retry-mode-select-on-command-lock-violation.patch @@ -0,0 +1,44 @@ +From d2d06d4fe0f2cc2df9b17fefec96e6e1a1271d91 Mon Sep 17 00:00:00 2001 +From: Hannes Reinecke +Date: Fri, 22 Jan 2016 15:42:41 +0100 +Subject: scsi_dh_rdac: always retry MODE SELECT on command lock violation + +From: Hannes Reinecke + +commit d2d06d4fe0f2cc2df9b17fefec96e6e1a1271d91 upstream. + +If MODE SELECT returns with sense '05/91/36' (command lock violation) +it should always be retried without counting the number of retries. +During an HBA upgrade or similar circumstances one might see a flood +of MODE SELECT command from various HBAs, which will easily trigger +the sense code and exceed the retry count. + +Signed-off-by: Hannes Reinecke +Reviewed-by: Johannes Thumshirn +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/device_handler/scsi_dh_rdac.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/scsi/device_handler/scsi_dh_rdac.c ++++ b/drivers/scsi/device_handler/scsi_dh_rdac.c +@@ -569,7 +569,7 @@ static int mode_select_handle_sense(stru + /* + * Command Lock contention + */ +- err = SCSI_DH_RETRY; ++ err = SCSI_DH_IMM_RETRY; + break; + default: + break; +@@ -619,6 +619,8 @@ retry: + err = mode_select_handle_sense(sdev, h->sense); + if (err == SCSI_DH_RETRY && retry_cnt--) + goto retry; ++ if (err == SCSI_DH_IMM_RETRY) ++ goto retry; + } + if (err == SCSI_DH_OK) { + h->state = RDAC_STATE_ACTIVE; diff --git a/queue-3.10/scsi_sysfs-fix-queue_ramp_up_period-return-code.patch b/queue-3.10/scsi_sysfs-fix-queue_ramp_up_period-return-code.patch new file mode 100644 index 00000000000..0b5bab55e47 --- /dev/null +++ b/queue-3.10/scsi_sysfs-fix-queue_ramp_up_period-return-code.patch @@ -0,0 +1,36 @@ +From 863e02d0e173bb9d8cea6861be22820b25c076cc Mon Sep 17 00:00:00 2001 +From: Peter Oberparleiter +Date: Tue, 27 Oct 2015 10:49:54 +0100 +Subject: scsi_sysfs: Fix queue_ramp_up_period return code + +From: Peter Oberparleiter + +commit 863e02d0e173bb9d8cea6861be22820b25c076cc upstream. + +Writing a number to /sys/bus/scsi/devices//queue_ramp_up_period +returns the value of that number instead of the number of bytes written. +This behavior can confuse programs expecting POSIX write() semantics. +Fix this by returning the number of bytes written instead. + +Signed-off-by: Peter Oberparleiter +Reviewed-by: Hannes Reinecke +Reviewed-by: Matthew R. Ochs +Reviewed-by: Ewan D. Milne +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/scsi_sysfs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/scsi/scsi_sysfs.c ++++ b/drivers/scsi/scsi_sysfs.c +@@ -789,7 +789,7 @@ sdev_store_queue_ramp_up_period(struct d + return -EINVAL; + + sdev->queue_ramp_up_period = msecs_to_jiffies(period); +- return period; ++ return count; + } + + static struct device_attribute sdev_attr_queue_ramp_up_period = diff --git a/queue-3.10/series b/queue-3.10/series index e69de29bb2d..1ef1335cfa3 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -0,0 +1,54 @@ +alsa-seq-fix-double-port-list-deletion.patch +wan-x25-fix-use-after-free-in-x25_asy_open_tty.patch +staging-speakup-use-tty_ldisc_ref-for-paste-kworker.patch +pty-fix-possible-use-after-free-of-tty-driver_data.patch +pty-make-sure-super_block-is-still-valid-in-final-dev-tty-close.patch +aio-properly-check-iovec-sizes.patch +ext4-fix-potential-integer-overflow.patch +btrfs-fix-hang-on-extent-buffer-lock-caused-by-the-inode_paths-ioctl.patch +perf-fix-inherited-events-vs.-tracepoint-filters.patch +ptrace-use-fsuid-fsgid-effective-creds-for-fs-access-checks.patch +tools-lib-traceevent-fix-output-of-llu-for-64-bit-values-read-on-32-bit-machines.patch +tracing-fix-freak-link-error-caused-by-branch-tracer.patch +klist-fix-starting-point-removed-bug-in-klist-iterators.patch +scsi-restart-list-search-after-unlock-in-scsi_remove_target.patch +scsi_sysfs-fix-queue_ramp_up_period-return-code.patch +iscsi-target-fix-rx_login_comp-hang-after-login-failure.patch +fix-a-memory-leak-in-scsi_host_dev_release.patch +scsi-fix-null-pointer-dereference-in-runtime-pm.patch +iscsi-target-fix-potential-dead-lock-during-node-acl-delete.patch +scsi-fix-crashes-in-sd-and-sr-runtime-pm.patch +drivers-scsi-sg.c-mark-vma-as-vm_io-to-prevent-migration.patch +scsi_dh_rdac-always-retry-mode-select-on-command-lock-violation.patch +scsi-fix-soft-lockup-in-scsi_remove_target-on-module-removal.patch +iio-ad7793-fix-ad7785-product-id.patch +iio-lpc32xx_adc-fix-warnings-caused-by-enabling-unprepared-clock.patch +iio-ad5064-make-sure-ad5064_i2c_write-returns-0-on-success.patch +iio-adis_buffer-fix-out-of-bounds-memory-access.patch +iio-dac-mcp4725-set-iio-name-property-in-sysfs.patch +cifs-fix-erroneous-return-value.patch +nfs-fix-race-in-__update_open_stateid.patch +udf-limit-the-maximum-number-of-indirect-extents-in-a-row.patch +udf-prevent-buffer-overrun-with-multi-byte-characters.patch +udf-check-output-buffer-length-when-converting-name-to-cs0.patch +arm-8519-1-icst-try-other-dividends-than-1.patch +arm-8517-1-icst-avoid-arithmetic-overflow-in-icst_hz.patch +fuse-break-infinite-loop-in-fuse_fill_write_pages.patch +mm-soft-offline-check-return-value-in-second-__get_any_page-call.patch +input-elantech-add-fujitsu-lifebook-u745-to-force-crc_enabled.patch +input-elantech-mark-protocols-v2-and-v3-as-semi-mt.patch +input-i8042-add-fujitsu-lifebook-u745-to-the-nomux-list.patch +iommu-vt-d-fix-64-bit-accesses-to-32-bit-dmar_gsts_reg.patch +mm-memory_hotplug.c-check-for-missing-sections-in-test_pages_in_a_zone.patch +xhci-fix-list-corruption-in-urb-dequeue-at-host-removal.patch +m32r-fix-m32104ut_defconfig-build-fail.patch +dma-debug-switch-check-from-_text-to-_stext.patch +scripts-bloat-o-meter-fix-python3-syntax-error.patch +memcg-only-free-spare-array-when-readers-are-done.patch +radix-tree-fix-race-in-gang-lookup.patch +radix-tree-fix-oops-after-radix_tree_iter_retry.patch +intel_scu_ipcutil-underflow-in-scu_reg_access.patch +x86-asm-irq-stop-relying-on-magic-jmp-behavior-for-early_idt_handlers.patch +futex-drop-refcount-if-requeue_pi-acquired-the-rtmutex.patch +ip6mr-call-del_timer_sync-in-ip6mr_free_table.patch +module-wrapper-for-symbol-name.patch diff --git a/queue-3.10/staging-speakup-use-tty_ldisc_ref-for-paste-kworker.patch b/queue-3.10/staging-speakup-use-tty_ldisc_ref-for-paste-kworker.patch new file mode 100644 index 00000000000..c59f2a536d7 --- /dev/null +++ b/queue-3.10/staging-speakup-use-tty_ldisc_ref-for-paste-kworker.patch @@ -0,0 +1,47 @@ +From f4f9edcf9b5289ed96113e79fa65a7bf27ecb096 Mon Sep 17 00:00:00 2001 +From: Peter Hurley +Date: Sun, 10 Jan 2016 22:40:58 -0800 +Subject: staging/speakup: Use tty_ldisc_ref() for paste kworker + +From: Peter Hurley + +commit f4f9edcf9b5289ed96113e79fa65a7bf27ecb096 upstream. + +As the function documentation for tty_ldisc_ref_wait() notes, it is +only callable from a tty file_operations routine; otherwise there +is no guarantee the ref won't be NULL. + +The key difference with the VT's paste_selection() is that is an ioctl, +where __speakup_paste_selection() is completely async kworker, kicked +off from interrupt context. + +Fixes: 28a821c30688 ("Staging: speakup: Update __speakup_paste_selection() + tty (ab)usage to match vt") +Signed-off-by: Peter Hurley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/speakup/selection.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/staging/speakup/selection.c ++++ b/drivers/staging/speakup/selection.c +@@ -139,7 +139,9 @@ static void __speakup_paste_selection(st + struct tty_ldisc *ld; + DECLARE_WAITQUEUE(wait, current); + +- ld = tty_ldisc_ref_wait(tty); ++ ld = tty_ldisc_ref(tty); ++ if (!ld) ++ goto tty_unref; + + /* FIXME: this is completely unsafe */ + add_wait_queue(&vc->paste_wait, &wait); +@@ -158,6 +160,7 @@ static void __speakup_paste_selection(st + current->state = TASK_RUNNING; + + tty_ldisc_deref(ld); ++tty_unref: + tty_kref_put(tty); + } + diff --git a/queue-3.10/tools-lib-traceevent-fix-output-of-llu-for-64-bit-values-read-on-32-bit-machines.patch b/queue-3.10/tools-lib-traceevent-fix-output-of-llu-for-64-bit-values-read-on-32-bit-machines.patch new file mode 100644 index 00000000000..c712483a1f3 --- /dev/null +++ b/queue-3.10/tools-lib-traceevent-fix-output-of-llu-for-64-bit-values-read-on-32-bit-machines.patch @@ -0,0 +1,44 @@ +From 32abc2ede536aae52978d6c0a8944eb1df14f460 Mon Sep 17 00:00:00 2001 +From: Steven Rostedt +Date: Mon, 16 Nov 2015 17:25:16 -0500 +Subject: tools lib traceevent: Fix output of %llu for 64 bit values read on 32 bit machines + +From: Steven Rostedt + +commit 32abc2ede536aae52978d6c0a8944eb1df14f460 upstream. + +When a long value is read on 32 bit machines for 64 bit output, the +parsing needs to change "%lu" into "%llu", as the value is read +natively. + +Unfortunately, if "%llu" is already there, the code will add another "l" +to it and fail to parse it properly. + +Signed-off-by: Steven Rostedt +Acked-by: Namhyung Kim +Link: http://lkml.kernel.org/r/20151116172516.4b79b109@gandalf.local.home +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Greg Kroah-Hartman + +--- + tools/lib/traceevent/event-parse.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/tools/lib/traceevent/event-parse.c ++++ b/tools/lib/traceevent/event-parse.c +@@ -4190,13 +4190,12 @@ static void pretty_print(struct trace_se + sizeof(long) != 8) { + char *p; + +- ls = 2; + /* make %l into %ll */ +- p = strchr(format, 'l'); +- if (p) ++ if (ls == 1 && (p = strchr(format, 'l'))) + memmove(p+1, p, strlen(p)+1); + else if (strcmp(format, "%p") == 0) + strcpy(format, "0x%llx"); ++ ls = 2; + } + switch (ls) { + case -2: diff --git a/queue-3.10/tracing-fix-freak-link-error-caused-by-branch-tracer.patch b/queue-3.10/tracing-fix-freak-link-error-caused-by-branch-tracer.patch new file mode 100644 index 00000000000..213f8bccd5e --- /dev/null +++ b/queue-3.10/tracing-fix-freak-link-error-caused-by-branch-tracer.patch @@ -0,0 +1,72 @@ +From b33c8ff4431a343561e2319f17c14286f2aa52e2 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Fri, 12 Feb 2016 22:26:42 +0100 +Subject: tracing: Fix freak link error caused by branch tracer + +From: Arnd Bergmann + +commit b33c8ff4431a343561e2319f17c14286f2aa52e2 upstream. + +In my randconfig tests, I came across a bug that involves several +components: + +* gcc-4.9 through at least 5.3 +* CONFIG_GCOV_PROFILE_ALL enabling -fprofile-arcs for all files +* CONFIG_PROFILE_ALL_BRANCHES overriding every if() +* The optimized implementation of do_div() that tries to + replace a library call with an division by multiplication +* code in drivers/media/dvb-frontends/zl10353.c doing + + u32 adc_clock = 450560; /* 45.056 MHz */ + if (state->config.adc_clock) + adc_clock = state->config.adc_clock; + do_div(value, adc_clock); + +In this case, gcc fails to determine whether the divisor +in do_div() is __builtin_constant_p(). In particular, it +concludes that __builtin_constant_p(adc_clock) is false, while +__builtin_constant_p(!!adc_clock) is true. + +That in turn throws off the logic in do_div() that also uses +__builtin_constant_p(), and instead of picking either the +constant- optimized division, and the code in ilog2() that uses +__builtin_constant_p() to figure out whether it knows the answer at +compile time. The result is a link error from failing to find +multiple symbols that should never have been called based on +the __builtin_constant_p(): + +dvb-frontends/zl10353.c:138: undefined reference to `____ilog2_NaN' +dvb-frontends/zl10353.c:138: undefined reference to `__aeabi_uldivmod' +ERROR: "____ilog2_NaN" [drivers/media/dvb-frontends/zl10353.ko] undefined! +ERROR: "__aeabi_uldivmod" [drivers/media/dvb-frontends/zl10353.ko] undefined! + +This patch avoids the problem by changing __trace_if() to check +whether the condition is known at compile-time to be nonzero, rather +than checking whether it is actually a constant. + +I see this one link error in roughly one out of 1600 randconfig builds +on ARM, and the patch fixes all known instances. + +Link: http://lkml.kernel.org/r/1455312410-1058841-1-git-send-email-arnd@arndb.de + +Acked-by: Nicolas Pitre +Fixes: ab3c9c686e22 ("branch tracer, intel-iommu: fix build with CONFIG_BRANCH_TRACER=y") +Signed-off-by: Arnd Bergmann +Signed-off-by: Steven Rostedt +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/compiler.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/include/linux/compiler.h ++++ b/include/linux/compiler.h +@@ -131,7 +131,7 @@ void ftrace_likely_update(struct ftrace_ + */ + #define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) ) + #define __trace_if(cond) \ +- if (__builtin_constant_p((cond)) ? !!(cond) : \ ++ if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ + ({ \ + int ______r; \ + static struct ftrace_branch_data \ diff --git a/queue-3.10/udf-check-output-buffer-length-when-converting-name-to-cs0.patch b/queue-3.10/udf-check-output-buffer-length-when-converting-name-to-cs0.patch new file mode 100644 index 00000000000..df63e76027c --- /dev/null +++ b/queue-3.10/udf-check-output-buffer-length-when-converting-name-to-cs0.patch @@ -0,0 +1,95 @@ +From bb00c898ad1ce40c4bb422a8207ae562e9aea7ae Mon Sep 17 00:00:00 2001 +From: Andrew Gabbasov +Date: Thu, 24 Dec 2015 10:25:33 -0600 +Subject: udf: Check output buffer length when converting name to CS0 + +From: Andrew Gabbasov + +commit bb00c898ad1ce40c4bb422a8207ae562e9aea7ae upstream. + +If a name contains at least some characters with Unicode values +exceeding single byte, the CS0 output should have 2 bytes per character. +And if other input characters have single byte Unicode values, then +the single input byte is converted to 2 output bytes, and the length +of output becomes larger than the length of input. And if the input +name is long enough, the output length may exceed the allocated buffer +length. + +All this means that conversion from UTF8 or NLS to CS0 requires +checking of output length in order to stop when it exceeds the given +output buffer size. + +[JK: Make code return -ENAMETOOLONG instead of silently truncating the +name] + +Signed-off-by: Andrew Gabbasov +Signed-off-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman + +--- + fs/udf/unicode.c | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +--- a/fs/udf/unicode.c ++++ b/fs/udf/unicode.c +@@ -181,17 +181,22 @@ int udf_CS0toUTF8(struct ustr *utf_o, co + static int udf_UTF8toCS0(dstring *ocu, struct ustr *utf, int length) + { + unsigned c, i, max_val, utf_char; +- int utf_cnt, u_len; ++ int utf_cnt, u_len, u_ch; + + memset(ocu, 0, sizeof(dstring) * length); + ocu[0] = 8; + max_val = 0xffU; ++ u_ch = 1; + + try_again: + u_len = 0U; + utf_char = 0U; + utf_cnt = 0U; + for (i = 0U; i < utf->u_len; i++) { ++ /* Name didn't fit? */ ++ if (u_len + 1 + u_ch >= length) ++ return 0; ++ + c = (uint8_t)utf->u_name[i]; + + /* Complete a multi-byte UTF-8 character */ +@@ -233,6 +238,7 @@ try_again: + if (max_val == 0xffU) { + max_val = 0xffffU; + ocu[0] = (uint8_t)0x10U; ++ u_ch = 2; + goto try_again; + } + goto error_out; +@@ -303,15 +309,19 @@ static int udf_NLStoCS0(struct nls_table + int len; + unsigned i, max_val; + uint16_t uni_char; +- int u_len; ++ int u_len, u_ch; + + memset(ocu, 0, sizeof(dstring) * length); + ocu[0] = 8; + max_val = 0xffU; ++ u_ch = 1; + + try_again: + u_len = 0U; + for (i = 0U; i < uni->u_len; i++) { ++ /* Name didn't fit? */ ++ if (u_len + 1 + u_ch >= length) ++ return 0; + len = nls->char2uni(&uni->u_name[i], uni->u_len - i, &uni_char); + if (!len) + continue; +@@ -324,6 +334,7 @@ try_again: + if (uni_char > max_val) { + max_val = 0xffffU; + ocu[0] = (uint8_t)0x10U; ++ u_ch = 2; + goto try_again; + } + diff --git a/queue-3.10/udf-limit-the-maximum-number-of-indirect-extents-in-a-row.patch b/queue-3.10/udf-limit-the-maximum-number-of-indirect-extents-in-a-row.patch new file mode 100644 index 00000000000..de285ab13e3 --- /dev/null +++ b/queue-3.10/udf-limit-the-maximum-number-of-indirect-extents-in-a-row.patch @@ -0,0 +1,58 @@ +From b0918d9f476a8434b055e362b83fa4fd1d462c3f Mon Sep 17 00:00:00 2001 +From: Vegard Nossum +Date: Fri, 11 Dec 2015 15:54:16 +0100 +Subject: udf: limit the maximum number of indirect extents in a row + +From: Vegard Nossum + +commit b0918d9f476a8434b055e362b83fa4fd1d462c3f upstream. + +udf_next_aext() just follows extent pointers while extents are marked as +indirect. This can loop forever for corrupted filesystem. Limit number +the of indirect extents we are willing to follow in a row. + +[JK: Updated changelog, limit, style] + +Signed-off-by: Vegard Nossum +Cc: Jan Kara +Cc: Quentin Casasnovas +Cc: Andrew Morton +Signed-off-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman + +--- + fs/udf/inode.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +--- a/fs/udf/inode.c ++++ b/fs/udf/inode.c +@@ -2055,14 +2055,29 @@ void udf_write_aext(struct inode *inode, + epos->offset += adsize; + } + ++/* ++ * Only 1 indirect extent in a row really makes sense but allow upto 16 in case ++ * someone does some weird stuff. ++ */ ++#define UDF_MAX_INDIR_EXTS 16 ++ + int8_t udf_next_aext(struct inode *inode, struct extent_position *epos, + struct kernel_lb_addr *eloc, uint32_t *elen, int inc) + { + int8_t etype; ++ unsigned int indirections = 0; + + while ((etype = udf_current_aext(inode, epos, eloc, elen, inc)) == + (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) { + int block; ++ ++ if (++indirections > UDF_MAX_INDIR_EXTS) { ++ udf_err(inode->i_sb, ++ "too many indirect extents in inode %lu\n", ++ inode->i_ino); ++ return -1; ++ } ++ + epos->block = *eloc; + epos->offset = sizeof(struct allocExtDesc); + brelse(epos->bh); diff --git a/queue-3.10/udf-prevent-buffer-overrun-with-multi-byte-characters.patch b/queue-3.10/udf-prevent-buffer-overrun-with-multi-byte-characters.patch new file mode 100644 index 00000000000..91aa864cb24 --- /dev/null +++ b/queue-3.10/udf-prevent-buffer-overrun-with-multi-byte-characters.patch @@ -0,0 +1,61 @@ +From ad402b265ecf6fa22d04043b41444cdfcdf4f52d Mon Sep 17 00:00:00 2001 +From: Andrew Gabbasov +Date: Thu, 24 Dec 2015 10:25:32 -0600 +Subject: udf: Prevent buffer overrun with multi-byte characters + +From: Andrew Gabbasov + +commit ad402b265ecf6fa22d04043b41444cdfcdf4f52d upstream. + +udf_CS0toUTF8 function stops the conversion when the output buffer +length reaches UDF_NAME_LEN-2, which is correct maximum name length, +but, when checking, it leaves the space for a single byte only, +while multi-bytes output characters can take more space, causing +buffer overflow. + +Similar error exists in udf_CS0toNLS function, that restricts +the output length to UDF_NAME_LEN, while actual maximum allowed +length is UDF_NAME_LEN-2. + +In these cases the output can override not only the current buffer +length field, causing corruption of the name buffer itself, but also +following allocation structures, causing kernel crash. + +Adjust the output length checks in both functions to prevent buffer +overruns in case of multi-bytes UTF8 or NLS characters. + +Signed-off-by: Andrew Gabbasov +Signed-off-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman + +--- + fs/udf/unicode.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/fs/udf/unicode.c ++++ b/fs/udf/unicode.c +@@ -132,11 +132,15 @@ int udf_CS0toUTF8(struct ustr *utf_o, co + if (c < 0x80U) + utf_o->u_name[utf_o->u_len++] = (uint8_t)c; + else if (c < 0x800U) { ++ if (utf_o->u_len > (UDF_NAME_LEN - 4)) ++ break; + utf_o->u_name[utf_o->u_len++] = + (uint8_t)(0xc0 | (c >> 6)); + utf_o->u_name[utf_o->u_len++] = + (uint8_t)(0x80 | (c & 0x3f)); + } else { ++ if (utf_o->u_len > (UDF_NAME_LEN - 5)) ++ break; + utf_o->u_name[utf_o->u_len++] = + (uint8_t)(0xe0 | (c >> 12)); + utf_o->u_name[utf_o->u_len++] = +@@ -281,7 +285,7 @@ static int udf_CS0toNLS(struct nls_table + c = (c << 8) | ocu[i++]; + + len = nls->uni2char(c, &utf_o->u_name[utf_o->u_len], +- UDF_NAME_LEN - utf_o->u_len); ++ UDF_NAME_LEN - 2 - utf_o->u_len); + /* Valid character? */ + if (len >= 0) + utf_o->u_len += len; diff --git a/queue-3.10/wan-x25-fix-use-after-free-in-x25_asy_open_tty.patch b/queue-3.10/wan-x25-fix-use-after-free-in-x25_asy_open_tty.patch new file mode 100644 index 00000000000..9efe5a700d5 --- /dev/null +++ b/queue-3.10/wan-x25-fix-use-after-free-in-x25_asy_open_tty.patch @@ -0,0 +1,67 @@ +From ee9159ddce14bc1dec9435ae4e3bd3153e783706 Mon Sep 17 00:00:00 2001 +From: Peter Hurley +Date: Fri, 27 Nov 2015 14:18:39 -0500 +Subject: wan/x25: Fix use-after-free in x25_asy_open_tty() + +From: Peter Hurley + +commit ee9159ddce14bc1dec9435ae4e3bd3153e783706 upstream. + +The N_X25 line discipline may access the previous line discipline's closed +and already-freed private data on open [1]. + +The tty->disc_data field _never_ refers to valid data on entry to the +line discipline's open() method. Rather, the ldisc is expected to +initialize that field for its own use for the lifetime of the instance +(ie. from open() to close() only). + +[1] + [ 634.336761] ================================================================== + [ 634.338226] BUG: KASAN: use-after-free in x25_asy_open_tty+0x13d/0x490 at addr ffff8800a743efd0 + [ 634.339558] Read of size 4 by task syzkaller_execu/8981 + [ 634.340359] ============================================================================= + [ 634.341598] BUG kmalloc-512 (Not tainted): kasan: bad access detected + ... + [ 634.405018] Call Trace: + [ 634.405277] dump_stack (lib/dump_stack.c:52) + [ 634.405775] print_trailer (mm/slub.c:655) + [ 634.406361] object_err (mm/slub.c:662) + [ 634.406824] kasan_report_error (mm/kasan/report.c:138 mm/kasan/report.c:236) + [ 634.409581] __asan_report_load4_noabort (mm/kasan/report.c:279) + [ 634.411355] x25_asy_open_tty (drivers/net/wan/x25_asy.c:559 (discriminator 1)) + [ 634.413997] tty_ldisc_open.isra.2 (drivers/tty/tty_ldisc.c:447) + [ 634.414549] tty_set_ldisc (drivers/tty/tty_ldisc.c:567) + [ 634.415057] tty_ioctl (drivers/tty/tty_io.c:2646 drivers/tty/tty_io.c:2879) + [ 634.423524] do_vfs_ioctl (fs/ioctl.c:43 fs/ioctl.c:607) + [ 634.427491] SyS_ioctl (fs/ioctl.c:622 fs/ioctl.c:613) + [ 634.427945] entry_SYSCALL_64_fastpath (arch/x86/entry/entry_64.S:188) + +Reported-and-tested-by: Sasha Levin +Signed-off-by: Peter Hurley +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wan/x25_asy.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +--- a/drivers/net/wan/x25_asy.c ++++ b/drivers/net/wan/x25_asy.c +@@ -545,16 +545,12 @@ static void x25_asy_receive_buf(struct t + + static int x25_asy_open_tty(struct tty_struct *tty) + { +- struct x25_asy *sl = tty->disc_data; ++ struct x25_asy *sl; + int err; + + if (tty->ops->write == NULL) + return -EOPNOTSUPP; + +- /* First make sure we're not already connected. */ +- if (sl && sl->magic == X25_ASY_MAGIC) +- return -EEXIST; +- + /* OK. Find a free X.25 channel to use. */ + sl = x25_asy_alloc(); + if (sl == NULL) diff --git a/queue-3.10/x86-asm-irq-stop-relying-on-magic-jmp-behavior-for-early_idt_handlers.patch b/queue-3.10/x86-asm-irq-stop-relying-on-magic-jmp-behavior-for-early_idt_handlers.patch new file mode 100644 index 00000000000..614d7d82af8 --- /dev/null +++ b/queue-3.10/x86-asm-irq-stop-relying-on-magic-jmp-behavior-for-early_idt_handlers.patch @@ -0,0 +1,249 @@ +From e4037eb7c531a6687704ecf1b24c66ac25ad3ab6 Mon Sep 17 00:00:00 2001 +From: Andy Lutomirski +Date: Fri, 22 May 2015 16:15:47 -0700 +Subject: x86/asm/irq: Stop relying on magic JMP behavior for early_idt_handlers + +From: Andy Lutomirski + +commit 425be5679fd292a3c36cb1fe423086708a99f11a upstream. + +The early_idt_handlers asm code generates an array of entry +points spaced nine bytes apart. It's not really clear from that +code or from the places that reference it what's going on, and +the code only works in the first place because GAS never +generates two-byte JMP instructions when jumping to global +labels. + +Clean up the code to generate the correct array stride (member size) +explicitly. This should be considerably more robust against +screw-ups, as GAS will warn if a .fill directive has a negative +count. Using '. =' to advance would have been even more robust +(it would generate an actual error if it tried to move +backwards), but it would pad with nulls, confusing anyone who +tries to disassemble the code. The new scheme should be much +clearer to future readers. + +While we're at it, improve the comments and rename the array and +common code. + +Binutils may start relaxing jumps to non-weak labels. If so, +this change will fix our build, and we may need to backport this +change. + +Before, on x86_64: + + 0000000000000000 : + 0: 6a 00 pushq $0x0 + 2: 6a 00 pushq $0x0 + 4: e9 00 00 00 00 jmpq 9 + 5: R_X86_64_PC32 early_idt_handler-0x4 + ... + 48: 66 90 xchg %ax,%ax + 4a: 6a 08 pushq $0x8 + 4c: e9 00 00 00 00 jmpq 51 + 4d: R_X86_64_PC32 early_idt_handler-0x4 + ... + 117: 6a 00 pushq $0x0 + 119: 6a 1f pushq $0x1f + 11b: e9 00 00 00 00 jmpq 120 + 11c: R_X86_64_PC32 early_idt_handler-0x4 + +After: + + 0000000000000000 : + 0: 6a 00 pushq $0x0 + 2: 6a 00 pushq $0x0 + 4: e9 14 01 00 00 jmpq 11d + ... + 48: 6a 08 pushq $0x8 + 4a: e9 d1 00 00 00 jmpq 120 + 4f: cc int3 + 50: cc int3 + ... + 117: 6a 00 pushq $0x0 + 119: 6a 1f pushq $0x1f + 11b: eb 03 jmp 120 + 11d: cc int3 + 11e: cc int3 + 11f: cc int3 + +Signed-off-by: Andy Lutomirski +Acked-by: H. Peter Anvin +Cc: Binutils +Cc: Borislav Petkov +Cc: H.J. Lu +Cc: Jan Beulich +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Link: http://lkml.kernel.org/r/ac027962af343b0c599cbfcf50b945ad2ef3d7a8.1432336324.git.luto@kernel.org +Signed-off-by: Ingo Molnar +Signed-off-by: Jiri Slaby +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/include/asm/segment.h | 13 ++++++++++++- + arch/x86/kernel/head64.c | 2 +- + arch/x86/kernel/head_32.S | 33 ++++++++++++++++++--------------- + arch/x86/kernel/head_64.S | 20 +++++++++++--------- + 4 files changed, 42 insertions(+), 26 deletions(-) + +--- a/arch/x86/include/asm/segment.h ++++ b/arch/x86/include/asm/segment.h +@@ -212,8 +212,19 @@ + #define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES * 8) + + #ifdef __KERNEL__ ++ ++/* ++ * early_idt_handler_array is an array of entry points referenced in the ++ * early IDT. For simplicity, it's a real array with one entry point ++ * every nine bytes. That leaves room for an optional 'push $0' if the ++ * vector has no error code (two bytes), a 'push $vector_number' (two ++ * bytes), and a jump to the common entry code (up to five bytes). ++ */ ++#define EARLY_IDT_HANDLER_SIZE 9 ++ + #ifndef __ASSEMBLY__ +-extern const char early_idt_handlers[NUM_EXCEPTION_VECTORS][2+2+5]; ++ ++extern const char early_idt_handler_array[NUM_EXCEPTION_VECTORS][EARLY_IDT_HANDLER_SIZE]; + + /* + * Load a segment. Fall back on loading the zero +--- a/arch/x86/kernel/head64.c ++++ b/arch/x86/kernel/head64.c +@@ -162,7 +162,7 @@ void __init x86_64_start_kernel(char * r + clear_bss(); + + for (i = 0; i < NUM_EXCEPTION_VECTORS; i++) +- set_intr_gate(i, &early_idt_handlers[i]); ++ set_intr_gate(i, &early_idt_handler_array[i]); + load_idt((const struct desc_ptr *)&idt_descr); + + copy_bootdata(__va(real_mode_data)); +--- a/arch/x86/kernel/head_32.S ++++ b/arch/x86/kernel/head_32.S +@@ -499,21 +499,22 @@ check_x87: + __INIT + setup_once: + /* +- * Set up a idt with 256 entries pointing to ignore_int, +- * interrupt gates. It doesn't actually load idt - that needs +- * to be done on each CPU. Interrupts are enabled elsewhere, +- * when we can be relatively sure everything is ok. ++ * Set up a idt with 256 interrupt gates that push zero if there ++ * is no error code and then jump to early_idt_handler_common. ++ * It doesn't actually load the idt - that needs to be done on ++ * each CPU. Interrupts are enabled elsewhere, when we can be ++ * relatively sure everything is ok. + */ + + movl $idt_table,%edi +- movl $early_idt_handlers,%eax ++ movl $early_idt_handler_array,%eax + movl $NUM_EXCEPTION_VECTORS,%ecx + 1: + movl %eax,(%edi) + movl %eax,4(%edi) + /* interrupt gate, dpl=0, present */ + movl $(0x8E000000 + __KERNEL_CS),2(%edi) +- addl $9,%eax ++ addl $EARLY_IDT_HANDLER_SIZE,%eax + addl $8,%edi + loop 1b + +@@ -545,26 +546,28 @@ setup_once: + andl $0,setup_once_ref /* Once is enough, thanks */ + ret + +-ENTRY(early_idt_handlers) ++ENTRY(early_idt_handler_array) + # 36(%esp) %eflags + # 32(%esp) %cs + # 28(%esp) %eip + # 24(%rsp) error code + i = 0 + .rept NUM_EXCEPTION_VECTORS +- .if (EXCEPTION_ERRCODE_MASK >> i) & 1 +- ASM_NOP2 +- .else ++ .ifeq (EXCEPTION_ERRCODE_MASK >> i) & 1 + pushl $0 # Dummy error code, to make stack frame uniform + .endif + pushl $i # 20(%esp) Vector number +- jmp early_idt_handler ++ jmp early_idt_handler_common + i = i + 1 ++ .fill early_idt_handler_array + i*EARLY_IDT_HANDLER_SIZE - ., 1, 0xcc + .endr +-ENDPROC(early_idt_handlers) ++ENDPROC(early_idt_handler_array) + +- /* This is global to keep gas from relaxing the jumps */ +-ENTRY(early_idt_handler) ++early_idt_handler_common: ++ /* ++ * The stack is the hardware frame, an error code or zero, and the ++ * vector number. ++ */ + cld + + cmpl $2,(%esp) # X86_TRAP_NMI +@@ -624,7 +627,7 @@ ex_entry: + is_nmi: + addl $8,%esp /* drop vector number and error code */ + iret +-ENDPROC(early_idt_handler) ++ENDPROC(early_idt_handler_common) + + /* This is the default interrupt "handler" :-) */ + ALIGN +--- a/arch/x86/kernel/head_64.S ++++ b/arch/x86/kernel/head_64.S +@@ -329,26 +329,28 @@ bad_address: + jmp bad_address + + __INIT +- .globl early_idt_handlers +-early_idt_handlers: ++ENTRY(early_idt_handler_array) + # 104(%rsp) %rflags + # 96(%rsp) %cs + # 88(%rsp) %rip + # 80(%rsp) error code + i = 0 + .rept NUM_EXCEPTION_VECTORS +- .if (EXCEPTION_ERRCODE_MASK >> i) & 1 +- ASM_NOP2 +- .else ++ .ifeq (EXCEPTION_ERRCODE_MASK >> i) & 1 + pushq $0 # Dummy error code, to make stack frame uniform + .endif + pushq $i # 72(%rsp) Vector number +- jmp early_idt_handler ++ jmp early_idt_handler_common + i = i + 1 ++ .fill early_idt_handler_array + i*EARLY_IDT_HANDLER_SIZE - ., 1, 0xcc + .endr ++ENDPROC(early_idt_handler_array) + +-/* This is global to keep gas from relaxing the jumps */ +-ENTRY(early_idt_handler) ++early_idt_handler_common: ++ /* ++ * The stack is the hardware frame, an error code or zero, and the ++ * vector number. ++ */ + cld + + cmpl $2,(%rsp) # X86_TRAP_NMI +@@ -420,7 +422,7 @@ ENTRY(early_idt_handler) + is_nmi: + addq $16,%rsp # drop vector number and error code + INTERRUPT_RETURN +-ENDPROC(early_idt_handler) ++ENDPROC(early_idt_handler_common) + + __INITDATA + diff --git a/queue-3.10/xhci-fix-list-corruption-in-urb-dequeue-at-host-removal.patch b/queue-3.10/xhci-fix-list-corruption-in-urb-dequeue-at-host-removal.patch new file mode 100644 index 00000000000..479bdfdecd2 --- /dev/null +++ b/queue-3.10/xhci-fix-list-corruption-in-urb-dequeue-at-host-removal.patch @@ -0,0 +1,39 @@ +From 5c82171167adb8e4ac77b91a42cd49fb211a81a0 Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Tue, 26 Jan 2016 17:50:12 +0200 +Subject: xhci: Fix list corruption in urb dequeue at host removal + +From: Mathias Nyman + +commit 5c82171167adb8e4ac77b91a42cd49fb211a81a0 upstream. + +xhci driver frees data for all devices, both usb2 and and usb3 the +first time usb_remove_hcd() is called, including td_list and and xhci_ring +structures. + +When usb_remove_hcd() is called a second time for the second xhci bus it +will try to dequeue all pending urbs, and touches td_list which is already +freed for that endpoint. + +Reported-by: Joe Lawrence +Tested-by: Joe Lawrence +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -1502,7 +1502,9 @@ int xhci_urb_dequeue(struct usb_hcd *hcd + if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_HALTED)) { + xhci_dbg(xhci, "HW died, freeing TD.\n"); + urb_priv = urb->hcpriv; +- for (i = urb_priv->td_cnt; i < urb_priv->length; i++) { ++ for (i = urb_priv->td_cnt; ++ i < urb_priv->length && xhci->devs[urb->dev->slot_id]; ++ i++) { + td = urb_priv->td[i]; + if (!list_empty(&td->td_list)) + list_del_init(&td->td_list);