mirror of https://github.com/OpenIPC/firmware.git
70 lines
2.1 KiB
Diff
70 lines
2.1 KiB
Diff
diff -drupN a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
|
|
--- a/arch/arm64/mm/fault.c 2018-08-06 17:23:04.000000000 +0300
|
|
+++ b/arch/arm64/mm/fault.c 2022-06-12 05:28:14.000000000 +0300
|
|
@@ -249,6 +249,25 @@ static void do_bad_area(unsigned long ad
|
|
#define VM_FAULT_BADMAP 0x010000
|
|
#define VM_FAULT_BADACCESS 0x020000
|
|
|
|
+static void aw_vma_pid_add(struct vm_area_struct *vma, pid_t pid)
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ if (vma->access_vma_num > 62)
|
|
+ return;
|
|
+ if (vma->access_vma_num == 0) {
|
|
+ vma->access_vma_array[0] = pid;
|
|
+ vma->access_vma_num++;
|
|
+ return;
|
|
+ }
|
|
+ for (i = 0; i < vma->access_vma_num; i++) {
|
|
+ if (pid == vma->access_vma_array[i])
|
|
+ return;
|
|
+ }
|
|
+ vma->access_vma_array[vma->access_vma_num] = pid;
|
|
+ vma->access_vma_num++;
|
|
+}
|
|
+
|
|
static int __do_page_fault(struct mm_struct *mm, unsigned long addr,
|
|
unsigned int mm_flags, unsigned long vm_flags,
|
|
struct task_struct *tsk)
|
|
@@ -277,6 +296,7 @@ good_area:
|
|
goto out;
|
|
}
|
|
|
|
+ aw_vma_pid_add(vma, current->pid);
|
|
return handle_mm_fault(vma, addr & PAGE_MASK, mm_flags);
|
|
|
|
check_stack:
|
|
@@ -286,13 +306,19 @@ out:
|
|
return fault;
|
|
}
|
|
|
|
-static inline bool is_permission_fault(unsigned int esr)
|
|
+static inline bool is_permission_fault(unsigned int esr, struct pt_regs *regs)
|
|
{
|
|
unsigned int ec = ESR_ELx_EC(esr);
|
|
unsigned int fsc_type = esr & ESR_ELx_FSC_TYPE;
|
|
|
|
- return (ec == ESR_ELx_EC_DABT_CUR && fsc_type == ESR_ELx_FSC_PERM) ||
|
|
- (ec == ESR_ELx_EC_IABT_CUR && fsc_type == ESR_ELx_FSC_PERM);
|
|
+ if (ec != ESR_ELx_EC_DABT_CUR && ec != ESR_ELx_EC_IABT_CUR)
|
|
+ return false;
|
|
+
|
|
+ if (system_uses_ttbr0_pan())
|
|
+ return fsc_type == ESR_ELx_FSC_FAULT &&
|
|
+ (regs->pstate & PSR_PAN_BIT);
|
|
+ else
|
|
+ return fsc_type == ESR_ELx_FSC_PERM;
|
|
}
|
|
|
|
static bool is_el0_instruction_abort(unsigned int esr)
|
|
@@ -332,7 +358,7 @@ static int __kprobes do_page_fault(unsig
|
|
mm_flags |= FAULT_FLAG_WRITE;
|
|
}
|
|
|
|
- if (is_permission_fault(esr) && (addr < TASK_SIZE)) {
|
|
+ if (addr < TASK_SIZE && is_permission_fault(esr, regs)) {
|
|
/* regs->orig_addr_limit may be 0 if we entered from EL0 */
|
|
if (regs->orig_addr_limit == KERNEL_DS)
|
|
die("Accessing user space memory with fs=KERNEL_DS", regs, esr);
|