From 5df70aa7adfabea2cd13590cc1bf9b9d7375a2a8 Mon Sep 17 00:00:00 2001 From: corinna Date: Thu, 15 Jul 2004 17:00:43 +0000 Subject: [PATCH] * 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. --- winsup/cygwin/ChangeLog | 6 ++++++ winsup/cygwin/mmap.cc | 20 ++++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 80e8af1206..c217329395 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,5 +1,11 @@ 2004-07-15 Corinna Vinschen + * 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 + * 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 e2a25de52e..16611480ca 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; -- 2.11.0