Use absolute pointers in codepatch entries
authorsf <sf@openbsd.org>
Sat, 1 Jul 2017 19:38:41 +0000 (19:38 +0000)
committersf <sf@openbsd.org>
Sat, 1 Jul 2017 19:38:41 +0000 (19:38 +0000)
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
sys/arch/amd64/include/codepatch.h

index 41bd08f..3237044 100644 (file)
@@ -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 <sf@sfritsch.de>
  *
 #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);
index 9a29b3a..92cd2db 100644 (file)
@@ -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 <sf@sfritsch.de>
  *
@@ -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