From 34cdda1dd5ebd4611eb2d1ae2dd0f50bf48bb227 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Mon, 22 Jan 2018 19:51:13 +0100 Subject: [PATCH] kernel: x86: enable writes before patching. Follow up for commit a2021292d4778d374b601333976c75fad0522a73. Binary patching would otherwise fail after the kernel text area becomes read-only. --- .../kernel/arch/x86/arch_altcodepatch.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/system/kernel/arch/x86/arch_altcodepatch.cpp b/src/system/kernel/arch/x86/arch_altcodepatch.cpp index 491ce00351..c38ad739de 100644 --- a/src/system/kernel/arch/x86/arch_altcodepatch.cpp +++ b/src/system/kernel/arch/x86/arch_altcodepatch.cpp @@ -11,7 +11,9 @@ #include +#include #include +#include @@ -29,18 +31,27 @@ extern altcodepatch altcodepatch_end; void arch_altcodepatch_replace(uint16 tag, void* newcodepatch, size_t length) { - uint32 count = 0; + uint32 count = 0; + + // we need to write to the text area + struct elf_image_info* info = elf_get_kernel_image(); + uint32 kernelProtection = B_KERNEL_READ_AREA | B_KERNEL_EXECUTE_AREA; + set_area_protection(info->text_region.id, kernelProtection | B_KERNEL_WRITE_AREA); for (altcodepatch *patch = &altcodepatch_begin; patch < &altcodepatch_end; patch++) { if (patch->tag != tag) continue; - addr_t address = KERNEL_LOAD_BASE + patch->kernel_offset; + void* address = (void*)(KERNEL_LOAD_BASE + patch->kernel_offset); if (patch->length < length) panic("can't copy patch: new code is too long\n"); - memcpy((void*)address, newcodepatch, length); + memcpy(address, newcodepatch, length); count++; } + + // disable write after patch + set_area_protection(info->text_region.id, kernelProtection); + dprintf("arch_altcodepatch_replace found %d altcodepatches\n", count); }