From 8a1709b3af2253bea2cfdca1c1fa486c6207663f Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Tue, 11 Dec 2018 13:37:39 -0500 Subject: [PATCH] vm: Allow W|X before kernel startup ends. The altcodepatch mechanism needs to overwrite parts of the kernel image. This can't be done by setting it to RW-only and not RWX, as we are already running within the kernel when this occurs, and so instruction fetches can and will occur between the points of +W and -W. As gKernelStartup is turned off before the scheduler is started, this is not much of a lifted restriction, as no modules are loaded, no secondary threads started, etc. Fixes #14751. --- src/system/kernel/vm/vm.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp index dc2de231f5..205ab5dca1 100644 --- a/src/system/kernel/vm/vm.cpp +++ b/src/system/kernel/vm/vm.cpp @@ -4914,7 +4914,7 @@ vm_set_area_memory_type(area_id id, phys_addr_t physicalBase, uint32 type) /*! This function enforces some protection properties: - - kernel areas must be W^X + - kernel areas must be W^X (after kernel startup) - if B_WRITE_AREA is set, B_KERNEL_WRITE_AREA is set as well - if only B_READ_AREA has been set, B_KERNEL_READ_AREA is also set - if no protection is specified, it defaults to B_KERNEL_READ_AREA @@ -4923,8 +4923,10 @@ vm_set_area_memory_type(area_id id, phys_addr_t physicalBase, uint32 type) static void fix_protection(uint32* protection) { - if ((*protection & B_KERNEL_WRITE_AREA) != 0 - && (*protection & B_KERNEL_EXECUTE_AREA) != 0) + if ((*protection & B_KERNEL_EXECUTE_AREA) != 0 + && ((*protection & B_KERNEL_WRITE_AREA) != 0 + || (*protection & B_WRITE_AREA) != 0) + && !gKernelStartup) panic("kernel areas cannot be both writable and executable!"); if ((*protection & B_KERNEL_PROTECTION) == 0) {