From: Greg Kroah-Hartman Date: Fri, 6 Aug 2021 06:59:08 +0000 (+0200) Subject: 4.19-stable patches X-Git-Tag: v4.4.279~10 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=67bcca3f7ebd429247c7769a6bee0289fc170369;p=thirdparty%2Fkernel%2Fstable-queue.git 4.19-stable patches added patches: padata-add-separate-cpuhp-node-for-cpuhp_padata_dead.patch padata-validate-cpumask-without-removed-cpu-during-offline.patch --- diff --git a/queue-4.19/padata-add-separate-cpuhp-node-for-cpuhp_padata_dead.patch b/queue-4.19/padata-add-separate-cpuhp-node-for-cpuhp_padata_dead.patch new file mode 100644 index 00000000000..d5c878f3499 --- /dev/null +++ b/queue-4.19/padata-add-separate-cpuhp-node-for-cpuhp_padata_dead.patch @@ -0,0 +1,116 @@ +From 3c2214b6027ff37945799de717c417212e1a8c54 Mon Sep 17 00:00:00 2001 +From: Daniel Jordan +Date: Tue, 21 Apr 2020 12:34:55 -0400 +Subject: padata: add separate cpuhp node for CPUHP_PADATA_DEAD + +From: Daniel Jordan + +commit 3c2214b6027ff37945799de717c417212e1a8c54 upstream. + +Removing the pcrypt module triggers this: + + general protection fault, probably for non-canonical + address 0xdead000000000122 + CPU: 5 PID: 264 Comm: modprobe Not tainted 5.6.0+ #2 + Hardware name: QEMU Standard PC + RIP: 0010:__cpuhp_state_remove_instance+0xcc/0x120 + Call Trace: + padata_sysfs_release+0x74/0xce + kobject_put+0x81/0xd0 + padata_free+0x12/0x20 + pcrypt_exit+0x43/0x8ee [pcrypt] + +padata instances wrongly use the same hlist node for the online and dead +states, so __padata_free()'s second cpuhp remove call chokes on the node +that the first poisoned. + +cpuhp multi-instance callbacks only walk forward in cpuhp_step->list and +the same node is linked in both the online and dead lists, so the list +corruption that results from padata_alloc() adding the node to a second +list without removing it from the first doesn't cause problems as long +as no instances are freed. + +Avoid the issue by giving each state its own node. + +Fixes: 894c9ef9780c ("padata: validate cpumask without removed CPU during offline") +Signed-off-by: Daniel Jordan +Cc: Herbert Xu +Cc: Steffen Klassert +Cc: linux-crypto@vger.kernel.org +Cc: linux-kernel@vger.kernel.org +Cc: stable@vger.kernel.org # v5.4+ +Signed-off-by: Herbert Xu +Signed-off-by: Yang Yingliang +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/padata.h | 6 ++++-- + kernel/padata.c | 14 ++++++++------ + 2 files changed, 12 insertions(+), 8 deletions(-) + +--- a/include/linux/padata.h ++++ b/include/linux/padata.h +@@ -138,7 +138,8 @@ struct parallel_data { + /** + * struct padata_instance - The overall control structure. + * +- * @cpu_notifier: cpu hotplug notifier. ++ * @cpu_online_node: Linkage for CPU online callback. ++ * @cpu_dead_node: Linkage for CPU offline callback. + * @wq: The workqueue in use. + * @pd: The internal control structure. + * @cpumask: User supplied cpumasks for parallel and serial works. +@@ -150,7 +151,8 @@ struct parallel_data { + * @flags: padata flags. + */ + struct padata_instance { +- struct hlist_node node; ++ struct hlist_node cpu_online_node; ++ struct hlist_node cpu_dead_node; + struct workqueue_struct *wq; + struct parallel_data *pd; + struct padata_cpumask cpumask; +--- a/kernel/padata.c ++++ b/kernel/padata.c +@@ -748,7 +748,7 @@ static int padata_cpu_online(unsigned in + struct padata_instance *pinst; + int ret; + +- pinst = hlist_entry_safe(node, struct padata_instance, node); ++ pinst = hlist_entry_safe(node, struct padata_instance, cpu_online_node); + if (!pinst_has_cpu(pinst, cpu)) + return 0; + +@@ -763,7 +763,7 @@ static int padata_cpu_dead(unsigned int + struct padata_instance *pinst; + int ret; + +- pinst = hlist_entry_safe(node, struct padata_instance, node); ++ pinst = hlist_entry_safe(node, struct padata_instance, cpu_dead_node); + if (!pinst_has_cpu(pinst, cpu)) + return 0; + +@@ -779,8 +779,9 @@ static enum cpuhp_state hp_online; + static void __padata_free(struct padata_instance *pinst) + { + #ifdef CONFIG_HOTPLUG_CPU +- cpuhp_state_remove_instance_nocalls(CPUHP_PADATA_DEAD, &pinst->node); +- cpuhp_state_remove_instance_nocalls(hp_online, &pinst->node); ++ cpuhp_state_remove_instance_nocalls(CPUHP_PADATA_DEAD, ++ &pinst->cpu_dead_node); ++ cpuhp_state_remove_instance_nocalls(hp_online, &pinst->cpu_online_node); + #endif + + padata_stop(pinst); +@@ -964,9 +965,10 @@ static struct padata_instance *padata_al + mutex_init(&pinst->lock); + + #ifdef CONFIG_HOTPLUG_CPU +- cpuhp_state_add_instance_nocalls_cpuslocked(hp_online, &pinst->node); ++ cpuhp_state_add_instance_nocalls_cpuslocked(hp_online, ++ &pinst->cpu_online_node); + cpuhp_state_add_instance_nocalls_cpuslocked(CPUHP_PADATA_DEAD, +- &pinst->node); ++ &pinst->cpu_dead_node); + #endif + return pinst; + diff --git a/queue-4.19/padata-validate-cpumask-without-removed-cpu-during-offline.patch b/queue-4.19/padata-validate-cpumask-without-removed-cpu-during-offline.patch new file mode 100644 index 00000000000..1f8ece69937 --- /dev/null +++ b/queue-4.19/padata-validate-cpumask-without-removed-cpu-during-offline.patch @@ -0,0 +1,131 @@ +From 894c9ef9780c5cf2f143415e867ee39a33ecb75d Mon Sep 17 00:00:00 2001 +From: Daniel Jordan +Date: Tue, 3 Dec 2019 14:31:10 -0500 +Subject: padata: validate cpumask without removed CPU during offline + +From: Daniel Jordan + +commit 894c9ef9780c5cf2f143415e867ee39a33ecb75d upstream. + +Configuring an instance's parallel mask without any online CPUs... + + echo 2 > /sys/kernel/pcrypt/pencrypt/parallel_cpumask + echo 0 > /sys/devices/system/cpu/cpu1/online + +...makes tcrypt mode=215 crash like this: + + divide error: 0000 [#1] SMP PTI + CPU: 4 PID: 283 Comm: modprobe Not tainted 5.4.0-rc8-padata-doc-v2+ #2 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS ?-20191013_105130-anatol 04/01/2014 + RIP: 0010:padata_do_parallel+0x114/0x300 + Call Trace: + pcrypt_aead_encrypt+0xc0/0xd0 [pcrypt] + crypto_aead_encrypt+0x1f/0x30 + do_mult_aead_op+0x4e/0xdf [tcrypt] + test_mb_aead_speed.constprop.0.cold+0x226/0x564 [tcrypt] + do_test+0x28c2/0x4d49 [tcrypt] + tcrypt_mod_init+0x55/0x1000 [tcrypt] + ... + +cpumask_weight() in padata_cpu_hash() returns 0 because the mask has no +CPUs. The problem is __padata_remove_cpu() checks for valid masks too +early and so doesn't mark the instance PADATA_INVALID as expected, which +would have made padata_do_parallel() return error before doing the +division. + +Fix by introducing a second padata CPU hotplug state before +CPUHP_BRINGUP_CPU so that __padata_remove_cpu() sees the online mask +without @cpu. No need for the second argument to padata_replace() since +@cpu is now already missing from the online mask. + +Fixes: 33e54450683c ("padata: Handle empty padata cpumasks") +Signed-off-by: Daniel Jordan +Cc: Eric Biggers +Cc: Herbert Xu +Cc: Sebastian Andrzej Siewior +Cc: Steffen Klassert +Cc: Thomas Gleixner +Cc: linux-crypto@vger.kernel.org +Cc: linux-kernel@vger.kernel.org +Signed-off-by: Herbert Xu +Signed-off-by: Yang Yingliang +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/cpuhotplug.h | 1 + + kernel/padata.c | 18 ++++++++++++++---- + 2 files changed, 15 insertions(+), 4 deletions(-) + +--- a/include/linux/cpuhotplug.h ++++ b/include/linux/cpuhotplug.h +@@ -59,6 +59,7 @@ enum cpuhp_state { + CPUHP_IOMMU_INTEL_DEAD, + CPUHP_LUSTRE_CFS_DEAD, + CPUHP_AP_ARM_CACHE_B15_RAC_DEAD, ++ CPUHP_PADATA_DEAD, + CPUHP_WORKQUEUE_PREP, + CPUHP_POWER_NUMA_PREPARE, + CPUHP_HRTIMERS_PREPARE, +--- a/kernel/padata.c ++++ b/kernel/padata.c +@@ -682,7 +682,7 @@ static int __padata_remove_cpu(struct pa + { + struct parallel_data *pd = NULL; + +- if (cpumask_test_cpu(cpu, cpu_online_mask)) { ++ if (!cpumask_test_cpu(cpu, cpu_online_mask)) { + + if (!padata_validate_cpumask(pinst, pinst->cpumask.pcpu) || + !padata_validate_cpumask(pinst, pinst->cpumask.cbcpu)) +@@ -758,7 +758,7 @@ static int padata_cpu_online(unsigned in + return ret; + } + +-static int padata_cpu_prep_down(unsigned int cpu, struct hlist_node *node) ++static int padata_cpu_dead(unsigned int cpu, struct hlist_node *node) + { + struct padata_instance *pinst; + int ret; +@@ -779,6 +779,7 @@ static enum cpuhp_state hp_online; + static void __padata_free(struct padata_instance *pinst) + { + #ifdef CONFIG_HOTPLUG_CPU ++ cpuhp_state_remove_instance_nocalls(CPUHP_PADATA_DEAD, &pinst->node); + cpuhp_state_remove_instance_nocalls(hp_online, &pinst->node); + #endif + +@@ -964,6 +965,8 @@ static struct padata_instance *padata_al + + #ifdef CONFIG_HOTPLUG_CPU + cpuhp_state_add_instance_nocalls_cpuslocked(hp_online, &pinst->node); ++ cpuhp_state_add_instance_nocalls_cpuslocked(CPUHP_PADATA_DEAD, ++ &pinst->node); + #endif + return pinst; + +@@ -1010,17 +1013,24 @@ static __init int padata_driver_init(voi + int ret; + + ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN, "padata:online", +- padata_cpu_online, +- padata_cpu_prep_down); ++ padata_cpu_online, NULL); + if (ret < 0) + return ret; + hp_online = ret; ++ ++ ret = cpuhp_setup_state_multi(CPUHP_PADATA_DEAD, "padata:dead", ++ NULL, padata_cpu_dead); ++ if (ret < 0) { ++ cpuhp_remove_multi_state(hp_online); ++ return ret; ++ } + return 0; + } + module_init(padata_driver_init); + + static __exit void padata_driver_exit(void) + { ++ cpuhp_remove_multi_state(CPUHP_PADATA_DEAD); + cpuhp_remove_multi_state(hp_online); + } + module_exit(padata_driver_exit); diff --git a/queue-4.19/series b/queue-4.19/series index 838b8369a87..fe49cfee7ed 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -12,3 +12,5 @@ revert-bluetooth-shutdown-controller-after-workqueues-are-flushed-or-cancelled.p drm-i915-ensure-intel_engine_init_execlist-builds-with-clang.patch firmware-arm_scmi-ensure-drivers-provide-a-probe-function.patch revert-watchdog-itco_wdt-account-for-rebooting-on-second-timeout.patch +padata-validate-cpumask-without-removed-cpu-during-offline.patch +padata-add-separate-cpuhp-node-for-cpuhp_padata_dead.patch