From: Greg Kroah-Hartman Date: Tue, 31 Oct 2023 11:18:42 +0000 (+0100) Subject: 5.4-stable patches X-Git-Tag: v6.1.61~30 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=90e51d1960e9ea46d647750175d1ac9a84cf4339;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: arm64-fix-a-concurrency-issue-in-emulation_proc_handler.patch --- diff --git a/queue-5.4/arm64-fix-a-concurrency-issue-in-emulation_proc_handler.patch b/queue-5.4/arm64-fix-a-concurrency-issue-in-emulation_proc_handler.patch new file mode 100644 index 00000000000..0a178f18a75 --- /dev/null +++ b/queue-5.4/arm64-fix-a-concurrency-issue-in-emulation_proc_handler.patch @@ -0,0 +1,109 @@ +From ruanjinjie@huawei.com Tue Oct 31 12:17:33 2023 +From: Jinjie Ruan +Date: Mon, 30 Oct 2023 06:37:09 +0000 +Subject: arm64: fix a concurrency issue in emulation_proc_handler() +To: , , , , , +Cc: +Message-ID: <20231030063709.2443546-1-ruanjinjie@huawei.com> + +From: Jinjie Ruan + +In linux-6.1, the related code is refactored in commit 124c49b1b5d9 +("arm64: armv8_deprecated: rework deprected instruction handling") and this +issue was incidentally fixed. I have adapted the patch set to linux stable +5.10. However, 4.19 and 5.10 are too different and the patch set is +hard to adapt to 4.19. + +This patch is to solve the problem of repeated addition of linked lists +described below with few changes. + +How to reproduce: +CONFIG_ARMV8_DEPRECATED=y, CONFIG_SWP_EMULATION=y, and CONFIG_DEBUG_LIST=y, +then launch two shell executions: + #!/bin/bash + while [ 1 ]; + do + echo 1 > /proc/sys/abi/swp + done + +or "echo 1 > /proc/sys/abi/swp" and then aunch two shell executions: + #!/bin/bash + while [ 1 ]; + do + echo 0 > /proc/sys/abi/swp + done + +In emulation_proc_handler(), read and write operations are performed on +insn->current_mode. In the concurrency scenario, mutex only protects +writing insn->current_mode, and not protects the read. Suppose there are +two concurrent tasks, task1 updates insn->current_mode to INSN_EMULATE +in the critical section, the prev_mode of task2 is still the old data +INSN_UNDEF of insn->current_mode. As a result, two tasks call +update_insn_emulation_mode twice with prev_mode = INSN_UNDEF and +current_mode = INSN_EMULATE, then call register_emulation_hooks twice, +resulting in a list_add double problem. + +After applying this patch, the following list add or list del double +warnings never occur. + +Call trace: + __list_add_valid+0xd8/0xe4 + register_undef_hook+0x94/0x13c + update_insn_emulation_mode+0xd0/0x12c + emulation_proc_handler+0xd8/0xf4 + proc_sys_call_handler+0x140/0x250 + proc_sys_write+0x1c/0x2c + new_sync_write+0xec/0x18c + vfs_write+0x214/0x2ac + ksys_write+0x70/0xfc + __arm64_sys_write+0x24/0x30 + el0_svc_common.constprop.0+0x7c/0x1bc + do_el0_svc+0x2c/0x94 + el0_svc+0x20/0x30 + el0_sync_handler+0xb0/0xb4 + el0_sync+0x160/0x180 + +Call trace: + __list_del_entry_valid+0xac/0x110 + unregister_undef_hook+0x34/0x80 + update_insn_emulation_mode+0xf0/0x180 + emulation_proc_handler+0x8c/0xd8 + proc_sys_call_handler+0x1d8/0x208 + proc_sys_write+0x14/0x20 + new_sync_write+0xf0/0x190 + vfs_write+0x304/0x388 + ksys_write+0x6c/0x100 + __arm64_sys_write+0x1c/0x28 + el0_svc_common.constprop.4+0x68/0x188 + do_el0_svc+0x24/0xa0 + el0_svc+0x14/0x20 + el0_sync_handler+0x90/0xb8 + el0_sync+0x160/0x180 + +Fixes: af483947d472 ("arm64: fix oops in concurrently setting insn_emulation sysctls") +Cc: stable@vger.kernel.org#4.19.x +Cc: gregkh@linuxfoundation.org +Signed-off-by: Jinjie Ruan +Acked-by: Mark Rutland +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/kernel/armv8_deprecated.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/arch/arm64/kernel/armv8_deprecated.c ++++ b/arch/arm64/kernel/armv8_deprecated.c +@@ -208,10 +208,12 @@ static int emulation_proc_handler(struct + loff_t *ppos) + { + int ret = 0; +- struct insn_emulation *insn = container_of(table->data, struct insn_emulation, current_mode); +- enum insn_emulation_mode prev_mode = insn->current_mode; ++ struct insn_emulation *insn; ++ enum insn_emulation_mode prev_mode; + + mutex_lock(&insn_emulation_mutex); ++ insn = container_of(table->data, struct insn_emulation, current_mode); ++ prev_mode = insn->current_mode; + ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); + + if (ret || !write || prev_mode == insn->current_mode) diff --git a/queue-5.4/series b/queue-5.4/series index 4616cfcfc29..bf13c56f93e 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -36,3 +36,4 @@ x86-acpi-don-t-add-cpus-that-are-not-online-capable.patch x86-acpi-boot-use-fadt-version-to-check-support-for-.patch x86-i8259-skip-probing-when-acpi-madt-advertises-pca.patch drm-dp_mst-fix-null-deref-in-get_mst_branch_device_by_guid_helper.patch +arm64-fix-a-concurrency-issue-in-emulation_proc_handler.patch