From: sf Date: Fri, 13 Jul 2018 08:30:34 +0000 (+0000) Subject: Disable codepatching infrastructure after boot X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=5f6ecb1939a610ea2cc43585708e659fc0834e52;p=openbsd Disable codepatching infrastructure after boot 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@ --- diff --git a/sys/arch/amd64/amd64/codepatch.c b/sys/arch/amd64/amd64/codepatch.c index a6a0194f51a..57cc9784f6f 100644 --- a/sys/arch/amd64/amd64/codepatch.c +++ b/sys/arch/amd64/amd64/codepatch.c @@ -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 * @@ -17,6 +17,8 @@ #include #include +#include +#include /* 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); +} diff --git a/sys/arch/amd64/amd64/mainbus.c b/sys/arch/amd64/amd64/mainbus.c index f3083712e1f..2f0a74f51d2 100644 --- a/sys/arch/amd64/amd64/mainbus.c +++ b/sys/arch/amd64/amd64/mainbus.c @@ -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 #include +#include #include #include @@ -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 diff --git a/sys/arch/amd64/conf/ld.script b/sys/arch/amd64/conf/ld.script index 7c0ee2b8c43..0f0026ecef1 100644 --- a/sys/arch/amd64/conf/ld.script +++ b/sys/arch/amd64/conf/ld.script @@ -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 @@ -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 = .; diff --git a/sys/arch/amd64/include/codepatch.h b/sys/arch/amd64/include/codepatch.h index 1fc008bffe1..a5bfc304e1f 100644 --- a/sys/arch/amd64/include/codepatch.h +++ b/sys/arch/amd64/include/codepatch.h @@ -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 * @@ -22,12 +22,16 @@ #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 */