Disable codepatching infrastructure after boot
authorsf <sf@openbsd.org>
Fri, 13 Jul 2018 08:30:34 +0000 (08:30 +0000)
committersf <sf@openbsd.org>
Fri, 13 Jul 2018 08:30:34 +0000 (08:30 +0000)
This way, it is not available for use in ROP attacks.  This diff puts the
codepatching code into a separate section and unmaps that section after boot.
In the future, the memory could potentially be reused but that would require
larger changes.

ok pguenther@

sys/arch/amd64/amd64/codepatch.c
sys/arch/amd64/amd64/mainbus.c
sys/arch/amd64/conf/ld.script
sys/arch/amd64/include/codepatch.h

index a6a0194..57cc978 100644 (file)
@@ -1,4 +1,4 @@
-/*      $OpenBSD: codepatch.c,v 1.6 2017/10/14 04:44:43 jsg Exp $    */
+/*      $OpenBSD: codepatch.c,v 1.7 2018/07/13 08:30:34 sf Exp $    */
 /*
  * Copyright (c) 2014-2015 Stefan Fritsch <sf@sfritsch.de>
  *
@@ -17,6 +17,8 @@
 
 #include <sys/param.h>
 #include <uvm/uvm_extern.h>
+#include <machine/codepatch.h>
+#include <uvm/uvm_extern.h> /* round_page */
 
 #ifdef CODEPATCH_DEBUG
 #define DBGPRINT(fmt, args...) printf("%s: " fmt "\n", __func__, ## args)
@@ -34,6 +36,8 @@ CTASSERT(sizeof(struct codepatch) % 8 == 0);
 
 extern struct codepatch codepatch_begin;
 extern struct codepatch codepatch_end;
+extern char __cptext_start[];
+extern char __cptext_end[];
 
 void
 codepatch_fill_nop(void *caddr, uint16_t len)
@@ -174,3 +178,14 @@ codepatch_call(uint16_t tag, void *func)
        codepatch_unmaprw(rwmap);
        DBGPRINT("patched %d places", i);
 }
+
+void
+codepatch_disable(void)
+{
+       size_t size = round_page(__cptext_end - __cptext_start);
+       /* If this assert fails, something is wrong with the cptext section */
+       KASSERT(size > 0);
+       pmap_kremove((vaddr_t)__cptext_start, size);
+       pmap_update(pmap_kernel());
+       DBGPRINT("%s: Unmapped %#zx bytes\n", __func__, size);
+}
index f308371..2f0a74f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: mainbus.c,v 1.43 2018/04/25 00:46:28 jsg Exp $        */
+/*     $OpenBSD: mainbus.c,v 1.44 2018/07/13 08:30:34 sf Exp $ */
 /*     $NetBSD: mainbus.c,v 1.1 2003/04/26 18:39:29 fvdl Exp $ */
 
 /*
@@ -37,6 +37,7 @@
 
 #include <machine/bus.h>
 #include <machine/specialreg.h>
+#include <machine/codepatch.h>
 
 #include <dev/isa/isavar.h>
 #include <dev/pci/pcivar.h>
@@ -259,6 +260,7 @@ mainbus_attach(struct device *parent, struct device *self, void *aux)
                config_found(self, &mba, mainbus_print);
        }
 #endif
+       codepatch_disable();
 }
 
 #if NEFIFB > 0
index 7c0ee2b..0f0026e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ld.script,v 1.13 2018/07/12 14:11:11 guenther Exp $   */
+/*     $OpenBSD: ld.script,v 1.14 2018/07/13 08:30:34 sf Exp $ */
 
 /*
  * Copyright (c) 2009 Tobias Weingartner <weingart@tepid.org>
@@ -66,6 +66,15 @@ SECTIONS
                __kutext_end = ABSOLUTE(.);
        } :text =0xcccccccc
 
+       . = ALIGN(__ALIGN_SIZE);
+       __kernel_cptext_phys = . + __kernel_virt_to_phys;
+       .cptext : AT (__kernel_cptext_phys)
+       {
+               __cptext_start = ABSOLUTE(.);
+               *(.cptext)
+               __cptext_end = ABSOLUTE(.);
+       } :text =0xcccccccc
+
        PROVIDE (etext = .);
        _etext = .;
 
index 1fc008b..a5bfc30 100644 (file)
@@ -1,4 +1,4 @@
-/*      $OpenBSD: codepatch.h,v 1.6 2018/07/12 14:11:11 guenther Exp $    */
+/*      $OpenBSD: codepatch.h,v 1.7 2018/07/13 08:30:34 sf Exp $    */
 /*
  * Copyright (c) 2014-2015 Stefan Fritsch <sf@sfritsch.de>
  *
 
 #ifndef _LOCORE
 
-void *codepatch_maprw(vaddr_t *nva, vaddr_t dest);
-void codepatch_unmaprw(vaddr_t nva);
-void codepatch_fill_nop(void *caddr, uint16_t len);
-void codepatch_nop(uint16_t tag);
-void codepatch_replace(uint16_t tag, void *code, size_t len);
-void codepatch_call(uint16_t tag, void *func);
+/* code in this section will be unmapped after boot */
+#define __cptext __attribute__((section(".cptext")))
+
+__cptext void *codepatch_maprw(vaddr_t *nva, vaddr_t dest);
+__cptext void codepatch_unmaprw(vaddr_t nva);
+__cptext void codepatch_fill_nop(void *caddr, uint16_t len);
+__cptext void codepatch_nop(uint16_t tag);
+__cptext void codepatch_replace(uint16_t tag, void *code, size_t len);
+__cptext void codepatch_call(uint16_t tag, void *func);
+void codepatch_disable(void);
 
 #endif /* !_LOCORE */