[PATCH] ntdll: Try mmap again without exec if it fails with it.

Chip Davis cdavis at codeweavers.com
Mon Sep 23 19:44:49 CDT 2019


On some systems, mmap(2) with PROT_WRITE | PROT_EXEC can legitimately
fail. If we added PROT_EXEC implicitly, try again without it.

Signed-off-by: Chip Davis <cdavis at codeweavers.com>
---
 dlls/ntdll/virtual.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index 8b94f2eb67b0..cd9e8a93ee16 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -1203,6 +1203,7 @@ static NTSTATUS map_file_into_view( struct file_view *view, int fd, size_t start
     /* only try mmap if media is not removable (or if we require write access) */
     if (!removable || (flags & MAP_SHARED))
     {
+try_again:
         if (mmap( (char *)view->base + start, size, prot, flags, fd, offset ) != (void *)-1)
             goto done;
 
@@ -1223,7 +1224,16 @@ static NTSTATUS map_file_into_view( struct file_view *view, int fd, size_t start
         case EPERM:  /* noexec filesystem, fall back to read() */
             if (flags & MAP_SHARED)
             {
-                if (prot & PROT_EXEC) ERR( "failed to set PROT_EXEC on file map, noexec filesystem?\n" );
+                if (prot & PROT_EXEC)
+                {
+                    if (force_exec_prot && (vprot & (VPROT_WRITE|VPROT_EXEC)) == VPROT_WRITE)
+                    {
+                        /* exec + write may legitimately fail, in that case fall back to write only */
+                        prot &= ~PROT_EXEC;
+                        goto try_again;
+                    }
+                    ERR( "failed to set PROT_EXEC on file map, noexec filesystem?\n" );
+                }
                 return STATUS_ACCESS_DENIED;
             }
             if (prot & PROT_EXEC) WARN( "failed to set PROT_EXEC on file map, noexec filesystem?\n" );
-- 
2.21.0




More information about the wine-devel mailing list