Sun Dec 8 14:31:58 2019 UTC ()
Pull up following revision(s) (requested by ryo in ticket #510):

	sys/arch/arm/arm32/fault.c: revision 1.109

if Thumb-32 bit instruction located on a page boundariy, also need to consider the pc + 2 address.
Fix PR/54720. more detail and PoC are descrived in the PR.


(martin)
diff -r1.108 -r1.108.4.1 src/sys/arch/arm/arm32/fault.c

cvs diff -r1.108 -r1.108.4.1 src/sys/arch/arm/arm32/fault.c (expand / switch to unified diff)

--- src/sys/arch/arm/arm32/fault.c 2019/04/06 03:06:25 1.108
+++ src/sys/arch/arm/arm32/fault.c 2019/12/08 14:31:57 1.108.4.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: fault.c,v 1.108 2019/04/06 03:06:25 thorpej Exp $ */ 1/* $NetBSD: fault.c,v 1.108.4.1 2019/12/08 14:31:57 martin Exp $ */
2 2
3/* 3/*
4 * Copyright 2003 Wasabi Systems, Inc. 4 * Copyright 2003 Wasabi Systems, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Written by Steve C. Woodford for Wasabi Systems, Inc. 7 * Written by Steve C. Woodford for Wasabi Systems, Inc.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
@@ -71,27 +71,27 @@ @@ -71,27 +71,27 @@
71 * RiscBSD kernel project 71 * RiscBSD kernel project
72 * 72 *
73 * fault.c 73 * fault.c
74 * 74 *
75 * Fault handlers 75 * Fault handlers
76 * 76 *
77 * Created : 28/11/94 77 * Created : 28/11/94
78 */ 78 */
79 79
80#include "opt_ddb.h" 80#include "opt_ddb.h"
81#include "opt_kgdb.h" 81#include "opt_kgdb.h"
82 82
83#include <sys/types.h> 83#include <sys/types.h>
84__KERNEL_RCSID(0, "$NetBSD: fault.c,v 1.108 2019/04/06 03:06:25 thorpej Exp $"); 84__KERNEL_RCSID(0, "$NetBSD: fault.c,v 1.108.4.1 2019/12/08 14:31:57 martin Exp $");
85 85
86#include <sys/param.h> 86#include <sys/param.h>
87#include <sys/systm.h> 87#include <sys/systm.h>
88#include <sys/proc.h> 88#include <sys/proc.h>
89#include <sys/kernel.h> 89#include <sys/kernel.h>
90#include <sys/kauth.h> 90#include <sys/kauth.h>
91#include <sys/cpu.h> 91#include <sys/cpu.h>
92#include <sys/intr.h> 92#include <sys/intr.h>
93 93
94#include <uvm/uvm_extern.h> 94#include <uvm/uvm_extern.h>
95#include <uvm/uvm_stat.h> 95#include <uvm/uvm_stat.h>
96#ifdef UVMHIST 96#ifdef UVMHIST
97#include <uvm/uvm.h> 97#include <uvm/uvm.h>
@@ -828,26 +828,29 @@ prefetch_abort_handler(trapframe_t *tf) @@ -828,26 +828,29 @@ prefetch_abort_handler(trapframe_t *tf)
828 break; 828 break;
829 } 829 }
830 830
831 /* Prefetch aborts cannot happen in kernel mode */ 831 /* Prefetch aborts cannot happen in kernel mode */
832 if (__predict_false(!user)) 832 if (__predict_false(!user))
833 dab_fatal(tf, 0, tf->tf_pc, NULL, NULL); 833 dab_fatal(tf, 0, tf->tf_pc, NULL, NULL);
834 834
835 /* Get fault address */ 835 /* Get fault address */
836 fault_pc = tf->tf_pc; 836 fault_pc = tf->tf_pc;
837 KASSERTMSG(tf == lwp_trapframe(l), "tf %p vs %p", tf, lwp_trapframe(l)); 837 KASSERTMSG(tf == lwp_trapframe(l), "tf %p vs %p", tf, lwp_trapframe(l));
838 UVMHIST_LOG(maphist, " (pc=0x%jx, l=0x%#jx, tf=0x%#jx)", 838 UVMHIST_LOG(maphist, " (pc=0x%jx, l=0x%#jx, tf=0x%#jx)",
839 fault_pc, (uintptr_t)l, (uintptr_t)tf, 0); 839 fault_pc, (uintptr_t)l, (uintptr_t)tf, 0);
840 840
 841#ifdef THUMB_CODE
 842 recheck:
 843#endif
