Module: wine Branch: master Commit: 2e364d25cc51656cfc9c512905cc12fee41bcd29 URL: http://source.winehq.org/git/wine.git/?a=commit;h=2e364d25cc51656cfc9c512905...
Author: Alexandre Julliard julliard@winehq.org Date: Fri Nov 17 11:54:51 2017 +0100
ntdll: Fall back to read() on noexec filesystems also for non-image mappings.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/ntdll/virtual.c | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-)
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c index 1c62e57..9cec872 100644 --- a/dlls/ntdll/virtual.c +++ b/dlls/ntdll/virtual.c @@ -1164,18 +1164,29 @@ static NTSTATUS map_file_into_view( struct file_view *view, int fd, size_t start if (mmap( (char *)view->base + start, size, prot, flags, fd, offset ) != (void *)-1) goto done;
- if ((errno == EPERM) && (prot & PROT_EXEC)) - ERR( "failed to set %08x protection on file map, noexec filesystem?\n", prot ); - - /* 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(); - if (flags & MAP_SHARED) /* we cannot fake shared mappings */ - { - if (errno == EINVAL) return STATUS_INVALID_PARAMETER; - ERR( "shared writable mmap not supported, broken filesystem?\n" ); - return STATUS_NOT_SUPPORTED; + switch (errno) + { + case EINVAL: /* file offset is not page-aligned, fall back to read() */ + if (flags & MAP_SHARED) return STATUS_INVALID_PARAMETER; + break; + case ENOEXEC: + case ENODEV: /* filesystem doesn't support mmap(), fall back to read() */ + if (flags & MAP_SHARED) + { + ERR( "shared writable mmap not supported, broken filesystem?\n" ); + return STATUS_NOT_SUPPORTED; + } + break; + 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" ); + return STATUS_ACCESS_DENIED; + } + if (prot & PROT_EXEC) WARN( "failed to set PROT_EXEC on file map, noexec filesystem?\n" ); + break; + default: + return FILE_GetNtStatus(); } }