[PATCH] ntdll: Handle executable file mappings from noexec filesystems

Marcus Meissner meissner at suse.de
Fri Dec 10 06:23:21 CST 2010


Hi,

regression from my previous patch, which forced EXEC permissions on
some mappings, which in turn gets EPERM when the filesystem is
"noexec" mounted.

Some WARN()s on other error branches of mprotect.

Ciao, Marcus
---
 dlls/ntdll/virtual.c |   13 ++++++++++---
 1 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index d7a04c3..1e8582c 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -651,10 +651,14 @@ static BOOL VIRTUAL_SetProt( struct file_view *view, /* [in] Pointer to view */
         TRACE( "forcing exec permission on %p-%p\n", base, (char *)base + size - 1 );
         if (!mprotect( base, size, unix_prot | PROT_EXEC )) goto done;
         /* exec + write may legitimately fail, in that case fall back to write only */
+        WARN( "forcing exec permission on %p-%p to prot 0x%x failed, errno %d.\n", base, (char *)base + size - 1, unix_prot, errno );
         if (!(unix_prot & PROT_WRITE)) return FALSE;
     }
 
-    if (mprotect( base, size, unix_prot )) return FALSE;  /* FIXME: last error */
+    if (mprotect( base, size, unix_prot )) {
+        WARN( "mprotect on %p-%p to 0x%x failed, errno %d\n", base, (char *)base + size - 1, unix_prot, errno );
+        return FALSE;  /* FIXME: last error */
+    }
 
 done:
     memset( p, vprot, size >> page_shift );
@@ -879,8 +883,11 @@ static NTSTATUS map_file_into_view( struct file_view *view, int fd, size_t start
 
         /* mmap() failed; if this is because the file offset is not    */
         /* page-aligned (EINVAL), or because the underlying filesystem */
-        /* does not support mmap() (ENOEXEC,ENODEV), we do it by hand. */
-        if ((errno != ENOEXEC) && (errno != EINVAL) && (errno != ENODEV)) return FILE_GetNtStatus();
+        /* does not support mmap() (ENOEXEC,ENODEV), or because the filesystem */
+        /* is mounted "noexec" (EPERM) we do it by hand. */
+        if ((errno != EPERM) && (errno != ENOEXEC) && (errno != EINVAL) && (errno != ENODEV))
+            return FILE_GetNtStatus();
+
         if (shared_write)  /* we cannot fake shared write mappings */
         {
             if (errno == EINVAL) return STATUS_INVALID_PARAMETER;
-- 
1.7.1



More information about the wine-patches mailing list