diff options
author | Philip Guenther <guenther@cvs.openbsd.org> | 2022-11-07 01:41:58 +0000 |
---|---|---|
committer | Philip Guenther <guenther@cvs.openbsd.org> | 2022-11-07 01:41:58 +0000 |
commit | 079941ccc68343241f45e4a554061c5b2b6c689f (patch) | |
tree | 85e6631aa7754d69fc2ac16c212913ca961c089b /sys/arch/amd64 | |
parent | 2f479c799896ce4d1e1e0332be560926bb839429 (diff) |
In kpageflttrap(), validate a non-NULL pcb_onfault against an array
of permitted addresses, done via .nofault* sections that end up in
the linked kernel's rodata.
ok deraadt@ kettenis@
Diffstat (limited to 'sys/arch/amd64')
-rw-r--r-- | sys/arch/amd64/amd64/copy.S | 9 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/efi_machdep.c | 3 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/trap.c | 15 | ||||
-rw-r--r-- | sys/arch/amd64/conf/ld.script | 6 |
4 files changed, 29 insertions, 4 deletions
diff --git a/sys/arch/amd64/amd64/copy.S b/sys/arch/amd64/amd64/copy.S index 73dcefa058f..87bdd002952 100644 --- a/sys/arch/amd64/amd64/copy.S +++ b/sys/arch/amd64/amd64/copy.S @@ -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 $ */ /* @@ -44,6 +44,11 @@ #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 diff --git a/sys/arch/amd64/amd64/efi_machdep.c b/sys/arch/amd64/amd64/efi_machdep.c index 90716cb32e8..40ed5004b6c 100644 --- a/sys/arch/amd64/amd64/efi_machdep.c +++ b/sys/arch/amd64/amd64/efi_machdep.c @@ -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) diff --git a/sys/arch/amd64/amd64/trap.c b/sys/arch/amd64/amd64/trap.c index ffda7e2609b..61f150321da 100644 --- a/sys/arch/amd64/amd64/trap.c +++ b/sys/arch/amd64/amd64/trap.c @@ -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 && diff --git a/sys/arch/amd64/conf/ld.script b/sys/arch/amd64/conf/ld.script index 18298f8b8c3..c02f60c66cb 100644 --- a/sys/arch/amd64/conf/ld.script +++ b/sys/arch/amd64/conf/ld.script @@ -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 |