Clear DF flag after kcopy faulted.
authorbluhm <bluhm@openbsd.org>
Thu, 6 Jun 2024 00:36:46 +0000 (00:36 +0000)
committerbluhm <bluhm@openbsd.org>
Thu, 6 Jun 2024 00:36:46 +0000 (00:36 +0000)
A memory corruption in the kernel happend that was caused by memset
in the wrong direction.  After that DF bit was set in ddb rflags.

Only kcopy and memmove use std to set DF bit.  kcopy has the special
property that it can fault.  In this case DF is set in the trap
frame.  kpageflttrap() changes the return address to copy_fault via
pcb_onfault.  When alltraps_kern returns, it restores the rflags
with DF set and jumps into copy_fault.  From there a function return
goes back into regular kernel execution.  Now DF is set, but kernel
memset and memcpy expect that it is cleared.

After copy fault, also reset the DF bit with cld in copy_fault.
The crash happend on OpenBSD 7.4 amd64.  As i386 code looks similar,
also insert cld there.

OK guenther@ miod@

sys/arch/amd64/amd64/copy.S
sys/arch/i386/i386/locore.s

index f09ebf9..23f5f70 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: copy.S,v 1.19 2023/07/28 06:18:35 guenther Exp $      */
+/*     $OpenBSD: copy.S,v 1.20 2024/06/06 00:36:46 bluhm Exp $ */
 /*     $NetBSD: copy.S,v 1.1 2003/04/26 18:39:26 fvdl Exp $    */
 
 /*
@@ -189,6 +189,7 @@ ENTRY(_copyin)
 
 NENTRY(copy_fault)
 DECLARE_ONFAULT(copy_fault)
+       cld
        SMAP_CLAC
        movq    CPUVAR(CURPCB),%rdx
        popq    PCB_ONFAULT(%rdx)
index b25acfa..feb8fa4 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: locore.s,v 1.204 2023/12/12 07:37:20 deraadt Exp $    */
+/*     $OpenBSD: locore.s,v 1.205 2024/06/06 00:36:46 bluhm Exp $      */
 /*     $NetBSD: locore.s,v 1.145 1996/05/03 19:41:19 christos Exp $    */
 
 /*-
@@ -555,6 +555,7 @@ ENTRY(_copyin)
        ret
 
 ENTRY(copy_fault)
+       cld
        SMAP_CLAC
        GET_CURPCB(%edx)
        popl    PCB_ONFAULT(%edx)