Skip to content

Commit

Permalink
Pass VM_PROT_EXECUTE to vm_fault for instruction faults.
Browse files Browse the repository at this point in the history
We need to tell vm_fault the reason for the fault was because we tried to
execute from the memory location. Without this it may return with success
as we only request read-only memory, then we return to the same location
and try to execute from the same memory address. This leads to an infinite
loop raising the same fault and returning to the same invalid location.

MFC after:	1 week
Sponsored by:	DARPA, AFRL
Differential Revision:	https://reviews.freebsd.org/D18511
  • Loading branch information
zxombie committed Dec 27, 2018
1 parent fe53027 commit 4dd54d8
Showing 1 changed file with 7 additions and 3 deletions.
10 changes: 7 additions & 3 deletions sys/arm64/arm64/trap.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ svc_handler(struct thread *td, struct trapframe *frame)

static void
data_abort(struct thread *td, struct trapframe *frame, uint64_t esr,
uint64_t far, int lower)
uint64_t far, int lower, int exec)
{
struct vm_map *map;
struct proc *p;
Expand Down Expand Up @@ -229,6 +229,8 @@ data_abort(struct thread *td, struct trapframe *frame, uint64_t esr,

va = trunc_page(far);
ftype = ((esr >> 6) & 1) ? VM_PROT_READ | VM_PROT_WRITE : VM_PROT_READ;
if (exec)
ftype |= VM_PROT_EXECUTE;

/* Fault in the page. */
error = vm_fault(map, va, ftype, VM_FAULT_NORMAL);
Expand Down Expand Up @@ -336,7 +338,8 @@ do_el1h_sync(struct thread *td, struct trapframe *frame)
case EXCP_DATA_ABORT:
far = READ_SPECIALREG(far_el1);
intr_enable();
data_abort(td, frame, esr, far, 0);
data_abort(td, frame, esr, far, 0,
exception == EXCP_INSN_ABORT);
break;
case EXCP_BRK:
#ifdef KDTRACE_HOOKS
Expand Down Expand Up @@ -433,7 +436,8 @@ do_el0_sync(struct thread *td, struct trapframe *frame)
case EXCP_INSN_ABORT_L:
case EXCP_DATA_ABORT_L:
case EXCP_DATA_ABORT:
data_abort(td, frame, esr, far, 1);
data_abort(td, frame, esr, far, 1,
exception == EXCP_INSN_ABORT_L);
break;
case EXCP_UNKNOWN:
if (!undef_insn(0, frame))
Expand Down

0 comments on commit 4dd54d8

Please sign in to comment.