From: Greg Kroah-Hartman Date: Fri, 12 Jul 2019 09:12:30 +0000 (+0200) Subject: 5.2-stable patches X-Git-Tag: v5.2.1~13 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=83aabc6a31a62d4bf34c4ea1060201ef972a5c59;p=thirdparty%2Fkernel%2Fstable-queue.git 5.2-stable patches added patches: carl9170-fix-misuse-of-device-driver-api.patch coresight-etb10-do-not-call-smp_processor_id-from-preemptible.patch coresight-potential-uninitialized-variable-in-probe.patch coresight-tmc-etf-do-not-call-smp_processor_id-from-preemptible.patch coresight-tmc-etr-alloc_perf_buf-do-not-call-smp_processor_id-from-preemptible.patch coresight-tmc-etr-do-not-call-smp_processor_id-from-preemptible.patch revert-x86-build-move-_etext-to-actual-end-of-.text.patch vmci-fix-integer-overflow-in-vmci-handle-arrays.patch --- diff --git a/queue-5.2/carl9170-fix-misuse-of-device-driver-api.patch b/queue-5.2/carl9170-fix-misuse-of-device-driver-api.patch new file mode 100644 index 00000000000..be1511bf36a --- /dev/null +++ b/queue-5.2/carl9170-fix-misuse-of-device-driver-api.patch @@ -0,0 +1,148 @@ +From feb09b2933275a70917a869989ea2823e7356be8 Mon Sep 17 00:00:00 2001 +From: Christian Lamparter +Date: Sat, 8 Jun 2019 16:49:47 +0200 +Subject: carl9170: fix misuse of device driver API + +From: Christian Lamparter + +commit feb09b2933275a70917a869989ea2823e7356be8 upstream. + +This patch follows Alan Stern's recent patch: +"p54: Fix race between disconnect and firmware loading" + +that overhauled carl9170 buggy firmware loading and driver +unbinding procedures. + +Since the carl9170 code was adapted from p54 it uses the +same functions and is likely to have the same problem, but +it's just that the syzbot hasn't reproduce them (yet). + +a summary from the changes (copied from the p54 patch): + * Call usb_driver_release_interface() rather than + device_release_driver(). + + * Lock udev (the interface's parent) before unbinding the + driver instead of locking udev->parent. + + * During the firmware loading process, take a reference + to the USB interface instead of the USB device. + + * Don't take an unnecessary reference to the device during + probe (and then don't drop it during disconnect). + +and + + * Make sure to prevent use-after-free bugs by explicitly + setting the driver context to NULL after signaling the + completion. + +Cc: +Cc: Alan Stern +Signed-off-by: Christian Lamparter +Acked-by: Alan Stern +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/carl9170/usb.c | 39 +++++++++++++------------------- + 1 file changed, 17 insertions(+), 22 deletions(-) + +--- a/drivers/net/wireless/ath/carl9170/usb.c ++++ b/drivers/net/wireless/ath/carl9170/usb.c +@@ -128,6 +128,8 @@ static const struct usb_device_id carl91 + }; + MODULE_DEVICE_TABLE(usb, carl9170_usb_ids); + ++static struct usb_driver carl9170_driver; ++ + static void carl9170_usb_submit_data_urb(struct ar9170 *ar) + { + struct urb *urb; +@@ -966,32 +968,28 @@ err_out: + + static void carl9170_usb_firmware_failed(struct ar9170 *ar) + { +- struct device *parent = ar->udev->dev.parent; +- struct usb_device *udev; +- +- /* +- * Store a copy of the usb_device pointer locally. +- * This is because device_release_driver initiates +- * carl9170_usb_disconnect, which in turn frees our +- * driver context (ar). ++ /* Store a copies of the usb_interface and usb_device pointer locally. ++ * This is because release_driver initiates carl9170_usb_disconnect, ++ * which in turn frees our driver context (ar). + */ +- udev = ar->udev; ++ struct usb_interface *intf = ar->intf; ++ struct usb_device *udev = ar->udev; + + complete(&ar->fw_load_wait); ++ /* at this point 'ar' could be already freed. Don't use it anymore */ ++ ar = NULL; + + /* unbind anything failed */ +- if (parent) +- device_lock(parent); +- +- device_release_driver(&udev->dev); +- if (parent) +- device_unlock(parent); ++ usb_lock_device(udev); ++ usb_driver_release_interface(&carl9170_driver, intf); ++ usb_unlock_device(udev); + +- usb_put_dev(udev); ++ usb_put_intf(intf); + } + + static void carl9170_usb_firmware_finish(struct ar9170 *ar) + { ++ struct usb_interface *intf = ar->intf; + int err; + + err = carl9170_parse_firmware(ar); +@@ -1009,7 +1007,7 @@ static void carl9170_usb_firmware_finish + goto err_unrx; + + complete(&ar->fw_load_wait); +- usb_put_dev(ar->udev); ++ usb_put_intf(intf); + return; + + err_unrx: +@@ -1052,7 +1050,6 @@ static int carl9170_usb_probe(struct usb + return PTR_ERR(ar); + + udev = interface_to_usbdev(intf); +- usb_get_dev(udev); + ar->udev = udev; + ar->intf = intf; + ar->features = id->driver_info; +@@ -1094,15 +1091,14 @@ static int carl9170_usb_probe(struct usb + atomic_set(&ar->rx_anch_urbs, 0); + atomic_set(&ar->rx_pool_urbs, 0); + +- usb_get_dev(ar->udev); ++ usb_get_intf(intf); + + carl9170_set_state(ar, CARL9170_STOPPED); + + err = request_firmware_nowait(THIS_MODULE, 1, CARL9170FW_NAME, + &ar->udev->dev, GFP_KERNEL, ar, carl9170_usb_firmware_step2); + if (err) { +- usb_put_dev(udev); +- usb_put_dev(udev); ++ usb_put_intf(intf); + carl9170_free(ar); + } + return err; +@@ -1131,7 +1127,6 @@ static void carl9170_usb_disconnect(stru + + carl9170_release_firmware(ar); + carl9170_free(ar); +- usb_put_dev(udev); + } + + #ifdef CONFIG_PM diff --git a/queue-5.2/coresight-etb10-do-not-call-smp_processor_id-from-preemptible.patch b/queue-5.2/coresight-etb10-do-not-call-smp_processor_id-from-preemptible.patch new file mode 100644 index 00000000000..0d4e45d68bd --- /dev/null +++ b/queue-5.2/coresight-etb10-do-not-call-smp_processor_id-from-preemptible.patch @@ -0,0 +1,48 @@ +From 730766bae3280a25d40ea76a53dc6342e84e6513 Mon Sep 17 00:00:00 2001 +From: Suzuki K Poulose +Date: Thu, 20 Jun 2019 16:12:36 -0600 +Subject: coresight: etb10: Do not call smp_processor_id from preemptible + +From: Suzuki K Poulose + +commit 730766bae3280a25d40ea76a53dc6342e84e6513 upstream. + +During a perf session we try to allocate buffers on the "node" associated +with the CPU the event is bound to. If it is not bound to a CPU, we +use the current CPU node, using smp_processor_id(). However this is unsafe +in a pre-emptible context and could generate the splats as below : + + BUG: using smp_processor_id() in preemptible [00000000] code: perf/2544 + +Use NUMA_NO_NODE hint instead of using the current node for events +not bound to CPUs. + +Fixes: 2997aa4063d97fdb39 ("coresight: etb10: implementing AUX API") +Cc: Mathieu Poirier +Signed-off-by: Suzuki K Poulose +Cc: stable # 4.6+ +Signed-off-by: Mathieu Poirier +Link: https://lore.kernel.org/r/20190620221237.3536-5-mathieu.poirier@linaro.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hwtracing/coresight/coresight-etb10.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +--- a/drivers/hwtracing/coresight/coresight-etb10.c ++++ b/drivers/hwtracing/coresight/coresight-etb10.c +@@ -373,12 +373,10 @@ static void *etb_alloc_buffer(struct cor + struct perf_event *event, void **pages, + int nr_pages, bool overwrite) + { +- int node, cpu = event->cpu; ++ int node; + struct cs_buffers *buf; + +- if (cpu == -1) +- cpu = smp_processor_id(); +- node = cpu_to_node(cpu); ++ node = (event->cpu == -1) ? NUMA_NO_NODE : cpu_to_node(event->cpu); + + buf = kzalloc_node(sizeof(struct cs_buffers), GFP_KERNEL, node); + if (!buf) diff --git a/queue-5.2/coresight-potential-uninitialized-variable-in-probe.patch b/queue-5.2/coresight-potential-uninitialized-variable-in-probe.patch new file mode 100644 index 00000000000..90500947929 --- /dev/null +++ b/queue-5.2/coresight-potential-uninitialized-variable-in-probe.patch @@ -0,0 +1,34 @@ +From 0530ef6b41e80c5cc979e0e50682302161edb6b7 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Thu, 20 Jun 2019 16:12:37 -0600 +Subject: coresight: Potential uninitialized variable in probe() + +From: Dan Carpenter + +commit 0530ef6b41e80c5cc979e0e50682302161edb6b7 upstream. + +The "drvdata->atclk" clock is optional, but if it gets set to an error +pointer then we're accidentally return an uninitialized variable instead +of success. + +Fixes: 78e6427b4e7b ("coresight: funnel: Support static funnel") +Signed-off-by: Dan Carpenter +Signed-off-by: Mathieu Poirier +Cc: stable +Link: https://lore.kernel.org/r/20190620221237.3536-6-mathieu.poirier@linaro.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hwtracing/coresight/coresight-funnel.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/hwtracing/coresight/coresight-funnel.c ++++ b/drivers/hwtracing/coresight/coresight-funnel.c +@@ -241,6 +241,7 @@ static int funnel_probe(struct device *d + } + + pm_runtime_put(dev); ++ ret = 0; + + out_disable_clk: + if (ret && !IS_ERR_OR_NULL(drvdata->atclk)) diff --git a/queue-5.2/coresight-tmc-etf-do-not-call-smp_processor_id-from-preemptible.patch b/queue-5.2/coresight-tmc-etf-do-not-call-smp_processor_id-from-preemptible.patch new file mode 100644 index 00000000000..1f04cff79a4 --- /dev/null +++ b/queue-5.2/coresight-tmc-etf-do-not-call-smp_processor_id-from-preemptible.patch @@ -0,0 +1,67 @@ +From 024c1fd9dbcc1d8a847f1311f999d35783921b7f Mon Sep 17 00:00:00 2001 +From: Suzuki K Poulose +Date: Thu, 20 Jun 2019 16:12:35 -0600 +Subject: coresight: tmc-etf: Do not call smp_processor_id from preemptible + +From: Suzuki K Poulose + +commit 024c1fd9dbcc1d8a847f1311f999d35783921b7f upstream. + +During a perf session we try to allocate buffers on the "node" associated +with the CPU the event is bound to. If it is not bound to a CPU, we +use the current CPU node, using smp_processor_id(). However this is unsafe +in a pre-emptible context and could generate the splats as below : + + BUG: using smp_processor_id() in preemptible [00000000] code: perf/2544 + caller is tmc_alloc_etf_buffer+0x5c/0x60 + CPU: 2 PID: 2544 Comm: perf Not tainted 5.1.0-rc6-147786-g116841e #344 + Hardware name: ARM LTD ARM Juno Development Platform/ARM Juno Development Platform, BIOS EDK II Feb 1 2019 + Call trace: + dump_backtrace+0x0/0x150 + show_stack+0x14/0x20 + dump_stack+0x9c/0xc4 + debug_smp_processor_id+0x10c/0x110 + tmc_alloc_etf_buffer+0x5c/0x60 + etm_setup_aux+0x1c4/0x230 + rb_alloc_aux+0x1b8/0x2b8 + perf_mmap+0x35c/0x478 + mmap_region+0x34c/0x4f0 + do_mmap+0x2d8/0x418 + vm_mmap_pgoff+0xd0/0xf8 + ksys_mmap_pgoff+0x88/0xf8 + __arm64_sys_mmap+0x28/0x38 + el0_svc_handler+0xd8/0x138 + el0_svc+0x8/0xc + +Use NUMA_NO_NODE hint instead of using the current node for events +not bound to CPUs. + +Fixes: 2e499bbc1a929ac ("coresight: tmc: implementing TMC-ETF AUX space API") +Cc: Mathieu Poirier +Signed-off-by: Suzuki K Poulose +Cc: stable # 4.7+ +Signed-off-by: Mathieu Poirier +Link: https://lore.kernel.org/r/20190620221237.3536-4-mathieu.poirier@linaro.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hwtracing/coresight/coresight-tmc-etf.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +--- a/drivers/hwtracing/coresight/coresight-tmc-etf.c ++++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c +@@ -378,12 +378,10 @@ static void *tmc_alloc_etf_buffer(struct + struct perf_event *event, void **pages, + int nr_pages, bool overwrite) + { +- int node, cpu = event->cpu; ++ int node; + struct cs_buffers *buf; + +- if (cpu == -1) +- cpu = smp_processor_id(); +- node = cpu_to_node(cpu); ++ node = (event->cpu == -1) ? NUMA_NO_NODE : cpu_to_node(event->cpu); + + /* Allocate memory structure for interaction with Perf */ + buf = kzalloc_node(sizeof(struct cs_buffers), GFP_KERNEL, node); diff --git a/queue-5.2/coresight-tmc-etr-alloc_perf_buf-do-not-call-smp_processor_id-from-preemptible.patch b/queue-5.2/coresight-tmc-etr-alloc_perf_buf-do-not-call-smp_processor_id-from-preemptible.patch new file mode 100644 index 00000000000..d7db9173da7 --- /dev/null +++ b/queue-5.2/coresight-tmc-etr-alloc_perf_buf-do-not-call-smp_processor_id-from-preemptible.patch @@ -0,0 +1,69 @@ +From 3a8710392db2c70f74aed6f06b16e8bec0f05a35 Mon Sep 17 00:00:00 2001 +From: Suzuki K Poulose +Date: Thu, 20 Jun 2019 16:12:34 -0600 +Subject: coresight: tmc-etr: alloc_perf_buf: Do not call smp_processor_id from preemptible + +From: Suzuki K Poulose + +commit 3a8710392db2c70f74aed6f06b16e8bec0f05a35 upstream. + +During a perf session we try to allocate buffers on the "node" associated +with the CPU the event is bound to. If it is not bound to a CPU, we +use the current CPU node, using smp_processor_id(). However this is unsafe +in a pre-emptible context and could generate the splats as below : + + BUG: using smp_processor_id() in preemptible [00000000] code: perf/1743 + caller is tmc_alloc_etr_buffer+0x1bc/0x1f0 + CPU: 1 PID: 1743 Comm: perf Not tainted 5.1.0-rc6-147786-g116841e #344 + Hardware name: ARM LTD ARM Juno Development Platform/ARM Juno Development Platform, BIOS EDK II Feb 1 2019 + Call trace: + dump_backtrace+0x0/0x150 + show_stack+0x14/0x20 + dump_stack+0x9c/0xc4 + debug_smp_processor_id+0x10c/0x110 + tmc_alloc_etr_buffer+0x1bc/0x1f0 + etm_setup_aux+0x1c4/0x230 + rb_alloc_aux+0x1b8/0x2b8 + perf_mmap+0x35c/0x478 + mmap_region+0x34c/0x4f0 + do_mmap+0x2d8/0x418 + vm_mmap_pgoff+0xd0/0xf8 + ksys_mmap_pgoff+0x88/0xf8 + __arm64_sys_mmap+0x28/0x38 + el0_svc_handler+0xd8/0x138 + el0_svc+0x8/0xc + +Use NUMA_NO_NODE hint instead of using the current node for events +not bound to CPUs. + +Fixes: 22f429f19c4135d51e9 ("coresight: etm-perf: Add support for ETR backend") +Cc: Mathieu Poirier +Signed-off-by: Suzuki K Poulose +Cc: stable # 4.20+ +Signed-off-by: Mathieu Poirier +Link: https://lore.kernel.org/r/20190620221237.3536-3-mathieu.poirier@linaro.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hwtracing/coresight/coresight-tmc-etr.c | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c ++++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c +@@ -1178,14 +1178,11 @@ static struct etr_buf * + alloc_etr_buf(struct tmc_drvdata *drvdata, struct perf_event *event, + int nr_pages, void **pages, bool snapshot) + { +- int node, cpu = event->cpu; ++ int node; + struct etr_buf *etr_buf; + unsigned long size; + +- if (cpu == -1) +- cpu = smp_processor_id(); +- node = cpu_to_node(cpu); +- ++ node = (event->cpu == -1) ? NUMA_NO_NODE : cpu_to_node(event->cpu); + /* + * Try to match the perf ring buffer size if it is larger + * than the size requested via sysfs. diff --git a/queue-5.2/coresight-tmc-etr-do-not-call-smp_processor_id-from-preemptible.patch b/queue-5.2/coresight-tmc-etr-do-not-call-smp_processor_id-from-preemptible.patch new file mode 100644 index 00000000000..aed5250aacb --- /dev/null +++ b/queue-5.2/coresight-tmc-etr-do-not-call-smp_processor_id-from-preemptible.patch @@ -0,0 +1,69 @@ +From 3ff44563dbb02456a33f2a42000f04db4ef19a8f Mon Sep 17 00:00:00 2001 +From: Suzuki K Poulose +Date: Thu, 20 Jun 2019 16:12:33 -0600 +Subject: coresight: tmc-etr: Do not call smp_processor_id() from preemptible + +From: Suzuki K Poulose + +commit 3ff44563dbb02456a33f2a42000f04db4ef19a8f upstream. + +During a perf session we try to allocate buffers on the "node" associated +with the CPU the event is bound to. If it's not bound to a CPU, we use +the current CPU node, using smp_processor_id(). However this is unsafe +in a pre-emptible context and could generate the splats as below : + + BUG: using smp_processor_id() in preemptible [00000000] code: perf/1743 + caller is alloc_etr_buf.isra.6+0x80/0xa0 + CPU: 1 PID: 1743 Comm: perf Not tainted 5.1.0-rc6-147786-g116841e #344 + Hardware name: ARM LTD ARM Juno Development Platform/ARM Juno Development Platform, BIOS EDK II Feb 1 2019 + Call trace: + dump_backtrace+0x0/0x150 + show_stack+0x14/0x20 + dump_stack+0x9c/0xc4 + debug_smp_processor_id+0x10c/0x110 + alloc_etr_buf.isra.6+0x80/0xa0 + tmc_alloc_etr_buffer+0x12c/0x1f0 + etm_setup_aux+0x1c4/0x230 + rb_alloc_aux+0x1b8/0x2b8 + perf_mmap+0x35c/0x478 + mmap_region+0x34c/0x4f0 + do_mmap+0x2d8/0x418 + vm_mmap_pgoff+0xd0/0xf8 + ksys_mmap_pgoff+0x88/0xf8 + __arm64_sys_mmap+0x28/0x38 + el0_svc_handler+0xd8/0x138 + el0_svc+0x8/0xc + +Use NUMA_NO_NODE hint instead of using the current node for events +not bound to CPUs. + +Fixes: 855ab61c16bf70b646 ("coresight: tmc-etr: Refactor function tmc_etr_setup_perf_buf()") +Cc: Mathieu Poirier +Signed-off-by: Suzuki K Poulose +Signed-off-by: Mathieu Poirier +Cc: stable +Link: https://lore.kernel.org/r/20190620221237.3536-2-mathieu.poirier@linaro.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hwtracing/coresight/coresight-tmc-etr.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c ++++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c +@@ -1317,13 +1317,11 @@ static struct etr_perf_buffer * + tmc_etr_setup_perf_buf(struct tmc_drvdata *drvdata, struct perf_event *event, + int nr_pages, void **pages, bool snapshot) + { +- int node, cpu = event->cpu; ++ int node; + struct etr_buf *etr_buf; + struct etr_perf_buffer *etr_perf; + +- if (cpu == -1) +- cpu = smp_processor_id(); +- node = cpu_to_node(cpu); ++ node = (event->cpu == -1) ? NUMA_NO_NODE : cpu_to_node(event->cpu); + + etr_perf = kzalloc_node(sizeof(*etr_perf), GFP_KERNEL, node); + if (!etr_perf) diff --git a/queue-5.2/revert-x86-build-move-_etext-to-actual-end-of-.text.patch b/queue-5.2/revert-x86-build-move-_etext-to-actual-end-of-.text.patch new file mode 100644 index 00000000000..ffdc881ca8d --- /dev/null +++ b/queue-5.2/revert-x86-build-move-_etext-to-actual-end-of-.text.patch @@ -0,0 +1,56 @@ +From 013c66edf207ddb78422b8b636f56c87939c9e34 Mon Sep 17 00:00:00 2001 +From: Ross Zwisler +Date: Mon, 1 Jul 2019 09:52:08 -0600 +Subject: Revert "x86/build: Move _etext to actual end of .text" + +From: Ross Zwisler + +commit 013c66edf207ddb78422b8b636f56c87939c9e34 upstream. + +This reverts commit 392bef709659abea614abfe53cf228e7a59876a4. + +Per the discussion here: + + https://lkml.kernel.org/r/201906201042.3BF5CD6@keescook + +the above referenced commit breaks kernel compilation with old GCC +toolchains as well as current versions of the Gold linker. + +Revert it to fix the regression and to keep the ability to compile the +kernel with these tools. + +Signed-off-by: Ross Zwisler +Signed-off-by: Thomas Gleixner +Reviewed-by: Guenter Roeck +Cc: +Cc: "H. Peter Anvin" +Cc: Borislav Petkov +Cc: Kees Cook +Cc: Johannes Hirte +Cc: Klaus Kusche +Cc: samitolvanen@google.com +Cc: Guenter Roeck +Link: https://lkml.kernel.org/r/20190701155208.211815-1-zwisler@google.com +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/vmlinux.lds.S | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/arch/x86/kernel/vmlinux.lds.S ++++ b/arch/x86/kernel/vmlinux.lds.S +@@ -141,10 +141,10 @@ SECTIONS + *(.text.__x86.indirect_thunk) + __indirect_thunk_end = .; + #endif +- } :text = 0x9090 + +- /* End of text section */ +- _etext = .; ++ /* End of text section */ ++ _etext = .; ++ } :text = 0x9090 + + NOTES :text :note + diff --git a/queue-5.2/series b/queue-5.2/series index 72115bdb9e6..836028d833d 100644 --- a/queue-5.2/series +++ b/queue-5.2/series @@ -42,3 +42,11 @@ lkdtm-support-llvm-objcopy.patch binder-fix-memory-leak-in-error-path.patch binder-return-errors-from-buffer-copy-functions.patch iio-adc-stm32-adc-add-missing-vdda-supply.patch +coresight-potential-uninitialized-variable-in-probe.patch +coresight-etb10-do-not-call-smp_processor_id-from-preemptible.patch +coresight-tmc-etr-do-not-call-smp_processor_id-from-preemptible.patch +coresight-tmc-etr-alloc_perf_buf-do-not-call-smp_processor_id-from-preemptible.patch +coresight-tmc-etf-do-not-call-smp_processor_id-from-preemptible.patch +carl9170-fix-misuse-of-device-driver-api.patch +revert-x86-build-move-_etext-to-actual-end-of-.text.patch +vmci-fix-integer-overflow-in-vmci-handle-arrays.patch diff --git a/queue-5.2/vmci-fix-integer-overflow-in-vmci-handle-arrays.patch b/queue-5.2/vmci-fix-integer-overflow-in-vmci-handle-arrays.patch new file mode 100644 index 00000000000..a89a2c949bc --- /dev/null +++ b/queue-5.2/vmci-fix-integer-overflow-in-vmci-handle-arrays.patch @@ -0,0 +1,374 @@ +From 1c2eb5b2853c9f513690ba6b71072d8eb65da16a Mon Sep 17 00:00:00 2001 +From: Vishnu DASA +Date: Fri, 24 May 2019 15:13:10 +0000 +Subject: VMCI: Fix integer overflow in VMCI handle arrays + +From: Vishnu DASA + +commit 1c2eb5b2853c9f513690ba6b71072d8eb65da16a upstream. + +The VMCI handle array has an integer overflow in +vmci_handle_arr_append_entry when it tries to expand the array. This can be +triggered from a guest, since the doorbell link hypercall doesn't impose a +limit on the number of doorbell handles that a VM can create in the +hypervisor, and these handles are stored in a handle array. + +In this change, we introduce a mandatory max capacity for handle +arrays/lists to avoid excessive memory usage. + +Signed-off-by: Vishnu Dasa +Reviewed-by: Adit Ranadive +Reviewed-by: Jorgen Hansen +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/misc/vmw_vmci/vmci_context.c | 80 ++++++++++++++++-------------- + drivers/misc/vmw_vmci/vmci_handle_array.c | 38 +++++++++----- + drivers/misc/vmw_vmci/vmci_handle_array.h | 29 +++++++--- + include/linux/vmw_vmci_defs.h | 11 +++- + 4 files changed, 99 insertions(+), 59 deletions(-) + +--- a/drivers/misc/vmw_vmci/vmci_context.c ++++ b/drivers/misc/vmw_vmci/vmci_context.c +@@ -21,6 +21,9 @@ + #include "vmci_driver.h" + #include "vmci_event.h" + ++/* Use a wide upper bound for the maximum contexts. */ ++#define VMCI_MAX_CONTEXTS 2000 ++ + /* + * List of current VMCI contexts. Contexts can be added by + * vmci_ctx_create() and removed via vmci_ctx_destroy(). +@@ -117,19 +120,22 @@ struct vmci_ctx *vmci_ctx_create(u32 cid + /* Initialize host-specific VMCI context. */ + init_waitqueue_head(&context->host_context.wait_queue); + +- context->queue_pair_array = vmci_handle_arr_create(0); ++ context->queue_pair_array = ++ vmci_handle_arr_create(0, VMCI_MAX_GUEST_QP_COUNT); + if (!context->queue_pair_array) { + error = -ENOMEM; + goto err_free_ctx; + } + +- context->doorbell_array = vmci_handle_arr_create(0); ++ context->doorbell_array = ++ vmci_handle_arr_create(0, VMCI_MAX_GUEST_DOORBELL_COUNT); + if (!context->doorbell_array) { + error = -ENOMEM; + goto err_free_qp_array; + } + +- context->pending_doorbell_array = vmci_handle_arr_create(0); ++ context->pending_doorbell_array = ++ vmci_handle_arr_create(0, VMCI_MAX_GUEST_DOORBELL_COUNT); + if (!context->pending_doorbell_array) { + error = -ENOMEM; + goto err_free_db_array; +@@ -204,7 +210,7 @@ static int ctx_fire_notification(u32 con + * We create an array to hold the subscribers we find when + * scanning through all contexts. + */ +- subscriber_array = vmci_handle_arr_create(0); ++ subscriber_array = vmci_handle_arr_create(0, VMCI_MAX_CONTEXTS); + if (subscriber_array == NULL) + return VMCI_ERROR_NO_MEM; + +@@ -623,20 +629,26 @@ int vmci_ctx_add_notification(u32 contex + + spin_lock(&context->lock); + +- list_for_each_entry(n, &context->notifier_list, node) { +- if (vmci_handle_is_equal(n->handle, notifier->handle)) { +- exists = true; +- break; ++ if (context->n_notifiers < VMCI_MAX_CONTEXTS) { ++ list_for_each_entry(n, &context->notifier_list, node) { ++ if (vmci_handle_is_equal(n->handle, notifier->handle)) { ++ exists = true; ++ break; ++ } + } +- } + +- if (exists) { +- kfree(notifier); +- result = VMCI_ERROR_ALREADY_EXISTS; ++ if (exists) { ++ kfree(notifier); ++ result = VMCI_ERROR_ALREADY_EXISTS; ++ } else { ++ list_add_tail_rcu(¬ifier->node, ++ &context->notifier_list); ++ context->n_notifiers++; ++ result = VMCI_SUCCESS; ++ } + } else { +- list_add_tail_rcu(¬ifier->node, &context->notifier_list); +- context->n_notifiers++; +- result = VMCI_SUCCESS; ++ kfree(notifier); ++ result = VMCI_ERROR_NO_MEM; + } + + spin_unlock(&context->lock); +@@ -721,8 +733,7 @@ static int vmci_ctx_get_chkpt_doorbells( + u32 *buf_size, void **pbuf) + { + struct dbell_cpt_state *dbells; +- size_t n_doorbells; +- int i; ++ u32 i, n_doorbells; + + n_doorbells = vmci_handle_arr_get_size(context->doorbell_array); + if (n_doorbells > 0) { +@@ -860,7 +871,8 @@ int vmci_ctx_rcv_notifications_get(u32 c + spin_lock(&context->lock); + + *db_handle_array = context->pending_doorbell_array; +- context->pending_doorbell_array = vmci_handle_arr_create(0); ++ context->pending_doorbell_array = ++ vmci_handle_arr_create(0, VMCI_MAX_GUEST_DOORBELL_COUNT); + if (!context->pending_doorbell_array) { + context->pending_doorbell_array = *db_handle_array; + *db_handle_array = NULL; +@@ -942,12 +954,11 @@ int vmci_ctx_dbell_create(u32 context_id + return VMCI_ERROR_NOT_FOUND; + + spin_lock(&context->lock); +- if (!vmci_handle_arr_has_entry(context->doorbell_array, handle)) { +- vmci_handle_arr_append_entry(&context->doorbell_array, handle); +- result = VMCI_SUCCESS; +- } else { ++ if (!vmci_handle_arr_has_entry(context->doorbell_array, handle)) ++ result = vmci_handle_arr_append_entry(&context->doorbell_array, ++ handle); ++ else + result = VMCI_ERROR_DUPLICATE_ENTRY; +- } + + spin_unlock(&context->lock); + vmci_ctx_put(context); +@@ -1083,15 +1094,16 @@ int vmci_ctx_notify_dbell(u32 src_cid, + if (!vmci_handle_arr_has_entry( + dst_context->pending_doorbell_array, + handle)) { +- vmci_handle_arr_append_entry( ++ result = vmci_handle_arr_append_entry( + &dst_context->pending_doorbell_array, + handle); +- +- ctx_signal_notify(dst_context); +- wake_up(&dst_context->host_context.wait_queue); +- ++ if (result == VMCI_SUCCESS) { ++ ctx_signal_notify(dst_context); ++ wake_up(&dst_context->host_context.wait_queue); ++ } ++ } else { ++ result = VMCI_SUCCESS; + } +- result = VMCI_SUCCESS; + } + spin_unlock(&dst_context->lock); + } +@@ -1118,13 +1130,11 @@ int vmci_ctx_qp_create(struct vmci_ctx * + if (context == NULL || vmci_handle_is_invalid(handle)) + return VMCI_ERROR_INVALID_ARGS; + +- if (!vmci_handle_arr_has_entry(context->queue_pair_array, handle)) { +- vmci_handle_arr_append_entry(&context->queue_pair_array, +- handle); +- result = VMCI_SUCCESS; +- } else { ++ if (!vmci_handle_arr_has_entry(context->queue_pair_array, handle)) ++ result = vmci_handle_arr_append_entry( ++ &context->queue_pair_array, handle); ++ else + result = VMCI_ERROR_DUPLICATE_ENTRY; +- } + + return result; + } +--- a/drivers/misc/vmw_vmci/vmci_handle_array.c ++++ b/drivers/misc/vmw_vmci/vmci_handle_array.c +@@ -8,24 +8,29 @@ + #include + #include "vmci_handle_array.h" + +-static size_t handle_arr_calc_size(size_t capacity) ++static size_t handle_arr_calc_size(u32 capacity) + { +- return sizeof(struct vmci_handle_arr) + ++ return VMCI_HANDLE_ARRAY_HEADER_SIZE + + capacity * sizeof(struct vmci_handle); + } + +-struct vmci_handle_arr *vmci_handle_arr_create(size_t capacity) ++struct vmci_handle_arr *vmci_handle_arr_create(u32 capacity, u32 max_capacity) + { + struct vmci_handle_arr *array; + ++ if (max_capacity == 0 || capacity > max_capacity) ++ return NULL; ++ + if (capacity == 0) +- capacity = VMCI_HANDLE_ARRAY_DEFAULT_SIZE; ++ capacity = min((u32)VMCI_HANDLE_ARRAY_DEFAULT_CAPACITY, ++ max_capacity); + + array = kmalloc(handle_arr_calc_size(capacity), GFP_ATOMIC); + if (!array) + return NULL; + + array->capacity = capacity; ++ array->max_capacity = max_capacity; + array->size = 0; + + return array; +@@ -36,27 +41,34 @@ void vmci_handle_arr_destroy(struct vmci + kfree(array); + } + +-void vmci_handle_arr_append_entry(struct vmci_handle_arr **array_ptr, +- struct vmci_handle handle) ++int vmci_handle_arr_append_entry(struct vmci_handle_arr **array_ptr, ++ struct vmci_handle handle) + { + struct vmci_handle_arr *array = *array_ptr; + + if (unlikely(array->size >= array->capacity)) { + /* reallocate. */ + struct vmci_handle_arr *new_array; +- size_t new_capacity = array->capacity * VMCI_ARR_CAP_MULT; +- size_t new_size = handle_arr_calc_size(new_capacity); ++ u32 capacity_bump = min(array->max_capacity - array->capacity, ++ array->capacity); ++ size_t new_size = handle_arr_calc_size(array->capacity + ++ capacity_bump); ++ ++ if (array->size >= array->max_capacity) ++ return VMCI_ERROR_NO_MEM; + + new_array = krealloc(array, new_size, GFP_ATOMIC); + if (!new_array) +- return; ++ return VMCI_ERROR_NO_MEM; + +- new_array->capacity = new_capacity; ++ new_array->capacity += capacity_bump; + *array_ptr = array = new_array; + } + + array->entries[array->size] = handle; + array->size++; ++ ++ return VMCI_SUCCESS; + } + + /* +@@ -66,7 +78,7 @@ struct vmci_handle vmci_handle_arr_remov + struct vmci_handle entry_handle) + { + struct vmci_handle handle = VMCI_INVALID_HANDLE; +- size_t i; ++ u32 i; + + for (i = 0; i < array->size; i++) { + if (vmci_handle_is_equal(array->entries[i], entry_handle)) { +@@ -101,7 +113,7 @@ struct vmci_handle vmci_handle_arr_remov + * Handle at given index, VMCI_INVALID_HANDLE if invalid index. + */ + struct vmci_handle +-vmci_handle_arr_get_entry(const struct vmci_handle_arr *array, size_t index) ++vmci_handle_arr_get_entry(const struct vmci_handle_arr *array, u32 index) + { + if (unlikely(index >= array->size)) + return VMCI_INVALID_HANDLE; +@@ -112,7 +124,7 @@ vmci_handle_arr_get_entry(const struct v + bool vmci_handle_arr_has_entry(const struct vmci_handle_arr *array, + struct vmci_handle entry_handle) + { +- size_t i; ++ u32 i; + + for (i = 0; i < array->size; i++) + if (vmci_handle_is_equal(array->entries[i], entry_handle)) +--- a/drivers/misc/vmw_vmci/vmci_handle_array.h ++++ b/drivers/misc/vmw_vmci/vmci_handle_array.h +@@ -9,32 +9,41 @@ + #define _VMCI_HANDLE_ARRAY_H_ + + #include ++#include + #include + +-#define VMCI_HANDLE_ARRAY_DEFAULT_SIZE 4 +-#define VMCI_ARR_CAP_MULT 2 /* Array capacity multiplier */ +- + struct vmci_handle_arr { +- size_t capacity; +- size_t size; ++ u32 capacity; ++ u32 max_capacity; ++ u32 size; ++ u32 pad; + struct vmci_handle entries[]; + }; + +-struct vmci_handle_arr *vmci_handle_arr_create(size_t capacity); ++#define VMCI_HANDLE_ARRAY_HEADER_SIZE \ ++ offsetof(struct vmci_handle_arr, entries) ++/* Select a default capacity that results in a 64 byte sized array */ ++#define VMCI_HANDLE_ARRAY_DEFAULT_CAPACITY 6 ++/* Make sure that the max array size can be expressed by a u32 */ ++#define VMCI_HANDLE_ARRAY_MAX_CAPACITY \ ++ ((U32_MAX - VMCI_HANDLE_ARRAY_HEADER_SIZE - 1) / \ ++ sizeof(struct vmci_handle)) ++ ++struct vmci_handle_arr *vmci_handle_arr_create(u32 capacity, u32 max_capacity); + void vmci_handle_arr_destroy(struct vmci_handle_arr *array); +-void vmci_handle_arr_append_entry(struct vmci_handle_arr **array_ptr, +- struct vmci_handle handle); ++int vmci_handle_arr_append_entry(struct vmci_handle_arr **array_ptr, ++ struct vmci_handle handle); + struct vmci_handle vmci_handle_arr_remove_entry(struct vmci_handle_arr *array, + struct vmci_handle + entry_handle); + struct vmci_handle vmci_handle_arr_remove_tail(struct vmci_handle_arr *array); + struct vmci_handle +-vmci_handle_arr_get_entry(const struct vmci_handle_arr *array, size_t index); ++vmci_handle_arr_get_entry(const struct vmci_handle_arr *array, u32 index); + bool vmci_handle_arr_has_entry(const struct vmci_handle_arr *array, + struct vmci_handle entry_handle); + struct vmci_handle *vmci_handle_arr_get_handles(struct vmci_handle_arr *array); + +-static inline size_t vmci_handle_arr_get_size( ++static inline u32 vmci_handle_arr_get_size( + const struct vmci_handle_arr *array) + { + return array->size; +--- a/include/linux/vmw_vmci_defs.h ++++ b/include/linux/vmw_vmci_defs.h +@@ -62,9 +62,18 @@ enum { + + /* + * A single VMCI device has an upper limit of 128MB on the amount of +- * memory that can be used for queue pairs. ++ * memory that can be used for queue pairs. Since each queue pair ++ * consists of at least two pages, the memory limit also dictates the ++ * number of queue pairs a guest can create. + */ + #define VMCI_MAX_GUEST_QP_MEMORY (128 * 1024 * 1024) ++#define VMCI_MAX_GUEST_QP_COUNT (VMCI_MAX_GUEST_QP_MEMORY / PAGE_SIZE / 2) ++ ++/* ++ * There can be at most PAGE_SIZE doorbells since there is one doorbell ++ * per byte in the doorbell bitmap page. ++ */ ++#define VMCI_MAX_GUEST_DOORBELL_COUNT PAGE_SIZE + + /* + * Queues with pre-mapped data pages must be small, so that we don't pin