From: Greg Kroah-Hartman Date: Fri, 6 Jan 2017 15:29:43 +0000 (+0100) Subject: 4.4-stable patches X-Git-Tag: v4.4.41~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a00b453a1e55ad8f68ece98169343d2747224c62;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: kconfig-nconf-fix-hang-when-editing-symbol-with-a-long-prompt.patch libceph-verify-authorize-reply-on-connect.patch net-mvpp2-fix-dma-unmapping-of-tx-buffers-for-fragments.patch nfs_write_end-fix-handling-of-short-copies.patch pci-check-for-pme-in-targeted-sleep-state.patch powerpc-convert-cmp-to-cmpd-in-idle-enter-sequence.patch powerpc-ps3-fix-system-hang-with-gcc-5-builds.patch sg_write-bsg_write-is-not-fit-to-be-called-under-kernel_ds.patch target-user-fix-use-after-free-of-tcmu_cmds-if-they-are-expired.patch --- diff --git a/queue-4.4/kconfig-nconf-fix-hang-when-editing-symbol-with-a-long-prompt.patch b/queue-4.4/kconfig-nconf-fix-hang-when-editing-symbol-with-a-long-prompt.patch new file mode 100644 index 00000000000..bed2a9da72a --- /dev/null +++ b/queue-4.4/kconfig-nconf-fix-hang-when-editing-symbol-with-a-long-prompt.patch @@ -0,0 +1,70 @@ +From 79e51b5c2deea542b3bb8c66e0d502230b017dde Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +Date: Thu, 24 Nov 2016 22:10:23 +0000 +Subject: kconfig/nconf: Fix hang when editing symbol with a long prompt + +From: Ben Hutchings + +commit 79e51b5c2deea542b3bb8c66e0d502230b017dde upstream. + +Currently it is impossible to edit the value of a config symbol with a +prompt longer than (terminal width - 2) characters. dialog_inputbox() +calculates a negative x-offset for the input window and newwin() fails +as this is invalid. It also doesn't check for this failure, so it +busy-loops calling wgetch(NULL) which immediately returns -1. + +The additions in the offset calculations also don't match the intended +size of the window. + +Limit the window size and calculate the offset similarly to +show_scroll_win(). + +Fixes: 692d97c380c6 ("kconfig: new configuration interface (nconfig)") +Signed-off-by: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman + +--- + scripts/kconfig/nconf.gui.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +--- a/scripts/kconfig/nconf.gui.c ++++ b/scripts/kconfig/nconf.gui.c +@@ -364,12 +364,14 @@ int dialog_inputbox(WINDOW *main_window, + WINDOW *prompt_win; + WINDOW *form_win; + PANEL *panel; +- int i, x, y; ++ int i, x, y, lines, columns, win_lines, win_cols; + int res = -1; + int cursor_position = strlen(init); + int cursor_form_win; + char *result = *resultp; + ++ getmaxyx(stdscr, lines, columns); ++ + if (strlen(init)+1 > *result_len) { + *result_len = strlen(init)+1; + *resultp = result = realloc(result, *result_len); +@@ -386,14 +388,19 @@ int dialog_inputbox(WINDOW *main_window, + if (title) + prompt_width = max(prompt_width, strlen(title)); + ++ win_lines = min(prompt_lines+6, lines-2); ++ win_cols = min(prompt_width+7, columns-2); ++ prompt_lines = max(win_lines-6, 0); ++ prompt_width = max(win_cols-7, 0); ++ + /* place dialog in middle of screen */ +- y = (getmaxy(stdscr)-(prompt_lines+4))/2; +- x = (getmaxx(stdscr)-(prompt_width+4))/2; ++ y = (lines-win_lines)/2; ++ x = (columns-win_cols)/2; + + strncpy(result, init, *result_len); + + /* create the windows */ +- win = newwin(prompt_lines+6, prompt_width+7, y, x); ++ win = newwin(win_lines, win_cols, y, x); + prompt_win = derwin(win, prompt_lines+1, prompt_width, 2, 2); + form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2); + keypad(form_win, TRUE); diff --git a/queue-4.4/libceph-verify-authorize-reply-on-connect.patch b/queue-4.4/libceph-verify-authorize-reply-on-connect.patch new file mode 100644 index 00000000000..330f5ff6f3f --- /dev/null +++ b/queue-4.4/libceph-verify-authorize-reply-on-connect.patch @@ -0,0 +1,54 @@ +From 5c056fdc5b474329037f2aa18401bd73033e0ce0 Mon Sep 17 00:00:00 2001 +From: Ilya Dryomov +Date: Fri, 2 Dec 2016 16:35:09 +0100 +Subject: libceph: verify authorize reply on connect + +From: Ilya Dryomov + +commit 5c056fdc5b474329037f2aa18401bd73033e0ce0 upstream. + +After sending an authorizer (ceph_x_authorize_a + ceph_x_authorize_b), +the client gets back a ceph_x_authorize_reply, which it is supposed to +verify to ensure the authenticity and protect against replay attacks. +The code for doing this is there (ceph_x_verify_authorizer_reply(), +ceph_auth_verify_authorizer_reply() + plumbing), but it is never +invoked by the the messenger. + +AFAICT this goes back to 2009, when ceph authentication protocols +support was added to the kernel client in 4e7a5dcd1bba ("ceph: +negotiate authentication protocol; implement AUTH_NONE protocol"). + +The second param of ceph_connection_operations::verify_authorizer_reply +is unused all the way down. Pass 0 to facilitate backporting, and kill +it in the next commit. + +Signed-off-by: Ilya Dryomov +Reviewed-by: Sage Weil +Signed-off-by: Greg Kroah-Hartman + +--- + net/ceph/messenger.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/net/ceph/messenger.c ++++ b/net/ceph/messenger.c +@@ -2042,6 +2042,19 @@ static int process_connect(struct ceph_c + + dout("process_connect on %p tag %d\n", con, (int)con->in_tag); + ++ if (con->auth_reply_buf) { ++ /* ++ * Any connection that defines ->get_authorizer() ++ * should also define ->verify_authorizer_reply(). ++ * See get_connect_authorizer(). ++ */ ++ ret = con->ops->verify_authorizer_reply(con, 0); ++ if (ret < 0) { ++ con->error_msg = "bad authorize reply"; ++ return ret; ++ } ++ } ++ + switch (con->in_reply.tag) { + case CEPH_MSGR_TAG_FEATURES: + pr_err("%s%lld %s feature set mismatch," diff --git a/queue-4.4/net-mvpp2-fix-dma-unmapping-of-tx-buffers-for-fragments.patch b/queue-4.4/net-mvpp2-fix-dma-unmapping-of-tx-buffers-for-fragments.patch new file mode 100644 index 00000000000..120bed6561e --- /dev/null +++ b/queue-4.4/net-mvpp2-fix-dma-unmapping-of-tx-buffers-for-fragments.patch @@ -0,0 +1,166 @@ +From 8354491c9d5b06709384cea91d13019bf5e61449 Mon Sep 17 00:00:00 2001 +From: Thomas Petazzoni +Date: Wed, 21 Dec 2016 11:28:49 +0100 +Subject: net: mvpp2: fix dma unmapping of TX buffers for fragments + +From: Thomas Petazzoni + +commit 8354491c9d5b06709384cea91d13019bf5e61449 upstream. + +Since commit 71ce391dfb784 ("net: mvpp2: enable proper per-CPU TX +buffers unmapping"), we are not correctly DMA unmapping TX buffers for +fragments. + +Indeed, the mvpp2_txq_inc_put() function only stores in the +txq_cpu->tx_buffs[] array the physical address of the buffer to be +DMA-unmapped when skb != NULL. In addition, when DMA-unmapping, we use +skb_headlen(skb) to get the size to be unmapped. Both of this works fine +for TX descriptors that are associated directly to a SKB, but not the +ones that are used for fragments, with a NULL pointer as skb: + + - We have a NULL physical address when calling DMA unmap + - skb_headlen(skb) crashes because skb is NULL + +This causes random crashes when fragments are used. + +To solve this problem, we need to: + + - Store the physical address of the buffer to be unmapped + unconditionally, regardless of whether it is tied to a SKB or not. + + - Store the length of the buffer to be unmapped, which requires a new + field. + +Instead of adding a third array to store the length of the buffer to be +unmapped, and as suggested by David Miller, this commit refactors the +tx_buffs[] and tx_skb[] arrays of 'struct mvpp2_txq_pcpu' into a +separate structure 'mvpp2_txq_pcpu_buf', to which a 'size' field is +added. Therefore, instead of having three arrays to allocate/free, we +have a single one, which also improve data locality, reducing the +impact on the CPU cache. + +Fixes: 71ce391dfb784 ("net: mvpp2: enable proper per-CPU TX buffers unmapping") +Reported-by: Raphael G +Cc: Raphael G +Signed-off-by: Thomas Petazzoni +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/ethernet/marvell/mvpp2.c | 59 +++++++++++++++++------------------ + 1 file changed, 30 insertions(+), 29 deletions(-) + +--- a/drivers/net/ethernet/marvell/mvpp2.c ++++ b/drivers/net/ethernet/marvell/mvpp2.c +@@ -772,6 +772,17 @@ struct mvpp2_rx_desc { + u32 reserved8; + }; + ++struct mvpp2_txq_pcpu_buf { ++ /* Transmitted SKB */ ++ struct sk_buff *skb; ++ ++ /* Physical address of transmitted buffer */ ++ dma_addr_t phys; ++ ++ /* Size transmitted */ ++ size_t size; ++}; ++ + /* Per-CPU Tx queue control */ + struct mvpp2_txq_pcpu { + int cpu; +@@ -787,11 +798,8 @@ struct mvpp2_txq_pcpu { + /* Number of Tx DMA descriptors reserved for each CPU */ + int reserved_num; + +- /* Array of transmitted skb */ +- struct sk_buff **tx_skb; +- +- /* Array of transmitted buffers' physical addresses */ +- dma_addr_t *tx_buffs; ++ /* Infos about transmitted buffers */ ++ struct mvpp2_txq_pcpu_buf *buffs; + + /* Index of last TX DMA descriptor that was inserted */ + int txq_put_index; +@@ -981,10 +989,11 @@ static void mvpp2_txq_inc_put(struct mvp + struct sk_buff *skb, + struct mvpp2_tx_desc *tx_desc) + { +- txq_pcpu->tx_skb[txq_pcpu->txq_put_index] = skb; +- if (skb) +- txq_pcpu->tx_buffs[txq_pcpu->txq_put_index] = +- tx_desc->buf_phys_addr; ++ struct mvpp2_txq_pcpu_buf *tx_buf = ++ txq_pcpu->buffs + txq_pcpu->txq_put_index; ++ tx_buf->skb = skb; ++ tx_buf->size = tx_desc->data_size; ++ tx_buf->phys = tx_desc->buf_phys_addr; + txq_pcpu->txq_put_index++; + if (txq_pcpu->txq_put_index == txq_pcpu->size) + txq_pcpu->txq_put_index = 0; +@@ -4403,17 +4412,16 @@ static void mvpp2_txq_bufs_free(struct m + int i; + + for (i = 0; i < num; i++) { +- dma_addr_t buf_phys_addr = +- txq_pcpu->tx_buffs[txq_pcpu->txq_get_index]; +- struct sk_buff *skb = txq_pcpu->tx_skb[txq_pcpu->txq_get_index]; ++ struct mvpp2_txq_pcpu_buf *tx_buf = ++ txq_pcpu->buffs + txq_pcpu->txq_get_index; + + mvpp2_txq_inc_get(txq_pcpu); + +- dma_unmap_single(port->dev->dev.parent, buf_phys_addr, +- skb_headlen(skb), DMA_TO_DEVICE); +- if (!skb) ++ dma_unmap_single(port->dev->dev.parent, tx_buf->phys, ++ tx_buf->size, DMA_TO_DEVICE); ++ if (!tx_buf->skb) + continue; +- dev_kfree_skb_any(skb); ++ dev_kfree_skb_any(tx_buf->skb); + } + } + +@@ -4664,15 +4672,10 @@ static int mvpp2_txq_init(struct mvpp2_p + for_each_present_cpu(cpu) { + txq_pcpu = per_cpu_ptr(txq->pcpu, cpu); + txq_pcpu->size = txq->size; +- txq_pcpu->tx_skb = kmalloc(txq_pcpu->size * +- sizeof(*txq_pcpu->tx_skb), +- GFP_KERNEL); +- if (!txq_pcpu->tx_skb) +- goto error; +- +- txq_pcpu->tx_buffs = kmalloc(txq_pcpu->size * +- sizeof(dma_addr_t), GFP_KERNEL); +- if (!txq_pcpu->tx_buffs) ++ txq_pcpu->buffs = kmalloc(txq_pcpu->size * ++ sizeof(struct mvpp2_txq_pcpu_buf), ++ GFP_KERNEL); ++ if (!txq_pcpu->buffs) + goto error; + + txq_pcpu->count = 0; +@@ -4686,8 +4689,7 @@ static int mvpp2_txq_init(struct mvpp2_p + error: + for_each_present_cpu(cpu) { + txq_pcpu = per_cpu_ptr(txq->pcpu, cpu); +- kfree(txq_pcpu->tx_skb); +- kfree(txq_pcpu->tx_buffs); ++ kfree(txq_pcpu->buffs); + } + + dma_free_coherent(port->dev->dev.parent, +@@ -4706,8 +4708,7 @@ static void mvpp2_txq_deinit(struct mvpp + + for_each_present_cpu(cpu) { + txq_pcpu = per_cpu_ptr(txq->pcpu, cpu); +- kfree(txq_pcpu->tx_skb); +- kfree(txq_pcpu->tx_buffs); ++ kfree(txq_pcpu->buffs); + } + + if (txq->descs) diff --git a/queue-4.4/nfs_write_end-fix-handling-of-short-copies.patch b/queue-4.4/nfs_write_end-fix-handling-of-short-copies.patch new file mode 100644 index 00000000000..5a1a2dd52b3 --- /dev/null +++ b/queue-4.4/nfs_write_end-fix-handling-of-short-copies.patch @@ -0,0 +1,32 @@ +From c0cf3ef5e0f47e385920450b245d22bead93e7ad Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Mon, 5 Sep 2016 21:42:32 -0400 +Subject: nfs_write_end(): fix handling of short copies + +From: Al Viro + +commit c0cf3ef5e0f47e385920450b245d22bead93e7ad upstream. + +What matters when deciding if we should make a page uptodate is +not how much we _wanted_ to copy, but how much we actually have +copied. As it is, on architectures that do not zero tail on +short copy we can leave uninitialized data in page marked uptodate. + +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/file.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/nfs/file.c ++++ b/fs/nfs/file.c +@@ -407,7 +407,7 @@ static int nfs_write_end(struct file *fi + */ + if (!PageUptodate(page)) { + unsigned pglen = nfs_page_length(page); +- unsigned end = offset + len; ++ unsigned end = offset + copied; + + if (pglen == 0) { + zero_user_segments(page, 0, offset, diff --git a/queue-4.4/pci-check-for-pme-in-targeted-sleep-state.patch b/queue-4.4/pci-check-for-pme-in-targeted-sleep-state.patch new file mode 100644 index 00000000000..178b354bfee --- /dev/null +++ b/queue-4.4/pci-check-for-pme-in-targeted-sleep-state.patch @@ -0,0 +1,48 @@ +From 6496ebd7edf446fccf8266a1a70ffcb64252593e Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Fri, 21 Oct 2016 16:45:38 -0400 +Subject: PCI: Check for PME in targeted sleep state + +From: Alan Stern + +commit 6496ebd7edf446fccf8266a1a70ffcb64252593e upstream. + +One some systems, the firmware does not allow certain PCI devices to be put +in deep D-states. This can cause problems for wakeup signalling, if the +device does not support PME# in the deepest allowed suspend state. For +example, Pierre reports that on his system, ACPI does not permit his xHCI +host controller to go into D3 during runtime suspend -- but D3 is the only +state in which the controller can generate PME# signals. As a result, the +controller goes into runtime suspend but never wakes up, so it doesn't work +properly. USB devices plugged into the controller are never detected. + +If the device relies on PME# for wakeup signals but is not capable of +generating PME# in the target state, the PCI core should accurately report +that it cannot do wakeup from runtime suspend. This patch modifies the +pci_dev_run_wake() routine to add this check. + +Reported-by: Pierre de Villemereuil +Tested-by: Pierre de Villemereuil +Signed-off-by: Alan Stern +Signed-off-by: Bjorn Helgaas +Acked-by: Rafael J. Wysocki +CC: Lukas Wunner +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pci/pci.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -2043,6 +2043,10 @@ bool pci_dev_run_wake(struct pci_dev *de + if (!dev->pme_support) + return false; + ++ /* PME-capable in principle, but not from the intended sleep state */ ++ if (!pci_pme_capable(dev, pci_target_state(dev))) ++ return false; ++ + while (bus->parent) { + struct pci_dev *bridge = bus->self; + diff --git a/queue-4.4/powerpc-convert-cmp-to-cmpd-in-idle-enter-sequence.patch b/queue-4.4/powerpc-convert-cmp-to-cmpd-in-idle-enter-sequence.patch new file mode 100644 index 00000000000..11259429219 --- /dev/null +++ b/queue-4.4/powerpc-convert-cmp-to-cmpd-in-idle-enter-sequence.patch @@ -0,0 +1,45 @@ +From 80f23935cadb1c654e81951f5a8b7ceae0acc1b4 Mon Sep 17 00:00:00 2001 +From: Segher Boessenkool +Date: Thu, 6 Oct 2016 13:42:19 +0000 +Subject: powerpc: Convert cmp to cmpd in idle enter sequence + +From: Segher Boessenkool + +commit 80f23935cadb1c654e81951f5a8b7ceae0acc1b4 upstream. + +PowerPC's "cmp" instruction has four operands. Normally people write +"cmpw" or "cmpd" for the second cmp operand 0 or 1. But, frequently +people forget, and write "cmp" with just three operands. + +With older binutils this is silently accepted as if this was "cmpw", +while often "cmpd" is wanted. With newer binutils GAS will complain +about this for 64-bit code. For 32-bit code it still silently assumes +"cmpw" is what is meant. + +In this instance the code comes directly from ISA v2.07, including the +cmp, but cmpd is correct. Backport to stable so that new toolchains can +build old kernels. + +Fixes: 948cf67c4726 ("powerpc: Add NAP mode support on Power7 in HV mode") +Reviewed-by: Vaidyanathan Srinivasan +Signed-off-by: Segher Boessenkool +Signed-off-by: Michael Ellerman +Signed-off-by: Joel Stanley +Signed-off-by: Greg Kroah-Hartman + + +--- + arch/powerpc/kernel/idle_power7.S | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/powerpc/kernel/idle_power7.S ++++ b/arch/powerpc/kernel/idle_power7.S +@@ -44,7 +44,7 @@ + std r0,0(r1); \ + ptesync; \ + ld r0,0(r1); \ +-1: cmp cr0,r0,r0; \ ++1: cmpd cr0,r0,r0; \ + bne 1b; \ + IDLE_INST; \ + b . diff --git a/queue-4.4/powerpc-ps3-fix-system-hang-with-gcc-5-builds.patch b/queue-4.4/powerpc-ps3-fix-system-hang-with-gcc-5-builds.patch new file mode 100644 index 00000000000..5f43b791a72 --- /dev/null +++ b/queue-4.4/powerpc-ps3-fix-system-hang-with-gcc-5-builds.patch @@ -0,0 +1,65 @@ +From 6dff5b67054e17c91bd630bcdda17cfca5aa4215 Mon Sep 17 00:00:00 2001 +From: Geoff Levand +Date: Tue, 29 Nov 2016 10:47:32 -0800 +Subject: powerpc/ps3: Fix system hang with GCC 5 builds + +From: Geoff Levand + +commit 6dff5b67054e17c91bd630bcdda17cfca5aa4215 upstream. + +GCC 5 generates different code for this bootwrapper null check that +causes the PS3 to hang very early in its bootup. This check is of +limited value, so just get rid of it. + +Signed-off-by: Geoff Levand +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/boot/ps3-head.S | 5 ----- + arch/powerpc/boot/ps3.c | 8 +------- + 2 files changed, 1 insertion(+), 12 deletions(-) + +--- a/arch/powerpc/boot/ps3-head.S ++++ b/arch/powerpc/boot/ps3-head.S +@@ -57,11 +57,6 @@ __system_reset_overlay: + bctr + + 1: +- /* Save the value at addr zero for a null pointer write check later. */ +- +- li r4, 0 +- lwz r3, 0(r4) +- + /* Primary delays then goes to _zimage_start in wrapper. */ + + or 31, 31, 31 /* db16cyc */ +--- a/arch/powerpc/boot/ps3.c ++++ b/arch/powerpc/boot/ps3.c +@@ -119,13 +119,12 @@ void ps3_copy_vectors(void) + flush_cache((void *)0x100, 512); + } + +-void platform_init(unsigned long null_check) ++void platform_init(void) + { + const u32 heapsize = 0x1000000 - (u32)_end; /* 16MiB */ + void *chosen; + unsigned long ft_addr; + u64 rm_size; +- unsigned long val; + + console_ops.write = ps3_console_write; + platform_ops.exit = ps3_exit; +@@ -153,11 +152,6 @@ void platform_init(unsigned long null_ch + + printf(" flat tree at 0x%lx\n\r", ft_addr); + +- val = *(unsigned long *)0; +- +- if (val != null_check) +- printf("null check failed: %lx != %lx\n\r", val, null_check); +- + ((kernel_entry_t)0)(ft_addr, 0, NULL); + + ps3_exit(); diff --git a/queue-4.4/series b/queue-4.4/series index 023c642974d..e8a658f9593 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -47,3 +47,12 @@ ib-multicast-check-ib_find_pkey-return-value.patch ib-cma-fix-a-race-condition-in-iboe_addr_get_sgid.patch media-solo6x10-fix-lockup-by-avoiding-delayed-register-write.patch input-drv260x-fix-input-device-s-parent-assignment.patch +pci-check-for-pme-in-targeted-sleep-state.patch +libceph-verify-authorize-reply-on-connect.patch +nfs_write_end-fix-handling-of-short-copies.patch +powerpc-ps3-fix-system-hang-with-gcc-5-builds.patch +powerpc-convert-cmp-to-cmpd-in-idle-enter-sequence.patch +target-user-fix-use-after-free-of-tcmu_cmds-if-they-are-expired.patch +kconfig-nconf-fix-hang-when-editing-symbol-with-a-long-prompt.patch +sg_write-bsg_write-is-not-fit-to-be-called-under-kernel_ds.patch +net-mvpp2-fix-dma-unmapping-of-tx-buffers-for-fragments.patch diff --git a/queue-4.4/sg_write-bsg_write-is-not-fit-to-be-called-under-kernel_ds.patch b/queue-4.4/sg_write-bsg_write-is-not-fit-to-be-called-under-kernel_ds.patch new file mode 100644 index 00000000000..11de2b9c98d --- /dev/null +++ b/queue-4.4/sg_write-bsg_write-is-not-fit-to-be-called-under-kernel_ds.patch @@ -0,0 +1,46 @@ +From 128394eff343fc6d2f32172f03e24829539c5835 Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Fri, 16 Dec 2016 13:42:06 -0500 +Subject: sg_write()/bsg_write() is not fit to be called under KERNEL_DS + +From: Al Viro + +commit 128394eff343fc6d2f32172f03e24829539c5835 upstream. + +Both damn things interpret userland pointers embedded into the payload; +worse, they are actually traversing those. Leaving aside the bad +API design, this is very much _not_ safe to call with KERNEL_DS. +Bail out early if that happens. + +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + block/bsg.c | 3 +++ + drivers/scsi/sg.c | 3 +++ + 2 files changed, 6 insertions(+) + +--- a/block/bsg.c ++++ b/block/bsg.c +@@ -655,6 +655,9 @@ bsg_write(struct file *file, const char + + dprintk("%s: write %Zd bytes\n", bd->name, count); + ++ if (unlikely(segment_eq(get_fs(), KERNEL_DS))) ++ return -EINVAL; ++ + bsg_set_block(bd, file); + + bytes_written = 0; +--- a/drivers/scsi/sg.c ++++ b/drivers/scsi/sg.c +@@ -592,6 +592,9 @@ sg_write(struct file *filp, const char _ + sg_io_hdr_t *hp; + unsigned char cmnd[SG_MAX_CDB_SIZE]; + ++ if (unlikely(segment_eq(get_fs(), KERNEL_DS))) ++ return -EINVAL; ++ + if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp))) + return -ENXIO; + SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sdp, diff --git a/queue-4.4/target-user-fix-use-after-free-of-tcmu_cmds-if-they-are-expired.patch b/queue-4.4/target-user-fix-use-after-free-of-tcmu_cmds-if-they-are-expired.patch new file mode 100644 index 00000000000..25e41aa1f97 --- /dev/null +++ b/queue-4.4/target-user-fix-use-after-free-of-tcmu_cmds-if-they-are-expired.patch @@ -0,0 +1,37 @@ +From d0905ca757bc40bd1ebc261a448a521b064777d7 Mon Sep 17 00:00:00 2001 +From: Andy Grover +Date: Mon, 21 Nov 2016 16:35:30 -0800 +Subject: target/user: Fix use-after-free of tcmu_cmds if they are expired + +From: Andy Grover + +commit d0905ca757bc40bd1ebc261a448a521b064777d7 upstream. + +Don't free the cmd in tcmu_check_expired_cmd, it's still referenced by +an entry in our cmd_id->cmd idr. If userspace ever resumes processing, +tcmu_handle_completions() will use the now-invalid cmd pointer. + +Instead, don't free cmd. It will be freed by tcmu_handle_completion() if +userspace ever recovers, or tcmu_free_device if not. + +Reported-by: Bryant G Ly +Tested-by: Bryant G Ly +Signed-off-by: Andy Grover +Signed-off-by: Bart Van Assche +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_user.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/target/target_core_user.c ++++ b/drivers/target/target_core_user.c +@@ -645,8 +645,6 @@ static int tcmu_check_expired_cmd(int id + target_complete_cmd(cmd->se_cmd, SAM_STAT_CHECK_CONDITION); + cmd->se_cmd = NULL; + +- kmem_cache_free(tcmu_cmd_cache, cmd); +- + return 0; + } +