In kpageflttrap(), validate a non-NULL pcb_onfault against an array
authorguenther <guenther@openbsd.org>
Mon, 7 Nov 2022 01:41:57 +0000 (01:41 +0000)
committerguenther <guenther@openbsd.org>
Mon, 7 Nov 2022 01:41:57 +0000 (01:41 +0000)
of permitted addresses, done via .nofault* sections that end up in
the linked kernel's rodata.

ok deraadt@ kettenis@

sys/arch/amd64/amd64/copy.S
sys/arch/amd64/amd64/efi_machdep.c
sys/arch/amd64/amd64/trap.c
sys/arch/amd64/conf/ld.script

index 73dcefa..87bdd00 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: copy.S,v 1.14 2021/09/04 22:15:33 bluhm Exp $ */
+/*     $OpenBSD: copy.S,v 1.15 2022/11/07 01:41:57 guenther Exp $      */
 /*     $NetBSD: copy.S,v 1.1 2003/04/26 18:39:26 fvdl Exp $    */
 
 /*
 #include <machine/asm.h>
 #include <machine/codepatch.h>
 
+#define        DECLARE_ONFAULT(x)              \
+       .pushsection .nofault.0, "a"    ;\
+       .quad   x                       ;\
+       .popsection
+
 /*
  * Copy routines from and to userland, plus a few more. See the
  * section 9 manpages for info. Some cases can be optimized more.
@@ -183,6 +188,7 @@ ENTRY(copyin)
        lfence
 
 NENTRY(copy_fault)
+DECLARE_ONFAULT(copy_fault)
        SMAP_CLAC
        movq    CPUVAR(CURPCB),%rdx
        popq    PCB_ONFAULT(%rdx)
@@ -277,6 +283,7 @@ ENTRY(copyinstr)
        jmp     copystr_return
 
 ENTRY(copystr_fault)
+DECLARE_ONFAULT(copystr_fault)
        movl    $EFAULT,%eax
 copystr_return:
        SMAP_CLAC
index 90716cb..40ed500 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: efi_machdep.c,v 1.3 2022/11/04 16:49:31 kettenis Exp $        */
+/*     $OpenBSD: efi_machdep.c,v 1.4 2022/11/07 01:41:57 guenther Exp $        */
 
 /*
  * Copyright (c) 2022 Mark Kettenis <kettenis@openbsd.org>
@@ -236,6 +236,7 @@ efi_fault(void)
 {
        longjmp(&efi_jmpbuf);
 }
+__asm(".pushsection .nofault, \"a\"; .quad efi_fault; .popsection");
 
 void
 efi_enter(struct efi_softc *sc)
index ffda7e2..61f1503 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: trap.c,v 1.92 2022/11/04 16:49:31 kettenis Exp $      */
+/*     $OpenBSD: trap.c,v 1.93 2022/11/07 01:41:57 guenther Exp $      */
 /*     $NetBSD: trap.c,v 1.2 2003/05/04 23:51:56 fvdl Exp $    */
 
 /*-
@@ -226,6 +226,19 @@ kpageflttrap(struct trapframe *frame, uint64_t cr2)
                return 0;
 
        pcb = &p->p_addr->u_pcb;
+       if (pcb->pcb_onfault != NULL) {
+               extern caddr_t __nofault_start[], __nofault_end[];
+               caddr_t *nf = __nofault_start;
+               while (*nf++ != pcb->pcb_onfault) {
+                       if (nf >= __nofault_end) {
+                               KERNEL_LOCK();
+                               fault("invalid pcb_nofault=%lx",
+                                   (long)pcb->pcb_onfault);
+                               return 0;
+                               /* retain kernel lock */
+                       }
+               }
+       }
 
        /* This will only trigger if SMEP is enabled */
        if (pcb->pcb_onfault == NULL && cr2 <= VM_MAXUSER_ADDRESS &&
index 18298f8..c02f60c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ld.script,v 1.18 2022/09/02 09:02:37 mlarkin Exp $    */
+/*     $OpenBSD: ld.script,v 1.19 2022/11/07 01:41:57 guenther Exp $   */
 
 /*
  * Copyright (c) 2009 Tobias Weingartner <weingart@tepid.org>
@@ -85,6 +85,10 @@ SECTIONS
        {
                __rodata_start = ABSOLUTE(.);
                *(.rodata .rodata.*)
+               . = ALIGN(8);
+               __nofault_start = ABSOLUTE(.);
+               *(.nofault.*) *(.nofault)
+               __nofault_end = ABSOLUTE(.);
                *(.codepatch)
                *(.codepatchend)
        } :rodata =0xcccccccc