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

Reply via email to