[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

vm_map with PROT_WRITE only



There is a call during the mmap tests of stress-ng to mmap:

   mmap(NULL, page_size, PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);

This results in a vm_map_entry within the task with VM_PROT_WRITE as expected.

The write page fault raised when attempting to write to a page in this region is merged with VM_PROT_READ (user_trap in i386/i386/trap.c) but then when the map entry is found the protection requested does not then match that in the entry when tested in vm_map_lookup. The mapping request fails silently and then unsurprisingly stress-ng receives SIGSEGV.

It seems sensible to merge VM_PROT_READ when a write is required as occurs in the trap handling.

What would the correct fix be for this scenario ? As a workaround I applied the following:

diff --git a/vm/vm_user.c b/vm/vm_user.c
index 7f706d71..aa5fc534 100644
--- a/vm/vm_user.c
+++ b/vm/vm_user.c
@@ -348,10 +348,17 @@ kern_return_t vm_map(
        *address = trunc_page(*address);
        size = round_page(size);

+       if (max_protection & VM_PROT_WRITE)
+         max_protection |= VM_PROT_READ;
+
+       if (cur_protection & VM_PROT_WRITE)
+         cur_protection |= VM_PROT_READ;
+
        if (!IP_VALID(memory_object)) {
                object = VM_OBJECT_NULL;
                offset = 0;
                copy = FALSE;
+
        } else if ((object = vm_object_enter(memory_object, size, FALSE))
                        == VM_OBJECT_NULL)
          {


Reply to: