aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/mm/fault.c
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2018-04-17 16:26:37 -0400
committerEric W. Biederman <ebiederm@xmission.com>2018-04-25 11:40:51 -0400
commit3eb0f5193b497083391aa05d35210d5645211eef (patch)
tree65f009d4cdd5e407741a4431c0aacd40452779bd /arch/arm64/mm/fault.c
parentf6ed1ecad56fec7ab5c6bf741064b95801e9688f (diff)
signal: Ensure every siginfo we send has all bits initialized
Call clear_siginfo to ensure every stack allocated siginfo is properly initialized before being passed to the signal sending functions. Note: It is not safe to depend on C initializers to initialize struct siginfo on the stack because C is allowed to skip holes when initializing a structure. The initialization of struct siginfo in tracehook_report_syscall_exit was moved from the helper user_single_step_siginfo into tracehook_report_syscall_exit itself, to make it clear that the local variable siginfo gets fully initialized. In a few cases the scope of struct siginfo has been reduced to make it clear that siginfo siginfo is not used on other paths in the function in which it is declared. Instances of using memset to initialize siginfo have been replaced with calls clear_siginfo for clarity. Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Diffstat (limited to 'arch/arm64/mm/fault.c')
-rw-r--r--arch/arm64/mm/fault.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 4165485e8b6e..91c53a7d2575 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -305,11 +305,12 @@ static void do_bad_area(unsigned long addr, unsigned int esr, struct pt_regs *re
305 */ 305 */
306 if (user_mode(regs)) { 306 if (user_mode(regs)) {
307 const struct fault_info *inf = esr_to_fault_info(esr); 307 const struct fault_info *inf = esr_to_fault_info(esr);
308 struct siginfo si = { 308 struct siginfo si;
309 .si_signo = inf->sig, 309
310 .si_code = inf->code, 310 clear_siginfo(&si);
311 .si_addr = (void __user *)addr, 311 si.si_signo = inf->sig;
312 }; 312 si.si_code = inf->code;
313 si.si_addr = (void __user *)addr;
313 314
314 __do_user_fault(&si, esr); 315 __do_user_fault(&si, esr);
315 } else { 316 } else {
@@ -583,6 +584,7 @@ static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs)
583 nmi_exit(); 584 nmi_exit();
584 } 585 }
585 586
587 clear_siginfo(&info);
586 info.si_signo = inf->sig; 588 info.si_signo = inf->sig;
587 info.si_errno = 0; 589 info.si_errno = 0;
588 info.si_code = inf->code; 590 info.si_code = inf->code;
@@ -687,6 +689,7 @@ asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr,
687 show_pte(addr); 689 show_pte(addr);
688 } 690 }
689 691
692 clear_siginfo(&info);
690 info.si_signo = inf->sig; 693 info.si_signo = inf->sig;
691 info.si_errno = 0; 694 info.si_errno = 0;
692 info.si_code = inf->code; 695 info.si_code = inf->code;
@@ -729,6 +732,7 @@ asmlinkage void __exception do_sp_pc_abort(unsigned long addr,
729 local_irq_enable(); 732 local_irq_enable();
730 } 733 }
731 734
735 clear_siginfo(&info);
732 info.si_signo = SIGBUS; 736 info.si_signo = SIGBUS;
733 info.si_errno = 0; 737 info.si_errno = 0;
734 info.si_code = BUS_ADRALN; 738 info.si_code = BUS_ADRALN;
@@ -772,7 +776,6 @@ asmlinkage int __exception do_debug_exception(unsigned long addr,
772 struct pt_regs *regs) 776 struct pt_regs *regs)
773{ 777{
774 const struct fault_info *inf = debug_fault_info + DBG_ESR_EVT(esr); 778 const struct fault_info *inf = debug_fault_info + DBG_ESR_EVT(esr);
775 struct siginfo info;
776 int rv; 779 int rv;
777 780
778 /* 781 /*
@@ -788,6 +791,9 @@ asmlinkage int __exception do_debug_exception(unsigned long addr,
788 if (!inf->fn(addr, esr, regs)) { 791 if (!inf->fn(addr, esr, regs)) {
789 rv = 1; 792 rv = 1;
790 } else { 793 } else {
794 struct siginfo info;
795
796 clear_siginfo(&info);
791 info.si_signo = inf->sig; 797 info.si_signo = inf->sig;
792 info.si_errno = 0; 798 info.si_errno = 0;
793 info.si_code = inf->code; 799 info.si_code = inf->code;