841 /* Ok validate the address, can only execute in USER space */ 844 /* Ok validate the address, can only execute in USER space */
842 if (__predict_false(fault_pc >= VM_MAXUSER_ADDRESS || 845 if (__predict_false(fault_pc >= VM_MAXUSER_ADDRESS ||
843 (fault_pc < VM_MIN_ADDRESS && vector_page == ARM_VECTORS_LOW))) { 846 (fault_pc < VM_MIN_ADDRESS && vector_page == ARM_VECTORS_LOW))) {
844 KSI_INIT_TRAP(&ksi); 847 KSI_INIT_TRAP(&ksi);
845 ksi.ksi_signo = SIGSEGV; 848 ksi.ksi_signo = SIGSEGV;
846 ksi.ksi_code = SEGV_ACCERR; 849 ksi.ksi_code = SEGV_ACCERR;
847 ksi.ksi_addr = (uint32_t *)(intptr_t) fault_pc; 850 ksi.ksi_addr = (uint32_t *)(intptr_t) fault_pc;
848 ksi.ksi_trap = fault_pc; 851 ksi.ksi_trap = fault_pc;
849 goto do_trapsignal; 852 goto do_trapsignal;
850 } 853 }
851 854
852 map = &l->l_proc->p_vmspace->vm_map; 855 map = &l->l_proc->p_vmspace->vm_map;
853 va = trunc_page(fault_pc); 856 va = trunc_page(fault_pc);
@@ -887,26 +890,38 @@ prefetch_abort_handler(trapframe_t *tf) @@ -887,26 +890,38 @@ prefetch_abort_handler(trapframe_t *tf)
887 l->l_cred ? kauth_cred_geteuid(l->l_cred) : -1); 890 l->l_cred ? kauth_cred_geteuid(l->l_cred) : -1);
888 ksi.ksi_signo = SIGKILL; 891 ksi.ksi_signo = SIGKILL;
889 } else 892 } else
890 ksi.ksi_signo = SIGSEGV; 893 ksi.ksi_signo = SIGSEGV;
891 894
892 ksi.ksi_code = SEGV_MAPERR; 895 ksi.ksi_code = SEGV_MAPERR;
893 ksi.ksi_addr = (uint32_t *)(intptr_t) fault_pc; 896 ksi.ksi_addr = (uint32_t *)(intptr_t) fault_pc;
894 ksi.ksi_trap = fault_pc; 897 ksi.ksi_trap = fault_pc;
895 898
896do_trapsignal: 899do_trapsignal:
897 call_trapsignal(l, tf, &ksi); 900 call_trapsignal(l, tf, &ksi);
898 901
899out: 902out:
 903
 904#ifdef THUMB_CODE
 905#define THUMB_32BIT(hi) (((hi) & 0xe000) == 0xe000 && ((hi) & 0x1800))
 906 /* thumb-32 instruction was located on page boundary? */
 907 if ((tf->tf_spsr & PSR_T_bit) &&
 908 ((fault_pc & PAGE_MASK) == (PAGE_SIZE - THUMB_INSN_SIZE)) &&
 909 THUMB_32BIT(*(uint16_t *)tf->tf_pc)) {
 910 fault_pc = tf->tf_pc + THUMB_INSN_SIZE;
 911 goto recheck;
 912 }
 913#endif /* THUMB_CODE */
 914
900 KASSERT(!TRAP_USERMODE(tf) || VALID_R15_PSR(tf->tf_pc, tf->tf_spsr)); 915 KASSERT(!TRAP_USERMODE(tf) || VALID_R15_PSR(tf->tf_pc, tf->tf_spsr));
901 userret(l); 916 userret(l);
902} 917}
903 918
904/* 919/*
905 * Tentatively read an 8, 16, or 32-bit value from 'addr'. 920 * Tentatively read an 8, 16, or 32-bit value from 'addr'.
906 * If the read succeeds, the value is written to 'rptr' and zero is returned. 921 * If the read succeeds, the value is written to 'rptr' and zero is returned.
907 * Else, return EFAULT. 922 * Else, return EFAULT.
908 */ 923 */
909int 924int
910badaddr_read(void *addr, size_t size, void *rptr) 925badaddr_read(void *addr, size_t size, void *rptr)
911{ 926{
912 extern int badaddr_read_1(const uint8_t *, uint8_t *); 927 extern int badaddr_read_1(const uint8_t *, uint8_t *);