Patch "arm64: fix oops in concurrently setting insn_emulation sysctls" has been added to the 4.9-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    arm64: fix oops in concurrently setting insn_emulation sysctls

to the 4.9-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     arm64-fix-oops-in-concurrently-setting-insn_emulatio.patch
and it can be found in the queue-4.9 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit d11fd57d7876964c06e2423f753f77ff513d7604
Author: haibinzhang (张海斌) <haibinzhang@xxxxxxxxxxx>
Date:   Sat Jul 2 05:43:19 2022 +0000

    arm64: fix oops in concurrently setting insn_emulation sysctls
    
    [ Upstream commit af483947d472eccb79e42059276c4deed76f99a6 ]
    
    emulation_proc_handler() changes table->data for proc_dointvec_minmax
    and can generate the following Oops if called concurrently with itself:
    
     | Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010
     | Internal error: Oops: 96000006 [#1] SMP
     | Call trace:
     | update_insn_emulation_mode+0xc0/0x148
     | emulation_proc_handler+0x64/0xb8
     | proc_sys_call_handler+0x9c/0xf8
     | proc_sys_write+0x18/0x20
     | __vfs_write+0x20/0x48
     | vfs_write+0xe4/0x1d0
     | ksys_write+0x70/0xf8
     | __arm64_sys_write+0x20/0x28
     | el0_svc_common.constprop.0+0x7c/0x1c0
     | el0_svc_handler+0x2c/0xa0
     | el0_svc+0x8/0x200
    
    To fix this issue, keep the table->data as &insn->current_mode and
    use container_of() to retrieve the insn pointer. Another mutex is
    used to protect against the current_mode update but not for retrieving
    insn_emulation as table->data is no longer changing.
    
    Co-developed-by: hewenliang <hewenliang4@xxxxxxxxxx>
    Signed-off-by: hewenliang <hewenliang4@xxxxxxxxxx>
    Signed-off-by: Haibin Zhang <haibinzhang@xxxxxxxxxxx>
    Reviewed-by: Catalin Marinas <catalin.marinas@xxxxxxx>
    Link: https://lore.kernel.org/r/20220128090324.2727688-1-hewenliang4@xxxxxxxxxx
    Link: https://lore.kernel.org/r/9A004C03-250B-46C5-BF39-782D7551B00E@xxxxxxxxxxx
    Signed-off-by: Will Deacon <will@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/arch/arm64/kernel/armv8_deprecated.c b/arch/arm64/kernel/armv8_deprecated.c
index 49989207989a..89946ed1adb9 100644
--- a/arch/arm64/kernel/armv8_deprecated.c
+++ b/arch/arm64/kernel/armv8_deprecated.c
@@ -64,6 +64,7 @@ struct insn_emulation {
 static LIST_HEAD(insn_emulation);
 static int nr_insn_emulated __initdata;
 static DEFINE_RAW_SPINLOCK(insn_emulation_lock);
+static DEFINE_MUTEX(insn_emulation_mutex);
 
 static void register_emulation_hooks(struct insn_emulation_ops *ops)
 {
@@ -209,10 +210,10 @@ static int emulation_proc_handler(struct ctl_table *table, int write,
 				  loff_t *ppos)
 {
 	int ret = 0;
-	struct insn_emulation *insn = (struct insn_emulation *) table->data;
+	struct insn_emulation *insn = container_of(table->data, struct insn_emulation, current_mode);
 	enum insn_emulation_mode prev_mode = insn->current_mode;
 
-	table->data = &insn->current_mode;
+	mutex_lock(&insn_emulation_mutex);
 	ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
 
 	if (ret || !write || prev_mode == insn->current_mode)
@@ -225,7 +226,7 @@ static int emulation_proc_handler(struct ctl_table *table, int write,
 		update_insn_emulation_mode(insn, INSN_UNDEF);
 	}
 ret:
-	table->data = insn;
+	mutex_unlock(&insn_emulation_mutex);
 	return ret;
 }
 
@@ -255,7 +256,7 @@ static void __init register_insn_emulation_sysctl(struct ctl_table *table)
 		sysctl->maxlen = sizeof(int);
 
 		sysctl->procname = insn->ops->name;
-		sysctl->data = insn;
+		sysctl->data = &insn->current_mode;
 		sysctl->extra1 = &insn->min;
 		sysctl->extra2 = &insn->max;
 		sysctl->proc_handler = emulation_proc_handler;



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux