> Date: Fri, 14 Aug 2020 14:40:23 +0200 (CEST)
> From: Mark Kettenis <mark.kette...@xs4all.nl>
> 
> I suppose a way to test this properly is to pick a system call and
> replace a copyin() with a direct access?  That will succeed without
> PAN but should fail with PAN enabled right?

So that does indeed work.  However, the result is a hard hang.  So
here as an additional diff that makes sure we panic instead.  The idea
is that all user-space access from the kernel should be done by the
special unprivileged load/store instructions.

Index: arch/arm64/arm64/trap.c
===================================================================
RCS file: /cvs/src/sys/arch/arm64/arm64/trap.c,v
retrieving revision 1.27
diff -u -p -r1.27 trap.c
--- arch/arm64/arm64/trap.c     6 Jan 2020 12:37:30 -0000       1.27
+++ arch/arm64/arm64/trap.c     14 Aug 2020 21:05:54 -0000
@@ -65,6 +65,14 @@ void do_el0_error(struct trapframe *);
 
 void dumpregs(struct trapframe*);
 
+/* Check whether we're executing an unprivileged load/store instruction. */
+static inline int
+is_unpriv_ldst(uint64_t elr)
+{
+       uint32_t insn = *(uint32_t *)elr;
+       return ((insn & 0x3f200c00) == 0x38000800);
+}
+
 static void
 data_abort(struct trapframe *frame, uint64_t esr, uint64_t far,
     int lower, int exe)
@@ -104,8 +112,18 @@ data_abort(struct trapframe *frame, uint
                /* The top bit tells us which range to use */
                if ((far >> 63) == 1)
                        map = kernel_map;
-               else
+               else {
+                       /*
+                        * Only allow user-space access using
+                        * unprivileged load/store instructions.
+                        */
+                       if (!is_unpriv_ldst(frame->tf_elr)) {
+                               panic("attempt to access user address"
+                                     " 0x%llx from EL1", far);
+                       }
+
                        map = &p->p_vmspace->vm_map;
+               }
        }
 
        if (exe)

Reply via email to