Patch "arm64: mm: unaligned access by user-land should be received as SIGBUS" has been added to the 4.10-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
arm64: mm: unaligned access by user-land should be received as SIGBUS
to the 4.10-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-mm-unaligned-access-by-user-land-should-be-received-as-sigbus.patch
and it can be found in the queue-4.10 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
09a6adf53d42ca3088fa3fb41f40b768efc711edMon Sep 17 00:00:00 2001
From: Victor Kamensky <[email protected]>
Date: Mon, 3 Apr 2017 22:51:01 -0700
Subject: arm64: mm: unaligned access by user-land should be received as SIGBUS
From: Victor Kamensky <[email protected]>
commit 09a6adf53d42ca3088fa3fb41f40b768efc711ed upstream.
After 52d7523 (arm64: mm: allow the kernel to handle alignment faults on user accesses) commit user-land accesses that produce unaligned exceptions like in case of aarch32 ldm/stm/ldrd/strd instructions operating on unaligned memory received by user-land as SIGSEGV. It is wrong, it should be reported as SIGBUS as it was before 52d7523 commit.
Changed do_bad_area function to take signal and code parameters out of esr value using fault_info table, so in case of do_alignment_fault fault user-land will receive SIGBUS. Wrapped access to fault_info table into esr_to_fault_info function.
--- arch/arm64/mm/fault.c | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-)
arch/arm64/mm/fault.c +24 -18
@@ -41,7 +41,20 @@#include <asm/pgtable.h> #include <asm/tlbflush.h> -static const char *fault_name (unsigned int esr); +struct fault_info { +int (*fn)(unsigned long addr,unsigned int esr, +struct pt_regs *regs); +int sig; +int code; +const char *name; +}; + +static const struct fault_info fault_info[]; + +static inline const struct fault_info *esr_to_fault_info (unsigned int esr) +{ +return fault_info + (esr &63 ); +}#ifdef CONFIG_KPROBES static inline int notify_page_fault (struct pt_regs *regs,unsigned int esr)
@@ -196,10 +209,12 @@ static void __do_user_fault(struct task_ struct pt_regs *regs) {struct siginfo si; +const struct fault_info *inf;if (unhandled_signal (tsk, sig) &&show_unhandled_signals_ratelimited ()) { + inf =esr_to_fault_info (esr);pr_info ("%s[%d]: unhandled %s (%d) at 0x%08lx, esr 0x%03x\n" , - tsk->comm,task_pid_nr (tsk),fault_name (esr), sig, + tsk->comm,task_pid_nr (tsk), inf->name, sig, addr, esr);show_pte (tsk->mm, addr);show_regs (regs);
@@ -218,14 +233,16 @@ static void do_bad_area(unsigned long ad {struct task_struct *tsk = current;struct mm_struct *mm = tsk->active_mm; +const struct fault_info *inf;/* * If we are in kernel mode at this point, we have no context to * handle this fault with. */ -if (user_mode (regs)) -__do_user_fault (tsk, addr, esr,SIGSEGV ,SEGV_MAPERR , regs); -else +if (user_mode (regs)) { + inf =esr_to_fault_info (esr); +__do_user_fault (tsk, addr, esr, inf->sig, inf->code, regs); + }else __do_kernel_fault (mm, addr, esr, regs); }
@@ -487,12 +504,7 @@ static int do_bad(unsigned long addr, unreturn 1 ; } -static const struct fault_info { -int (*fn)(unsigned long addr,unsigned int esr,struct pt_regs *regs); -int sig; -int code; -const char *name; -} fault_info[] = { +static const struct fault_info fault_info[] = { { do_bad,SIGBUS ,0 ,"ttbr address size fault" }, { do_bad,SIGBUS ,0 ,"level 1 address size fault" }, { do_bad,SIGBUS ,0 ,"level 2 address size fault" },
@@ -559,19 +571,13 @@ static const struct fault_info { { do_bad, SIGBUS, 0, "unknown 63" }, }; -static const char *fault_name (unsigned int esr) -{ -const struct fault_info *inf = fault_info + (esr &63 ); -return inf->name; -} -/* * Dispatch a data abort to the relevant handler. */ asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr,struct pt_regs *regs) { -const struct fault_info *inf = fault_info + (esr &63 ); +const struct fault_info *inf =esr_to_fault_info (esr);struct siginfo info;if (!inf->fn (addr, esr, regs))
Patches currently in stable-queue which might be from [email protected] are
queue-4.10/arm64-mm-unaligned-access-by-user-land-should-be-received-as-sigbus.patch