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.
This commit is contained in:
Augustin Cavalier
2018-12-11 13:37:39 -05:00
parent 08858e10fa
commit 8a1709b3af
+5 -3
View File
@@ -4914,7 +4914,7 @@ vm_set_area_memory_type(area_id id, phys_addr_t physicalBase, uint32 type)
/*! This function enforces some protection properties: /*! 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 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 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 - 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 static void
fix_protection(uint32* protection) fix_protection(uint32* protection)
{ {
if ((*protection & B_KERNEL_WRITE_AREA) != 0 if ((*protection & B_KERNEL_EXECUTE_AREA) != 0
&& (*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!"); panic("kernel areas cannot be both writable and executable!");
if ((*protection & B_KERNEL_PROTECTION) == 0) { if ((*protection & B_KERNEL_PROTECTION) == 0) {