aboutsummaryrefslogtreecommitdiff
path: root/winsup/cygwin/mmap.cc
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2003-01-14 20:40:09 +0000
committerCorinna Vinschen <corinna@vinschen.de>2003-01-14 20:40:09 +0000
commit857b65ddba5afd0ef5c385a520056515b653a3e9 (patch)
tree1075fb4109251bdc9cca899838d84acda6b62a50 /winsup/cygwin/mmap.cc
parent9a47ce7f74ab6390a48111e00f3317da3cc7218a (diff)
downloadnewlib-857b65ddba5afd0ef5c385a520056515b653a3e9.zip
newlib-857b65ddba5afd0ef5c385a520056515b653a3e9.tar.gz
newlib-857b65ddba5afd0ef5c385a520056515b653a3e9.tar.bz2
* mmap.cc (mmap_record::access): Change argument type to caddr_t
for strictness. (mprotect): Protect against calling VirtualProtect() for shared pages on 9x/Me. (fixup_mmaps_after_fork): If ReadProcessMemory() fails, try to change protection of parent page to PAGE_READONLY, then try again. Revert protection afterwards.
Diffstat (limited to 'winsup/cygwin/mmap.cc')
-rw-r--r--winsup/cygwin/mmap.cc57
1 files changed, 51 insertions, 6 deletions
diff --git a/winsup/cygwin/mmap.cc b/winsup/cygwin/mmap.cc
index 19c8e08..4b7329c 100644
--- a/winsup/cygwin/mmap.cc
+++ b/winsup/cygwin/mmap.cc
@@ -96,7 +96,7 @@ class mmap_record
__off64_t map_map (__off64_t off, DWORD len);
BOOL unmap_map (caddr_t addr, DWORD len);
void fixup_map (void);
- int access (char *address);
+ int access (caddr_t address);
fhandler_base *alloc_fh ();
void free_fh (fhandler_base *fh);
@@ -226,7 +226,7 @@ mmap_record::fixup_map ()
}
int
-mmap_record::access (char *address)
+mmap_record::access (caddr_t address)
{
if (address < base_address_ || address >= base_address_ + size_to_map_)
return 0;
@@ -889,6 +889,13 @@ mprotect (caddr_t addr, size_t len, int prot)
syscall_printf ("mprotect (addr %x, len %d, prot %x)", addr, len, prot);
+ if (!wincap.virtual_protect_works_on_shared_pages ()
+ && addr >= (caddr_t)0x80000000 && addr <= (caddr_t)0xBFFFFFFF)
+ {
+ syscall_printf ("0 = mprotect (9x: No VirtualProtect on shared memory)");
+ return 0;
+ }
+
if (prot == PROT_NONE)
new_prot = PAGE_NOACCESS;
else
@@ -948,7 +955,7 @@ fixup_mmaps_after_fork (HANDLE parent)
for (int it = 0; it < mmapped_areas->nlists; ++it)
{
list *l = mmapped_areas->lists[it];
- if (l != 0)
+ if (l)
{
int li;
for (li = 0; li < l->nrecs; ++li)
@@ -978,9 +985,47 @@ fixup_mmaps_after_fork (HANDLE parent)
&& !ReadProcessMemory (parent, address, address,
getpagesize (), NULL))
{
- system_printf ("ReadProcessMemory failed for MAP_PRIVATE address %p, %E",
- rec->get_address ());
- return -1;
+ DWORD old_prot;
+
+ if (GetLastError () != ERROR_PARTIAL_COPY ||
+ !wincap.virtual_protect_works_on_shared_pages ())
+ {
+ system_printf ("ReadProcessMemory failed for "
+ "MAP_PRIVATE address %p, %E",
+ rec->get_address ());
+ return -1;
+ }
+ if (!VirtualProtectEx (parent,
+ address, getpagesize (),
+ PAGE_READONLY, &old_prot))
+ {
+ system_printf ("VirtualProtectEx failed for "
+ "MAP_PRIVATE address %p, %E",
+ rec->get_address ());
+ return -1;
+ }
+ else
+ {
+ BOOL ret, ret2;
+ ret = ReadProcessMemory (parent, address, address,
+ getpagesize (), NULL);
+ ret2 = VirtualProtectEx(parent,
+ address, getpagesize (),
+ old_prot, &old_prot);
+ if (!ret2)
+ system_printf ("WARNING: VirtualProtectEx to"
+ "return to previous state "
+ "in parent failed for "
+ "MAP_PRIVATE address %p, %E",
+ rec->get_address ());
+ if (!ret)
+ {
+ system_printf ("ReadProcessMemory FAILED for "
+ "MAP_PRIVATE address %p, %E",
+ rec->get_address ());
+ return -1;
+ }
+ }
}
}
rec->fixup_map ();