On Fri, 20 Dec 2019, Alexander Bluhm wrote: > Can we use the regular trap panic for SMEP and SMAP? pageflttrap() > returns 0 to print a nice reason in kerntrap(). Especially if ddb is > disabled, additional information is printed. > > attempt to access user address 0xe27539f1000 in supervisor mode > fatal page fault in supervisor mode > trap type 6 code 3 rip ffffffff819c2665 cs 8 rflags 10202 cr2 e27539f1000 cpl > 0 rsp ffff80001ffbfe28 > gsbase 0xffff80001fb63ff0 kgsbase 0x0 > panic: trap type 6, code=3, pc=ffffffff819c2665 ... > Index: arch/amd64/amd64/trap.c > =================================================================== > RCS file: /data/mirror/openbsd/cvs/src/sys/arch/amd64/amd64/trap.c,v > retrieving revision 1.77 > diff -u -p -r1.77 trap.c > --- arch/amd64/amd64/trap.c 6 Sep 2019 12:22:01 -0000 1.77 > +++ arch/amd64/amd64/trap.c 19 Dec 2019 23:46:40 -0000 > @@ -163,14 +163,18 @@ pageflttrap(struct trapframe *frame, int > extern struct vm_map *kernel_map; > > /* This will only trigger if SMEP is enabled */ > - if (cr2 <= VM_MAXUSER_ADDRESS && frame->tf_err & PGEX_I) > - panic("attempt to execute user address %p " > - "in supervisor mode", (void *)cr2); > + if (cr2 <= VM_MAXUSER_ADDRESS && frame->tf_err & PGEX_I) { > + printf("attempt to execute user address %p " > + "in supervisor mode\n", (void *)cr2); > + return 0; > + } > /* This will only trigger if SMAP is enabled */ > if (pcb->pcb_onfault == NULL && cr2 <= VM_MAXUSER_ADDRESS && > - frame->tf_err & PGEX_P) > - panic("attempt to access user address %p " > - "in supervisor mode", (void *)cr2); > + frame->tf_err & PGEX_P) { > + printf("attempt to access user address %p " > + "in supervisor mode\n", (void *)cr2); > + return 0; > + } > > /* > * It is only a kernel address space fault iff:
For this part, should we reuse the 'faultstr' logic seen later to set the panic string and do something like, say... Index: amd64/trap.c =================================================================== RCS file: /data/src/openbsd/src/sys/arch/amd64/amd64/trap.c,v retrieving revision 1.77 diff -u -p -r1.77 trap.c --- amd64/trap.c 6 Sep 2019 12:22:01 -0000 1.77 +++ amd64/trap.c 20 Dec 2019 02:21:03 -0000 @@ -77,6 +77,7 @@ #include <sys/signal.h> #include <sys/syscall.h> #include <sys/syscall_mi.h> +#include <sys/stdarg.h> #include <uvm/uvm_extern.h> @@ -132,6 +133,24 @@ static inline void verify_smap(const cha static inline void debug_trap(struct trapframe *_frame, struct proc *_p, long _type); +static inline int +fault(const char *format, ...) +{ + static char faultbuf[512]; + va_list ap; + + /* + * Save the fault info for DDB and retain the kernel lock to keep + * faultbuf from being overwritten by another CPU. + */ + va_start(ap, format); + vsnprintf(faultbuf, sizeof faultbuf, format, ap); + va_end(ap); + printf("%s\n", faultbuf); + faultstr = faultbuf; + return 0; +} + /* * pageflttrap(frame, usermode): page fault handler * Returns non-zero if the fault was handled (possibly by generating @@ -164,12 +183,12 @@ pageflttrap(struct trapframe *frame, int /* This will only trigger if SMEP is enabled */ if (cr2 <= VM_MAXUSER_ADDRESS && frame->tf_err & PGEX_I) - panic("attempt to execute user address %p " + return fault("attempt to execute user address %p " "in supervisor mode", (void *)cr2); /* This will only trigger if SMAP is enabled */ if (pcb->pcb_onfault == NULL && cr2 <= VM_MAXUSER_ADDRESS && frame->tf_err & PGEX_P) - panic("attempt to access user address %p " + return fault("attempt to access user address %p " "in supervisor mode", (void *)cr2); /* @@ -211,18 +230,9 @@ pageflttrap(struct trapframe *frame, int frame->tf_rip = (u_int64_t)pcb->pcb_onfault; return 1; } else { - /* - * Bad memory access in the kernel; save the fault - * info for DDB and retain the kernel lock to keep - * faultbuf from being overwritten by another CPU. - */ - static char faultbuf[512]; - snprintf(faultbuf, sizeof faultbuf, - "uvm_fault(%p, 0x%llx, 0, %d) -> %x", + /* bad memory access in the kernel */ + return fault("uvm_fault(%p, 0x%llx, 0, %d) -> %x", map, cr2, ftype, error); - printf("%s\n", faultbuf); - faultstr = faultbuf; - return 0; } } else { union sigval sv; Philip