From 2daa523994d9464fa02a5384e7a44ef5b457cf06 Mon Sep 17 00:00:00 2001 From: sf Date: Sat, 1 Jul 2017 19:38:41 +0000 Subject: [PATCH] Use absolute pointers in codepatch entries Instead of offsets to KERNBASE, store absolute pointers in the codepatch entries. This makes the resulting kernel a few KB larger on amd64, but KERNBASE will go away when ASLR is introduced. Requested by deraadt@ --- sys/arch/amd64/amd64/codepatch.c | 27 +++++++++++++-------------- sys/arch/amd64/include/codepatch.h | 5 +++-- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/sys/arch/amd64/amd64/codepatch.c b/sys/arch/amd64/amd64/codepatch.c index 41bd08fc906..323704415a7 100644 --- a/sys/arch/amd64/amd64/codepatch.c +++ b/sys/arch/amd64/amd64/codepatch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: codepatch.c,v 1.3 2017/03/26 23:27:44 jca Exp $ */ +/* $OpenBSD: codepatch.c,v 1.4 2017/07/01 19:38:41 sf Exp $ */ /* * Copyright (c) 2014-2015 Stefan Fritsch * @@ -26,10 +26,12 @@ #endif struct codepatch { - uint32_t offset; + vaddr_t addr; uint16_t len; uint16_t tag; + uint32_t _padding; }; +CTASSERT(sizeof(struct codepatch) % 8 == 0); extern struct codepatch codepatch_begin; extern struct codepatch codepatch_end; @@ -104,7 +106,7 @@ codepatch_nop(uint16_t tag) { struct codepatch *patch; unsigned char *rwaddr; - vaddr_t addr, rwmap = 0; + vaddr_t rwmap = 0; int i = 0; DBGPRINT("patching tag %u", tag); @@ -112,8 +114,7 @@ codepatch_nop(uint16_t tag) for (patch = &codepatch_begin; patch < &codepatch_end; patch++) { if (patch->tag != tag) continue; - addr = KERNBASE + patch->offset; - rwaddr = codepatch_maprw(&rwmap, addr); + rwaddr = codepatch_maprw(&rwmap, patch->addr); codepatch_fill_nop(rwaddr, patch->len); i++; } @@ -127,7 +128,7 @@ codepatch_replace(uint16_t tag, void *code, size_t len) { struct codepatch *patch; unsigned char *rwaddr; - vaddr_t addr, rwmap = 0; + vaddr_t rwmap = 0; int i = 0; DBGPRINT("patching tag %u with %p", tag, code); @@ -135,13 +136,12 @@ codepatch_replace(uint16_t tag, void *code, size_t len) for (patch = &codepatch_begin; patch < &codepatch_end; patch++) { if (patch->tag != tag) continue; - addr = KERNBASE + patch->offset; if (len > patch->len) { panic("%s: can't replace len %u with %zu at %#lx", - __func__, patch->len, len, addr); + __func__, patch->len, len, patch->addr); } - rwaddr = codepatch_maprw(&rwmap, addr); + rwaddr = codepatch_maprw(&rwmap, patch->addr); memcpy(rwaddr, code, len); codepatch_fill_nop(rwaddr + len, patch->len - len); i++; @@ -158,20 +158,19 @@ codepatch_call(uint16_t tag, void *func) unsigned char *rwaddr; int32_t offset; int i = 0; - vaddr_t addr, rwmap = 0; + vaddr_t rwmap = 0; DBGPRINT("patching tag %u with call %p", tag, func); for (patch = &codepatch_begin; patch < &codepatch_end; patch++) { if (patch->tag != tag) continue; - addr = KERNBASE + patch->offset; if (patch->len < 5) panic("%s: can't replace len %u with call at %#lx", - __func__, patch->len, addr); + __func__, patch->len, patch->addr); - offset = (vaddr_t)func - (addr + 5); - rwaddr = codepatch_maprw(&rwmap, addr); + offset = (vaddr_t)func - (patch->addr + 5); + rwaddr = codepatch_maprw(&rwmap, patch->addr); rwaddr[0] = 0xe8; /* call near */ memcpy(rwaddr + 1, &offset, sizeof(offset)); codepatch_fill_nop(rwaddr + 5, patch->len - 5); diff --git a/sys/arch/amd64/include/codepatch.h b/sys/arch/amd64/include/codepatch.h index 9a29b3aaf77..92cd2db51a2 100644 --- a/sys/arch/amd64/include/codepatch.h +++ b/sys/arch/amd64/include/codepatch.h @@ -1,4 +1,4 @@ -/* $OpenBSD: codepatch.h,v 1.2 2015/04/19 19:45:21 sf Exp $ */ +/* $OpenBSD: codepatch.h,v 1.3 2017/07/01 19:38:41 sf Exp $ */ /* * Copyright (c) 2014-2015 Stefan Fritsch * @@ -41,9 +41,10 @@ void codepatch_call(uint16_t tag, void *func); #define CODEPATCH_END(tag) \ 999: \ .section .codepatch, "a" ;\ - .int (998b - KERNBASE) ;\ + .quad 998b ;\ .short (999b - 998b) ;\ .short tag ;\ + .int 0 ;\ .previous #define CPTAG_STAC 1 -- 2.20.1