summaryrefslogtreecommitdiffstats
path: root/winsup
diff options
context:
space:
mode:
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog6
-rw-r--r--winsup/cygwin/mmap.cc20
2 files changed, 24 insertions, 2 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 80e8af120..c21732939 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,11 @@
2004-07-15 Corinna Vinschen <corinna@vinschen.de>
+ * mmap.cc (mprotect): When MAP_WRITE protection is requested, use
+ READWRITE or WRITECOPY protection, whatever has been used when the
+ page has been allocated initially.
+
+2004-07-15 Corinna Vinschen <corinna@vinschen.de>
+
* fhandler.h (class fhandler_dev_raw): Remove is_writing flag.
Remove declaration of writebuf.
(class fhandler_dev_floppy): Remove declaration of close.
diff --git a/winsup/cygwin/mmap.cc b/winsup/cygwin/mmap.cc
index e2a25de52..16611480c 100644
--- a/winsup/cygwin/mmap.cc
+++ b/winsup/cygwin/mmap.cc
@@ -786,15 +786,31 @@ mprotect (void *addr, size_t len, int prot)
return 0;
}
+ /* If write protection is requested, check if the page was
+ originally protected writecopy. In this case call VirtualProtect
+ requesting PAGE_WRITECOPY, otherwise the VirtualProtect will fail
+ on NT version >= 5.0 */
+ bool writecopy = false;
+ if (prot & PROT_WRITE)
+ {
+ MEMORY_BASIC_INFORMATION mbi;
+ if (VirtualQuery (addr, &mbi, sizeof mbi))
+ {
+ if (mbi.AllocationProtect == PAGE_WRITECOPY
+ || mbi.AllocationProtect == PAGE_EXECUTE_WRITECOPY)
+ writecopy = true;
+ }
+ }
+
switch (prot)
{
case PROT_READ | PROT_WRITE | PROT_EXEC:
case PROT_WRITE | PROT_EXEC:
- new_prot = PAGE_EXECUTE_READWRITE;
+ new_prot = writecopy ? PAGE_EXECUTE_WRITECOPY : PAGE_EXECUTE_READWRITE;
break;
case PROT_READ | PROT_WRITE:
case PROT_WRITE:
- new_prot = PAGE_READWRITE;
+ new_prot = writecopy ? PAGE_WRITECOPY : PAGE_READWRITE;
break;
case PROT_READ | PROT_EXEC:
new_prot = PAGE_EXECUTE_READ;