From: Greg Kroah-Hartman Date: Mon, 30 Oct 2017 09:31:00 +0000 (+0100) Subject: 4.9-stable patches X-Git-Tag: v3.18.79~11 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=da65239019226e6bfbdc8d46363d4acf4accebc9;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: assoc_array-fix-a-buggy-node-splitting-case.patch can-kvaser_usb-correct-return-value-in-printout.patch can-kvaser_usb-ignore-cmd_flush_queue_reply-messages.patch can-sun4i-fix-loopback-mode.patch cfg80211-fix-connect-disconnect-edge-cases.patch drm-amd-powerplay-fix-uninitialized-variable.patch fuse-fix-readdirplus-skipping-an-entry.patch input-elan_i2c-add-elan0611-to-the-acpi-table.patch input-gtco-fix-potential-out-of-bound-access.patch kvm-ppc-fix-oops-when-checking-kvm_cap_ppc_htm.patch scsi-sg-re-fix-off-by-one-in-sg_fill_request_table.patch scsi-zfcp-fix-erp_action-use-before-initialize-in-rec-action-trace.patch spi-bcm-qspi-fix-use-after-free-in-bcm_qspi_probe-in-error-path.patch spi-uapi-spidev-add-missing-ioctl-header.patch usb-xhci-handle-error-condition-in-xhci_stop_device.patch xen-gntdev-avoid-out-of-bounds-access-in-case-of-partial-gntdev_mmap.patch --- diff --git a/queue-4.9/assoc_array-fix-a-buggy-node-splitting-case.patch b/queue-4.9/assoc_array-fix-a-buggy-node-splitting-case.patch new file mode 100644 index 00000000000..729fca2dd92 --- /dev/null +++ b/queue-4.9/assoc_array-fix-a-buggy-node-splitting-case.patch @@ -0,0 +1,122 @@ +From ea6789980fdaa610d7eb63602c746bf6ec70cd2b Mon Sep 17 00:00:00 2001 +From: David Howells +Date: Wed, 11 Oct 2017 23:32:27 +0100 +Subject: assoc_array: Fix a buggy node-splitting case + +From: David Howells + +commit ea6789980fdaa610d7eb63602c746bf6ec70cd2b upstream. + +This fixes CVE-2017-12193. + +Fix a case in the assoc_array implementation in which a new leaf is +added that needs to go into a node that happens to be full, where the +existing leaves in that node cluster together at that level to the +exclusion of new leaf. + +What needs to happen is that the existing leaves get moved out to a new +node, N1, at level + 1 and the existing node needs replacing with one, +N0, that has pointers to the new leaf and to N1. + +The code that tries to do this gets this wrong in two ways: + + (1) The pointer that should've pointed from N0 to N1 is set to point + recursively to N0 instead. + + (2) The backpointer from N0 needs to be set correctly in the case N0 is + either the root node or reached through a shortcut. + +Fix this by removing this path and using the split_node path instead, +which achieves the same end, but in a more general way (thanks to Eric +Biggers for spotting the redundancy). + +The problem manifests itself as: + + BUG: unable to handle kernel NULL pointer dereference at 0000000000000010 + IP: assoc_array_apply_edit+0x59/0xe5 + +Fixes: 3cb989501c26 ("Add a generic associative array implementation.") +Reported-and-tested-by: WU Fan +Signed-off-by: David Howells +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + lib/assoc_array.c | 51 +++++++++++++++++---------------------------------- + 1 file changed, 17 insertions(+), 34 deletions(-) + +--- a/lib/assoc_array.c ++++ b/lib/assoc_array.c +@@ -598,21 +598,31 @@ static bool assoc_array_insert_into_term + if ((edit->segment_cache[ASSOC_ARRAY_FAN_OUT] ^ base_seg) == 0) + goto all_leaves_cluster_together; + +- /* Otherwise we can just insert a new node ahead of the old +- * one. ++ /* Otherwise all the old leaves cluster in the same slot, but ++ * the new leaf wants to go into a different slot - so we ++ * create a new node (n0) to hold the new leaf and a pointer to ++ * a new node (n1) holding all the old leaves. ++ * ++ * This can be done by falling through to the node splitting ++ * path. + */ +- goto present_leaves_cluster_but_not_new_leaf; ++ pr_devel("present leaves cluster but not new leaf\n"); + } + + split_node: + pr_devel("split node\n"); + +- /* We need to split the current node; we know that the node doesn't +- * simply contain a full set of leaves that cluster together (it +- * contains meta pointers and/or non-clustering leaves). ++ /* We need to split the current node. The node must contain anything ++ * from a single leaf (in the one leaf case, this leaf will cluster ++ * with the new leaf) and the rest meta-pointers, to all leaves, some ++ * of which may cluster. ++ * ++ * It won't contain the case in which all the current leaves plus the ++ * new leaves want to cluster in the same slot. + * + * We need to expel at least two leaves out of a set consisting of the +- * leaves in the node and the new leaf. ++ * leaves in the node and the new leaf. The current meta pointers can ++ * just be copied as they shouldn't cluster with any of the leaves. + * + * We need a new node (n0) to replace the current one and a new node to + * take the expelled nodes (n1). +@@ -717,33 +727,6 @@ found_slot_for_multiple_occupancy: + pr_devel("<--%s() = ok [split node]\n", __func__); + return true; + +-present_leaves_cluster_but_not_new_leaf: +- /* All the old leaves cluster in the same slot, but the new leaf wants +- * to go into a different slot, so we create a new node to hold the new +- * leaf and a pointer to a new node holding all the old leaves. +- */ +- pr_devel("present leaves cluster but not new leaf\n"); +- +- new_n0->back_pointer = node->back_pointer; +- new_n0->parent_slot = node->parent_slot; +- new_n0->nr_leaves_on_branch = node->nr_leaves_on_branch; +- new_n1->back_pointer = assoc_array_node_to_ptr(new_n0); +- new_n1->parent_slot = edit->segment_cache[0]; +- new_n1->nr_leaves_on_branch = node->nr_leaves_on_branch; +- edit->adjust_count_on = new_n0; +- +- for (i = 0; i < ASSOC_ARRAY_FAN_OUT; i++) +- new_n1->slots[i] = node->slots[i]; +- +- new_n0->slots[edit->segment_cache[0]] = assoc_array_node_to_ptr(new_n0); +- edit->leaf_p = &new_n0->slots[edit->segment_cache[ASSOC_ARRAY_FAN_OUT]]; +- +- edit->set[0].ptr = &assoc_array_ptr_to_node(node->back_pointer)->slots[node->parent_slot]; +- edit->set[0].to = assoc_array_node_to_ptr(new_n0); +- edit->excised_meta[0] = assoc_array_node_to_ptr(node); +- pr_devel("<--%s() = ok [insert node before]\n", __func__); +- return true; +- + all_leaves_cluster_together: + /* All the leaves, new and old, want to cluster together in this node + * in the same slot, so we have to replace this node with a shortcut to diff --git a/queue-4.9/can-kvaser_usb-correct-return-value-in-printout.patch b/queue-4.9/can-kvaser_usb-correct-return-value-in-printout.patch new file mode 100644 index 00000000000..becc0837686 --- /dev/null +++ b/queue-4.9/can-kvaser_usb-correct-return-value-in-printout.patch @@ -0,0 +1,33 @@ +From 8f65a923e6b628e187d5e791cf49393dd5e8c2f9 Mon Sep 17 00:00:00 2001 +From: Jimmy Assarsson +Date: Tue, 24 Oct 2017 12:23:28 +0200 +Subject: can: kvaser_usb: Correct return value in printout + +From: Jimmy Assarsson + +commit 8f65a923e6b628e187d5e791cf49393dd5e8c2f9 upstream. + +If the return value from kvaser_usb_send_simple_msg() was non-zero, the +return value from kvaser_usb_flush_queue() was printed in the kernel +warning. + +Signed-off-by: Jimmy Assarsson +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/can/usb/kvaser_usb.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/can/usb/kvaser_usb.c ++++ b/drivers/net/can/usb/kvaser_usb.c +@@ -1609,7 +1609,8 @@ static int kvaser_usb_close(struct net_d + if (err) + netdev_warn(netdev, "Cannot flush queue, error %d\n", err); + +- if (kvaser_usb_send_simple_msg(dev, CMD_RESET_CHIP, priv->channel)) ++ err = kvaser_usb_send_simple_msg(dev, CMD_RESET_CHIP, priv->channel); ++ if (err) + netdev_warn(netdev, "Cannot reset card, error %d\n", err); + + err = kvaser_usb_stop_chip(priv); diff --git a/queue-4.9/can-kvaser_usb-ignore-cmd_flush_queue_reply-messages.patch b/queue-4.9/can-kvaser_usb-ignore-cmd_flush_queue_reply-messages.patch new file mode 100644 index 00000000000..22131b5c28f --- /dev/null +++ b/queue-4.9/can-kvaser_usb-ignore-cmd_flush_queue_reply-messages.patch @@ -0,0 +1,50 @@ +From e1d2d1329a5722dbecc9c278303fcc4aa01f8790 Mon Sep 17 00:00:00 2001 +From: Jimmy Assarsson +Date: Tue, 24 Oct 2017 12:23:29 +0200 +Subject: can: kvaser_usb: Ignore CMD_FLUSH_QUEUE_REPLY messages + +From: Jimmy Assarsson + +commit e1d2d1329a5722dbecc9c278303fcc4aa01f8790 upstream. + +To avoid kernel warning "Unhandled message (68)", ignore the +CMD_FLUSH_QUEUE_REPLY message for now. + +As of Leaf v2 firmware version v4.1.844 (2017-02-15), flush tx queue is +synchronous. There is a capability bit indicating whether flushing tx +queue is synchronous or asynchronous. + +A proper solution would be to query the device for capabilities. If the +synchronous tx flush capability bit is set, we should wait for +CMD_FLUSH_QUEUE_REPLY message, while flushing the tx queue. + +Signed-off-by: Jimmy Assarsson +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/can/usb/kvaser_usb.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/net/can/usb/kvaser_usb.c ++++ b/drivers/net/can/usb/kvaser_usb.c +@@ -137,6 +137,7 @@ static inline bool kvaser_is_usbcan(cons + #define CMD_RESET_ERROR_COUNTER 49 + #define CMD_TX_ACKNOWLEDGE 50 + #define CMD_CAN_ERROR_EVENT 51 ++#define CMD_FLUSH_QUEUE_REPLY 68 + + #define CMD_LEAF_USB_THROTTLE 77 + #define CMD_LEAF_LOG_MESSAGE 106 +@@ -1301,6 +1302,11 @@ static void kvaser_usb_handle_message(co + goto warn; + break; + ++ case CMD_FLUSH_QUEUE_REPLY: ++ if (dev->family != KVASER_LEAF) ++ goto warn; ++ break; ++ + default: + warn: dev_warn(dev->udev->dev.parent, + "Unhandled message (%d)\n", msg->id); diff --git a/queue-4.9/can-sun4i-fix-loopback-mode.patch b/queue-4.9/can-sun4i-fix-loopback-mode.patch new file mode 100644 index 00000000000..2ec913be3e0 --- /dev/null +++ b/queue-4.9/can-sun4i-fix-loopback-mode.patch @@ -0,0 +1,38 @@ +From 3a379f5b36ae039dfeb6f73316e47ab1af4945df Mon Sep 17 00:00:00 2001 +From: Gerhard Bertelsmann +Date: Thu, 17 Aug 2017 15:59:49 +0200 +Subject: can: sun4i: fix loopback mode + +From: Gerhard Bertelsmann + +commit 3a379f5b36ae039dfeb6f73316e47ab1af4945df upstream. + +Fix loopback mode by setting the right flag and remove presume mode. + +Signed-off-by: Gerhard Bertelsmann +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/can/sun4i_can.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/net/can/sun4i_can.c ++++ b/drivers/net/can/sun4i_can.c +@@ -342,7 +342,7 @@ static int sun4i_can_start(struct net_de + + /* enter the selected mode */ + mod_reg_val = readl(priv->base + SUN4I_REG_MSEL_ADDR); +- if (priv->can.ctrlmode & CAN_CTRLMODE_PRESUME_ACK) ++ if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) + mod_reg_val |= SUN4I_MSEL_LOOPBACK_MODE; + else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) + mod_reg_val |= SUN4I_MSEL_LISTEN_ONLY_MODE; +@@ -811,7 +811,6 @@ static int sun4ican_probe(struct platfor + priv->can.ctrlmode_supported = CAN_CTRLMODE_BERR_REPORTING | + CAN_CTRLMODE_LISTENONLY | + CAN_CTRLMODE_LOOPBACK | +- CAN_CTRLMODE_PRESUME_ACK | + CAN_CTRLMODE_3_SAMPLES; + priv->base = addr; + priv->clk = clk; diff --git a/queue-4.9/cfg80211-fix-connect-disconnect-edge-cases.patch b/queue-4.9/cfg80211-fix-connect-disconnect-edge-cases.patch new file mode 100644 index 00000000000..bcf4fedf166 --- /dev/null +++ b/queue-4.9/cfg80211-fix-connect-disconnect-edge-cases.patch @@ -0,0 +1,111 @@ +From 51e13359cd5ea34acc62c90627603352956380af Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Tue, 17 Oct 2017 21:56:20 +0200 +Subject: cfg80211: fix connect/disconnect edge cases + +From: Johannes Berg + +commit 51e13359cd5ea34acc62c90627603352956380af upstream. + +If we try to connect while already connected/connecting, but +this fails, we set ssid_len=0 but leave current_bss hanging, +leading to errors. + +Check all of this better, first of all ensuring that we can't +try to connect to a different SSID while connected/ing; ensure +that prev_bssid is set for re-association attempts even in the +case of the driver supporting the connect() method, and don't +reset ssid_len in the failure cases. + +While at it, also reset ssid_len while disconnecting unless we +were connected and expect a disconnected event, and warn on a +successful connection without ssid_len being set. + +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + net/wireless/sme.c | 50 +++++++++++++++++++++++++++++++++++++++++--------- + 1 file changed, 41 insertions(+), 9 deletions(-) + +--- a/net/wireless/sme.c ++++ b/net/wireless/sme.c +@@ -505,11 +505,6 @@ static int cfg80211_sme_connect(struct w + return -EOPNOTSUPP; + + if (wdev->current_bss) { +- if (!prev_bssid) +- return -EALREADY; +- if (prev_bssid && +- !ether_addr_equal(prev_bssid, wdev->current_bss->pub.bssid)) +- return -ENOTCONN; + cfg80211_unhold_bss(wdev->current_bss); + cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub); + wdev->current_bss = NULL; +@@ -1025,11 +1020,35 @@ int cfg80211_connect(struct cfg80211_reg + + ASSERT_WDEV_LOCK(wdev); + +- if (WARN_ON(wdev->connect_keys)) { +- kzfree(wdev->connect_keys); +- wdev->connect_keys = NULL; ++ /* ++ * If we have an ssid_len, we're trying to connect or are ++ * already connected, so reject a new SSID unless it's the ++ * same (which is the case for re-association.) ++ */ ++ if (wdev->ssid_len && ++ (wdev->ssid_len != connect->ssid_len || ++ memcmp(wdev->ssid, connect->ssid, wdev->ssid_len))) ++ return -EALREADY; ++ ++ /* ++ * If connected, reject (re-)association unless prev_bssid ++ * matches the current BSSID. ++ */ ++ if (wdev->current_bss) { ++ if (!prev_bssid) ++ return -EALREADY; ++ if (!ether_addr_equal(prev_bssid, wdev->current_bss->pub.bssid)) ++ return -ENOTCONN; + } + ++ /* ++ * Reject if we're in the process of connecting with WEP, ++ * this case isn't very interesting and trying to handle ++ * it would make the code much more complex. ++ */ ++ if (wdev->connect_keys) ++ return -EINPROGRESS; ++ + cfg80211_oper_and_ht_capa(&connect->ht_capa_mask, + rdev->wiphy.ht_capa_mod_mask); + +@@ -1080,7 +1099,12 @@ int cfg80211_connect(struct cfg80211_reg + + if (err) { + wdev->connect_keys = NULL; +- wdev->ssid_len = 0; ++ /* ++ * This could be reassoc getting refused, don't clear ++ * ssid_len in that case. ++ */ ++ if (!wdev->current_bss) ++ wdev->ssid_len = 0; + return err; + } + +@@ -1105,5 +1129,13 @@ int cfg80211_disconnect(struct cfg80211_ + else if (wdev->current_bss) + err = rdev_disconnect(rdev, dev, reason); + ++ /* ++ * Clear ssid_len unless we actually were fully connected, ++ * in which case cfg80211_disconnected() will take care of ++ * this later. ++ */ ++ if (!wdev->current_bss) ++ wdev->ssid_len = 0; ++ + return err; + } diff --git a/queue-4.9/drm-amd-powerplay-fix-uninitialized-variable.patch b/queue-4.9/drm-amd-powerplay-fix-uninitialized-variable.patch new file mode 100644 index 00000000000..8b64c5e6cff --- /dev/null +++ b/queue-4.9/drm-amd-powerplay-fix-uninitialized-variable.patch @@ -0,0 +1,56 @@ +From 8b95f4f730cba02ef6febbdc4ca7e55ca045b00e Mon Sep 17 00:00:00 2001 +From: Rex Zhu +Date: Fri, 20 Oct 2017 15:07:41 +0800 +Subject: drm/amd/powerplay: fix uninitialized variable + +From: Rex Zhu + +commit 8b95f4f730cba02ef6febbdc4ca7e55ca045b00e upstream. + +refresh_rate was not initialized when program +display gap. +this patch can fix vce ring test failed +when do S3 on Polaris10. + +bug: https://bugs.freedesktop.org/show_bug.cgi?id=103102 +bug: https://bugzilla.kernel.org/show_bug.cgi?id=196615 +Reviewed-by: Alex Deucher +Signed-off-by: Rex Zhu +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c ++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c +@@ -825,7 +825,7 @@ uint32_t smu7_get_xclk(struct pp_hwmgr * + { + uint32_t reference_clock, tmp; + struct cgs_display_info info = {0}; +- struct cgs_mode_info mode_info; ++ struct cgs_mode_info mode_info = {0}; + + info.mode_info = &mode_info; + +@@ -3718,10 +3718,9 @@ int smu7_program_display_gap(struct pp_h + uint32_t ref_clock; + uint32_t refresh_rate = 0; + struct cgs_display_info info = {0}; +- struct cgs_mode_info mode_info; ++ struct cgs_mode_info mode_info = {0}; + + info.mode_info = &mode_info; +- + cgs_get_active_displays_info(hwmgr->device, &info); + num_active_displays = info.display_count; + +@@ -3737,6 +3736,7 @@ int smu7_program_display_gap(struct pp_h + frame_time_in_us = 1000000 / refresh_rate; + + pre_vbi_time_in_us = frame_time_in_us - 200 - mode_info.vblank_time_us; ++ + data->frame_time_x2 = frame_time_in_us * 2 / 100; + + display_gap2 = pre_vbi_time_in_us * (ref_clock / 100); diff --git a/queue-4.9/fuse-fix-readdirplus-skipping-an-entry.patch b/queue-4.9/fuse-fix-readdirplus-skipping-an-entry.patch new file mode 100644 index 00000000000..e727925db4a --- /dev/null +++ b/queue-4.9/fuse-fix-readdirplus-skipping-an-entry.patch @@ -0,0 +1,40 @@ +From c6cdd51404b7ac12dd95173ddfc548c59ecf037f Mon Sep 17 00:00:00 2001 +From: Miklos Szeredi +Date: Wed, 25 Oct 2017 16:34:27 +0200 +Subject: fuse: fix READDIRPLUS skipping an entry + +From: Miklos Szeredi + +commit c6cdd51404b7ac12dd95173ddfc548c59ecf037f upstream. + +Marios Titas running a Haskell program noticed a problem with fuse's +readdirplus: when it is interrupted by a signal, it skips one directory +entry. + +The reason is that fuse erronously updates ctx->pos after a failed +dir_emit(). + +The issue originates from the patch adding readdirplus support. + +Reported-by: Jakob Unterwurzacher +Tested-by: Marios Titas +Signed-off-by: Miklos Szeredi +Fixes: 0b05b18381ee ("fuse: implement NFS-like readdirplus support") +Signed-off-by: Greg Kroah-Hartman + +--- + fs/fuse/dir.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/fuse/dir.c ++++ b/fs/fuse/dir.c +@@ -1312,7 +1312,8 @@ static int parse_dirplusfile(char *buf, + */ + over = !dir_emit(ctx, dirent->name, dirent->namelen, + dirent->ino, dirent->type); +- ctx->pos = dirent->off; ++ if (!over) ++ ctx->pos = dirent->off; + } + + buf += reclen; diff --git a/queue-4.9/input-elan_i2c-add-elan0611-to-the-acpi-table.patch b/queue-4.9/input-elan_i2c-add-elan0611-to-the-acpi-table.patch new file mode 100644 index 00000000000..e7448e5973a --- /dev/null +++ b/queue-4.9/input-elan_i2c-add-elan0611-to-the-acpi-table.patch @@ -0,0 +1,36 @@ +From 57a95b41869b8f0d1949c24df2a9dac1ca7082ee Mon Sep 17 00:00:00 2001 +From: Kai-Heng Feng +Date: Tue, 24 Oct 2017 11:08:18 -0700 +Subject: Input: elan_i2c - add ELAN0611 to the ACPI table + +From: Kai-Heng Feng + +commit 57a95b41869b8f0d1949c24df2a9dac1ca7082ee upstream. + +ELAN0611 touchpad uses elan_i2c as its driver. It can be found +on Lenovo ideapad 320-15IKB. + +So add it to ACPI table to enable the touchpad. + +[Ido Adiv reports that the same ACPI ID is used for +Elan touchpad in ideapad 520]. + +BugLink: https://bugs.launchpad.net/bugs/1723736 +Signed-off-by: Kai-Heng Feng +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/input/mouse/elan_i2c_core.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/input/mouse/elan_i2c_core.c ++++ b/drivers/input/mouse/elan_i2c_core.c +@@ -1240,6 +1240,7 @@ static const struct acpi_device_id elan_ + { "ELAN0605", 0 }, + { "ELAN0609", 0 }, + { "ELAN060B", 0 }, ++ { "ELAN0611", 0 }, + { "ELAN1000", 0 }, + { } + }; diff --git a/queue-4.9/input-gtco-fix-potential-out-of-bound-access.patch b/queue-4.9/input-gtco-fix-potential-out-of-bound-access.patch new file mode 100644 index 00000000000..81b2df8e367 --- /dev/null +++ b/queue-4.9/input-gtco-fix-potential-out-of-bound-access.patch @@ -0,0 +1,57 @@ +From a50829479f58416a013a4ccca791336af3c584c7 Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Mon, 23 Oct 2017 16:46:00 -0700 +Subject: Input: gtco - fix potential out-of-bound access + +From: Dmitry Torokhov + +commit a50829479f58416a013a4ccca791336af3c584c7 upstream. + +parse_hid_report_descriptor() has a while (i < length) loop, which +only guarantees that there's at least 1 byte in the buffer, but the +loop body can read multiple bytes which causes out-of-bounds access. + +Reported-by: Andrey Konovalov +Reviewed-by: Andrey Konovalov +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/input/tablet/gtco.c | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +--- a/drivers/input/tablet/gtco.c ++++ b/drivers/input/tablet/gtco.c +@@ -230,13 +230,17 @@ static void parse_hid_report_descriptor( + + /* Walk this report and pull out the info we need */ + while (i < length) { +- prefix = report[i]; +- +- /* Skip over prefix */ +- i++; ++ prefix = report[i++]; + + /* Determine data size and save the data in the proper variable */ +- size = PREF_SIZE(prefix); ++ size = (1U << PREF_SIZE(prefix)) >> 1; ++ if (i + size > length) { ++ dev_err(ddev, ++ "Not enough data (need %d, have %d)\n", ++ i + size, length); ++ break; ++ } ++ + switch (size) { + case 1: + data = report[i]; +@@ -244,8 +248,7 @@ static void parse_hid_report_descriptor( + case 2: + data16 = get_unaligned_le16(&report[i]); + break; +- case 3: +- size = 4; ++ case 4: + data32 = get_unaligned_le32(&report[i]); + break; + } diff --git a/queue-4.9/kvm-ppc-fix-oops-when-checking-kvm_cap_ppc_htm.patch b/queue-4.9/kvm-ppc-fix-oops-when-checking-kvm_cap_ppc_htm.patch new file mode 100644 index 00000000000..57c63deb4c8 --- /dev/null +++ b/queue-4.9/kvm-ppc-fix-oops-when-checking-kvm_cap_ppc_htm.patch @@ -0,0 +1,54 @@ +From ac64115a66c18c01745bbd3c47a36b124e5fd8c0 Mon Sep 17 00:00:00 2001 +From: Greg Kurz +Date: Thu, 14 Sep 2017 23:56:25 +0200 +Subject: KVM: PPC: Fix oops when checking KVM_CAP_PPC_HTM + +From: Greg Kurz + +commit ac64115a66c18c01745bbd3c47a36b124e5fd8c0 upstream. + +The following program causes a kernel oops: + +#include +#include +#include +#include +#include + +main() +{ + int fd = open("/dev/kvm", O_RDWR); + ioctl(fd, KVM_CHECK_EXTENSION, KVM_CAP_PPC_HTM); +} + +This happens because when using the global KVM fd with +KVM_CHECK_EXTENSION, kvm_vm_ioctl_check_extension() gets +called with a NULL kvm argument, which gets dereferenced +in is_kvmppc_hv_enabled(). Spotted while reading the code. + +Let's use the hv_enabled fallback variable, like everywhere +else in this function. + +Fixes: 23528bb21ee2 ("KVM: PPC: Introduce KVM_CAP_PPC_HTM") +Signed-off-by: Greg Kurz +Reviewed-by: David Gibson +Reviewed-by: Thomas Huth +Signed-off-by: Paul Mackerras +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/kvm/powerpc.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/arch/powerpc/kvm/powerpc.c ++++ b/arch/powerpc/kvm/powerpc.c +@@ -601,8 +601,7 @@ int kvm_vm_ioctl_check_extension(struct + break; + #endif + case KVM_CAP_PPC_HTM: +- r = cpu_has_feature(CPU_FTR_TM_COMP) && +- is_kvmppc_hv_enabled(kvm); ++ r = cpu_has_feature(CPU_FTR_TM_COMP) && hv_enabled; + break; + default: + r = 0; diff --git a/queue-4.9/scsi-sg-re-fix-off-by-one-in-sg_fill_request_table.patch b/queue-4.9/scsi-sg-re-fix-off-by-one-in-sg_fill_request_table.patch new file mode 100644 index 00000000000..baa48719098 --- /dev/null +++ b/queue-4.9/scsi-sg-re-fix-off-by-one-in-sg_fill_request_table.patch @@ -0,0 +1,38 @@ +From 587c3c9f286cee5c9cac38d28c8ae1875f4ec85b Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +Date: Sun, 15 Oct 2017 18:16:33 +0100 +Subject: scsi: sg: Re-fix off by one in sg_fill_request_table() + +From: Ben Hutchings + +commit 587c3c9f286cee5c9cac38d28c8ae1875f4ec85b upstream. + +Commit 109bade9c625 ("scsi: sg: use standard lists for sg_requests") +introduced an off-by-one error in sg_ioctl(), which was fixed by commit +bd46fc406b30 ("scsi: sg: off by one in sg_ioctl()"). + +Unfortunately commit 4759df905a47 ("scsi: sg: factor out +sg_fill_request_table()") moved that code, and reintroduced the +bug (perhaps due to a botched rebase). Fix it again. + +Fixes: 4759df905a47 ("scsi: sg: factor out sg_fill_request_table()") +Signed-off-by: Ben Hutchings +Acked-by: Douglas Gilbert +Signed-off-by: Martin K. Petersen +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 +@@ -837,7 +837,7 @@ sg_fill_request_table(Sg_fd *sfp, sg_req + + val = 0; + list_for_each_entry(srp, &sfp->rq_list, entry) { +- if (val > SG_MAX_QUEUE) ++ if (val >= SG_MAX_QUEUE) + break; + rinfo[val].req_state = srp->done + 1; + rinfo[val].problem = diff --git a/queue-4.9/scsi-zfcp-fix-erp_action-use-before-initialize-in-rec-action-trace.patch b/queue-4.9/scsi-zfcp-fix-erp_action-use-before-initialize-in-rec-action-trace.patch new file mode 100644 index 00000000000..947e6a5ce44 --- /dev/null +++ b/queue-4.9/scsi-zfcp-fix-erp_action-use-before-initialize-in-rec-action-trace.patch @@ -0,0 +1,170 @@ +From ab31fd0ce65ec93828b617123792c1bb7c6dcc42 Mon Sep 17 00:00:00 2001 +From: Steffen Maier +Date: Fri, 13 Oct 2017 15:40:07 +0200 +Subject: scsi: zfcp: fix erp_action use-before-initialize in REC action trace + +From: Steffen Maier + +commit ab31fd0ce65ec93828b617123792c1bb7c6dcc42 upstream. + +v4.10 commit 6f2ce1c6af37 ("scsi: zfcp: fix rport unblock race with LUN +recovery") extended accessing parent pointer fields of struct +zfcp_erp_action for tracing. If an erp_action has never been enqueued +before, these parent pointer fields are uninitialized and NULL. Examples +are zfcp objects freshly added to the parent object's children list, +before enqueueing their first recovery subsequently. In +zfcp_erp_try_rport_unblock(), we iterate such list. Accessing erp_action +fields can cause a NULL pointer dereference. Since the kernel can read +from lowcore on s390, it does not immediately cause a kernel page +fault. Instead it can cause hangs on trying to acquire the wrong +erp_action->adapter->dbf->rec_lock in zfcp_dbf_rec_action_lvl() + ^bogus^ +while holding already other locks with IRQs disabled. + +Real life example from attaching lots of LUNs in parallel on many CPUs: + +crash> bt 17723 +PID: 17723 TASK: ... CPU: 25 COMMAND: "zfcperp0.0.1800" + LOWCORE INFO: + -psw : 0x0404300180000000 0x000000000038e424 + -function : _raw_spin_lock_wait_flags at 38e424 +... + #0 [fdde8fc90] zfcp_dbf_rec_action_lvl at 3e0004e9862 [zfcp] + #1 [fdde8fce8] zfcp_erp_try_rport_unblock at 3e0004dfddc [zfcp] + #2 [fdde8fd38] zfcp_erp_strategy at 3e0004e0234 [zfcp] + #3 [fdde8fda8] zfcp_erp_thread at 3e0004e0a12 [zfcp] + #4 [fdde8fe60] kthread at 173550 + #5 [fdde8feb8] kernel_thread_starter at 10add2 + +zfcp_adapter + zfcp_port + zfcp_unit
, 0x404040d600000000 + scsi_device NULL, returning early! +zfcp_scsi_dev.status = 0x40000000 +0x40000000 ZFCP_STATUS_COMMON_RUNNING + +crash> zfcp_unit
+struct zfcp_unit { + erp_action = { + adapter = 0x0, + port = 0x0, + unit = 0x0, + }, +} + +zfcp_erp_action is always fully embedded into its container object. Such +container object is never moved in its object tree (only add or delete). +Hence, erp_action parent pointers can never change. + +To fix the issue, initialize the erp_action parent pointers before +adding the erp_action container to any list and thus before it becomes +accessible from outside of its initializing function. + +In order to also close the time window between zfcp_erp_setup_act() +memsetting the entire erp_action to zero and setting the parent pointers +again, drop the memset and instead explicitly initialize individually +all erp_action fields except for parent pointers. To be extra careful +not to introduce any other unintended side effect, even keep zeroing the +erp_action fields for list and timer. Also double-check with +WARN_ON_ONCE that erp_action parent pointers never change, so we get to +know when we would deviate from previous behavior. + +Signed-off-by: Steffen Maier +Fixes: 6f2ce1c6af37 ("scsi: zfcp: fix rport unblock race with LUN recovery") +Reviewed-by: Benjamin Block +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/s390/scsi/zfcp_aux.c | 5 +++++ + drivers/s390/scsi/zfcp_erp.c | 18 +++++++++++------- + drivers/s390/scsi/zfcp_scsi.c | 5 +++++ + 3 files changed, 21 insertions(+), 7 deletions(-) + +--- a/drivers/s390/scsi/zfcp_aux.c ++++ b/drivers/s390/scsi/zfcp_aux.c +@@ -358,6 +358,8 @@ struct zfcp_adapter *zfcp_adapter_enqueu + + adapter->next_port_scan = jiffies; + ++ adapter->erp_action.adapter = adapter; ++ + if (zfcp_qdio_setup(adapter)) + goto failed; + +@@ -514,6 +516,9 @@ struct zfcp_port *zfcp_port_enqueue(stru + port->dev.groups = zfcp_port_attr_groups; + port->dev.release = zfcp_port_release; + ++ port->erp_action.adapter = adapter; ++ port->erp_action.port = port; ++ + if (dev_set_name(&port->dev, "0x%016llx", (unsigned long long)wwpn)) { + kfree(port); + goto err_out; +--- a/drivers/s390/scsi/zfcp_erp.c ++++ b/drivers/s390/scsi/zfcp_erp.c +@@ -193,9 +193,8 @@ static struct zfcp_erp_action *zfcp_erp_ + atomic_or(ZFCP_STATUS_COMMON_ERP_INUSE, + &zfcp_sdev->status); + erp_action = &zfcp_sdev->erp_action; +- memset(erp_action, 0, sizeof(struct zfcp_erp_action)); +- erp_action->port = port; +- erp_action->sdev = sdev; ++ WARN_ON_ONCE(erp_action->port != port); ++ WARN_ON_ONCE(erp_action->sdev != sdev); + if (!(atomic_read(&zfcp_sdev->status) & + ZFCP_STATUS_COMMON_RUNNING)) + act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; +@@ -208,8 +207,8 @@ static struct zfcp_erp_action *zfcp_erp_ + zfcp_erp_action_dismiss_port(port); + atomic_or(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status); + erp_action = &port->erp_action; +- memset(erp_action, 0, sizeof(struct zfcp_erp_action)); +- erp_action->port = port; ++ WARN_ON_ONCE(erp_action->port != port); ++ WARN_ON_ONCE(erp_action->sdev != NULL); + if (!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_RUNNING)) + act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; + break; +@@ -219,7 +218,8 @@ static struct zfcp_erp_action *zfcp_erp_ + zfcp_erp_action_dismiss_adapter(adapter); + atomic_or(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status); + erp_action = &adapter->erp_action; +- memset(erp_action, 0, sizeof(struct zfcp_erp_action)); ++ WARN_ON_ONCE(erp_action->port != NULL); ++ WARN_ON_ONCE(erp_action->sdev != NULL); + if (!(atomic_read(&adapter->status) & + ZFCP_STATUS_COMMON_RUNNING)) + act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; +@@ -229,7 +229,11 @@ static struct zfcp_erp_action *zfcp_erp_ + return NULL; + } + +- erp_action->adapter = adapter; ++ WARN_ON_ONCE(erp_action->adapter != adapter); ++ memset(&erp_action->list, 0, sizeof(erp_action->list)); ++ memset(&erp_action->timer, 0, sizeof(erp_action->timer)); ++ erp_action->step = ZFCP_ERP_STEP_UNINITIALIZED; ++ erp_action->fsf_req_id = 0; + erp_action->action = need; + erp_action->status = act_status; + +--- a/drivers/s390/scsi/zfcp_scsi.c ++++ b/drivers/s390/scsi/zfcp_scsi.c +@@ -115,10 +115,15 @@ static int zfcp_scsi_slave_alloc(struct + struct zfcp_unit *unit; + int npiv = adapter->connection_features & FSF_FEATURE_NPIV_MODE; + ++ zfcp_sdev->erp_action.adapter = adapter; ++ zfcp_sdev->erp_action.sdev = sdev; ++ + port = zfcp_get_port_by_wwpn(adapter, rport->port_name); + if (!port) + return -ENXIO; + ++ zfcp_sdev->erp_action.port = port; ++ + unit = zfcp_unit_find(port, zfcp_scsi_dev_lun(sdev)); + if (unit) + put_device(&unit->dev); diff --git a/queue-4.9/series b/queue-4.9/series index cbc1250ab53..39b5cf170b4 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -2,3 +2,19 @@ workqueue-replace-pool-manager_arb-mutex-with-a-flag.patch alsa-hda-realtek-add-support-for-alc236-alc3204.patch alsa-hda-fix-headset-mic-problem-for-dell-machines-with-alc236.patch ceph-unlock-dangling-spinlock-in-try_flush_caps.patch +usb-xhci-handle-error-condition-in-xhci_stop_device.patch +kvm-ppc-fix-oops-when-checking-kvm_cap_ppc_htm.patch +spi-uapi-spidev-add-missing-ioctl-header.patch +spi-bcm-qspi-fix-use-after-free-in-bcm_qspi_probe-in-error-path.patch +fuse-fix-readdirplus-skipping-an-entry.patch +xen-gntdev-avoid-out-of-bounds-access-in-case-of-partial-gntdev_mmap.patch +input-elan_i2c-add-elan0611-to-the-acpi-table.patch +input-gtco-fix-potential-out-of-bound-access.patch +assoc_array-fix-a-buggy-node-splitting-case.patch +scsi-zfcp-fix-erp_action-use-before-initialize-in-rec-action-trace.patch +scsi-sg-re-fix-off-by-one-in-sg_fill_request_table.patch +drm-amd-powerplay-fix-uninitialized-variable.patch +can-sun4i-fix-loopback-mode.patch +can-kvaser_usb-correct-return-value-in-printout.patch +can-kvaser_usb-ignore-cmd_flush_queue_reply-messages.patch +cfg80211-fix-connect-disconnect-edge-cases.patch diff --git a/queue-4.9/spi-bcm-qspi-fix-use-after-free-in-bcm_qspi_probe-in-error-path.patch b/queue-4.9/spi-bcm-qspi-fix-use-after-free-in-bcm_qspi_probe-in-error-path.patch new file mode 100644 index 00000000000..2abab4e5112 --- /dev/null +++ b/queue-4.9/spi-bcm-qspi-fix-use-after-free-in-bcm_qspi_probe-in-error-path.patch @@ -0,0 +1,64 @@ +From c0368e4db4a3e8a3dce40f3f621c06e14c560d79 Mon Sep 17 00:00:00 2001 +From: Florian Fainelli +Date: Wed, 11 Oct 2017 14:59:22 -0700 +Subject: spi: bcm-qspi: Fix use after free in bcm_qspi_probe() in error path + +From: Florian Fainelli + +commit c0368e4db4a3e8a3dce40f3f621c06e14c560d79 upstream. + +There was an inversion in how the error path in bcm_qspi_probe() is done +which would make us trip over a KASAN use-after-free report. Turns out +that qspi->dev_ids does not get allocated until later in the probe +process. Fix this by introducing a new lable: qspi_resource_err which +takes care of cleaning up the SPI master instance. + +Fixes: fa236a7ef240 ("spi: bcm-qspi: Add Broadcom MSPI driver") +Signed-off-by: Florian Fainelli +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/spi/spi-bcm-qspi.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- a/drivers/spi/spi-bcm-qspi.c ++++ b/drivers/spi/spi-bcm-qspi.c +@@ -1215,7 +1215,7 @@ int bcm_qspi_probe(struct platform_devic + goto qspi_probe_err; + } + } else { +- goto qspi_probe_err; ++ goto qspi_resource_err; + } + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "bspi"); +@@ -1237,7 +1237,7 @@ int bcm_qspi_probe(struct platform_devic + qspi->base[CHIP_SELECT] = devm_ioremap_resource(dev, res); + if (IS_ERR(qspi->base[CHIP_SELECT])) { + ret = PTR_ERR(qspi->base[CHIP_SELECT]); +- goto qspi_probe_err; ++ goto qspi_resource_err; + } + } + +@@ -1245,7 +1245,7 @@ int bcm_qspi_probe(struct platform_devic + GFP_KERNEL); + if (!qspi->dev_ids) { + ret = -ENOMEM; +- goto qspi_probe_err; ++ goto qspi_resource_err; + } + + for (val = 0; val < num_irqs; val++) { +@@ -1334,8 +1334,9 @@ qspi_reg_err: + bcm_qspi_hw_uninit(qspi); + clk_disable_unprepare(qspi->clk); + qspi_probe_err: +- spi_master_put(master); + kfree(qspi->dev_ids); ++qspi_resource_err: ++ spi_master_put(master); + return ret; + } + /* probe function to be called by SoC specific platform driver probe */ diff --git a/queue-4.9/spi-uapi-spidev-add-missing-ioctl-header.patch b/queue-4.9/spi-uapi-spidev-add-missing-ioctl-header.patch new file mode 100644 index 00000000000..e5140d4ec14 --- /dev/null +++ b/queue-4.9/spi-uapi-spidev-add-missing-ioctl-header.patch @@ -0,0 +1,38 @@ +From a2b4a79b88b24c49d98d45a06a014ffd22ada1a4 Mon Sep 17 00:00:00 2001 +From: Baruch Siach +Date: Sun, 10 Sep 2017 20:29:45 +0300 +Subject: spi: uapi: spidev: add missing ioctl header + +From: Baruch Siach + +commit a2b4a79b88b24c49d98d45a06a014ffd22ada1a4 upstream. + +The SPI_IOC_MESSAGE() macro references _IOC_SIZEBITS. Add linux/ioctl.h +to make sure this macro is defined. This fixes the following build +failure of lcdproc with the musl libc: + +In file included from .../sysroot/usr/include/sys/ioctl.h:7:0, + from hd44780-spi.c:31: +hd44780-spi.c: In function 'spi_transfer': +hd44780-spi.c:89:24: error: '_IOC_SIZEBITS' undeclared (first use in this function) + status = ioctl(p->fd, SPI_IOC_MESSAGE(1), &xfer); + ^ + +Signed-off-by: Baruch Siach +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + include/uapi/linux/spi/spidev.h | 1 + + 1 file changed, 1 insertion(+) + +--- a/include/uapi/linux/spi/spidev.h ++++ b/include/uapi/linux/spi/spidev.h +@@ -23,6 +23,7 @@ + #define SPIDEV_H + + #include ++#include + + /* User space versions of kernel symbols for SPI clocking modes, + * matching diff --git a/queue-4.9/usb-xhci-handle-error-condition-in-xhci_stop_device.patch b/queue-4.9/usb-xhci-handle-error-condition-in-xhci_stop_device.patch new file mode 100644 index 00000000000..3e0753000e7 --- /dev/null +++ b/queue-4.9/usb-xhci-handle-error-condition-in-xhci_stop_device.patch @@ -0,0 +1,71 @@ +From b3207c65dfafae27e7c492cb9188c0dc0eeaf3fd Mon Sep 17 00:00:00 2001 +From: Mayank Rana +Date: Fri, 6 Oct 2017 17:45:30 +0300 +Subject: usb: xhci: Handle error condition in xhci_stop_device() + +From: Mayank Rana + +commit b3207c65dfafae27e7c492cb9188c0dc0eeaf3fd upstream. + +xhci_stop_device() calls xhci_queue_stop_endpoint() multiple times +without checking the return value. xhci_queue_stop_endpoint() can +return error if the HC is already halted or unable to queue commands. +This can cause a deadlock condition as xhci_stop_device() would +end up waiting indefinitely for a completion for the command that +didn't get queued. Fix this by checking the return value and bailing +out of xhci_stop_device() in case of error. This patch happens to fix +potential memory leaks of the allocated command structures as well. + +Fixes: c311e391a7ef ("xhci: rework command timeout and cancellation,") +Signed-off-by: Mayank Rana +Signed-off-by: Jack Pham +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + + +--- + drivers/usb/host/xhci-hub.c | 22 +++++++++++++++++----- + 1 file changed, 17 insertions(+), 5 deletions(-) + +--- a/drivers/usb/host/xhci-hub.c ++++ b/drivers/usb/host/xhci-hub.c +@@ -412,15 +412,25 @@ static int xhci_stop_device(struct xhci_ + GFP_NOWAIT); + if (!command) { + spin_unlock_irqrestore(&xhci->lock, flags); +- xhci_free_command(xhci, cmd); +- return -ENOMEM; ++ ret = -ENOMEM; ++ goto cmd_cleanup; ++ } + ++ ret = xhci_queue_stop_endpoint(xhci, command, slot_id, ++ i, suspend); ++ if (ret) { ++ spin_unlock_irqrestore(&xhci->lock, flags); ++ xhci_free_command(xhci, command); ++ goto cmd_cleanup; + } +- xhci_queue_stop_endpoint(xhci, command, slot_id, i, +- suspend); + } + } +- xhci_queue_stop_endpoint(xhci, cmd, slot_id, 0, suspend); ++ ret = xhci_queue_stop_endpoint(xhci, cmd, slot_id, 0, suspend); ++ if (ret) { ++ spin_unlock_irqrestore(&xhci->lock, flags); ++ goto cmd_cleanup; ++ } ++ + xhci_ring_cmd_db(xhci); + spin_unlock_irqrestore(&xhci->lock, flags); + +@@ -431,6 +441,8 @@ static int xhci_stop_device(struct xhci_ + xhci_warn(xhci, "Timeout while waiting for stop endpoint command\n"); + ret = -ETIME; + } ++ ++cmd_cleanup: + xhci_free_command(xhci, cmd); + return ret; + } diff --git a/queue-4.9/xen-gntdev-avoid-out-of-bounds-access-in-case-of-partial-gntdev_mmap.patch b/queue-4.9/xen-gntdev-avoid-out-of-bounds-access-in-case-of-partial-gntdev_mmap.patch new file mode 100644 index 00000000000..71995baaf82 --- /dev/null +++ b/queue-4.9/xen-gntdev-avoid-out-of-bounds-access-in-case-of-partial-gntdev_mmap.patch @@ -0,0 +1,45 @@ +From 298d275d4d9bea3524ff4bc76678c140611d8a8d Mon Sep 17 00:00:00 2001 +From: Juergen Gross +Date: Wed, 25 Oct 2017 17:08:07 +0200 +Subject: xen/gntdev: avoid out of bounds access in case of partial gntdev_mmap() + +From: Juergen Gross + +commit 298d275d4d9bea3524ff4bc76678c140611d8a8d upstream. + +In case gntdev_mmap() succeeds only partially in mapping grant pages +it will leave some vital information uninitialized needed later for +cleanup. This will lead to an out of bounds array access when unmapping +the already mapped pages. + +So just initialize the data needed for unmapping the pages a little bit +earlier. + +Reported-by: Arthur Borsboom +Signed-off-by: Juergen Gross +Reviewed-by: Boris Ostrovsky +Signed-off-by: Boris Ostrovsky +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/xen/gntdev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/xen/gntdev.c ++++ b/drivers/xen/gntdev.c +@@ -1030,6 +1030,7 @@ static int gntdev_mmap(struct file *flip + mutex_unlock(&priv->lock); + + if (use_ptemod) { ++ map->pages_vm_start = vma->vm_start; + err = apply_to_page_range(vma->vm_mm, vma->vm_start, + vma->vm_end - vma->vm_start, + find_grant_ptes, map); +@@ -1067,7 +1068,6 @@ static int gntdev_mmap(struct file *flip + set_grant_ptes_as_special, NULL); + } + #endif +- map->pages_vm_start = vma->vm_start; + } + + return 0;