< prev index next >

src/hotspot/os/aix/os_aix.cpp

Print this page
rev 51957 : 8224221: add memprotect calls to event log
Reviewed-by: dholmes, mdoerr


2435   }
2436 
2437   // update bookkeeping
2438   if (rc && remove_bookkeeping) {
2439     vmembk_remove(vmi);
2440   }
2441 
2442   return rc;
2443 }
2444 
2445 static bool checked_mprotect(char* addr, size_t size, int prot) {
2446 
2447   // Little problem here: if SPEC1170 behaviour is off, mprotect() on AIX will
2448   // not tell me if protection failed when trying to protect an un-protectable range.
2449   //
2450   // This means if the memory was allocated using shmget/shmat, protection wont work
2451   // but mprotect will still return 0:
2452   //
2453   // See http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.basetechref/doc/basetrf1/mprotect.htm
2454 

2455   bool rc = ::mprotect(addr, size, prot) == 0 ? true : false;
2456 
2457   if (!rc) {
2458     const char* const s_errno = os::errno_name(errno);
2459     warning("mprotect(" PTR_FORMAT "-" PTR_FORMAT ", 0x%X) failed (%s).", addr, addr + size, prot, s_errno);
2460     return false;
2461   }
2462 
2463   // mprotect success check
2464   //
2465   // Mprotect said it changed the protection but can I believe it?
2466   //
2467   // To be sure I need to check the protection afterwards. Try to
2468   // read from protected memory and check whether that causes a segfault.
2469   //
2470   if (!os::Aix::xpg_sus_mode()) {
2471 
2472     if (CanUseSafeFetch32()) {
2473 
2474       const bool read_protected =
2475         (SafeFetch32((int*)addr, 0x12345678) == 0x12345678 &&
2476          SafeFetch32((int*)addr, 0x76543210) == 0x76543210) ? true : false;
2477 
2478       if (prot & PROT_READ) {
2479         rc = !read_protected;
2480       } else {
2481         rc = read_protected;
2482       }
2483 
2484       if (!rc) {
2485         if (os::Aix::on_pase()) {
2486           // There is an issue on older PASE systems where mprotect() will return success but the
2487           // memory will not be protected.
2488           // This has nothing to do with the problem of using mproect() on SPEC1170 incompatible
2489           // machines; we only see it rarely, when using mprotect() to protect the guard page of
2490           // a stack. It is an OS error.
2491           //
2492           // A valid strategy is just to try again. This usually works. :-/
2493 
2494           ::usleep(1000);

2495           if (::mprotect(addr, size, prot) == 0) {
2496             const bool read_protected_2 =
2497               (SafeFetch32((int*)addr, 0x12345678) == 0x12345678 &&
2498               SafeFetch32((int*)addr, 0x76543210) == 0x76543210) ? true : false;
2499             rc = true;
2500           }
2501         }
2502       }
2503     }
2504   }
2505 
2506   assert(rc == true, "mprotect failed.");
2507 
2508   return rc;
2509 }
2510 
2511 // Set protections specified
2512 bool os::protect_memory(char* addr, size_t size, ProtType prot, bool is_committed) {
2513   unsigned int p = 0;
2514   switch (prot) {




2435   }
2436 
2437   // update bookkeeping
2438   if (rc && remove_bookkeeping) {
2439     vmembk_remove(vmi);
2440   }
2441 
2442   return rc;
2443 }
2444 
2445 static bool checked_mprotect(char* addr, size_t size, int prot) {
2446 
2447   // Little problem here: if SPEC1170 behaviour is off, mprotect() on AIX will
2448   // not tell me if protection failed when trying to protect an un-protectable range.
2449   //
2450   // This means if the memory was allocated using shmget/shmat, protection wont work
2451   // but mprotect will still return 0:
2452   //
2453   // See http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.basetechref/doc/basetrf1/mprotect.htm
2454 
2455   Events::log(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(addr), p2i(addr+size), prot);
2456   bool rc = ::mprotect(addr, size, prot) == 0 ? true : false;
2457 
2458   if (!rc) {
2459     const char* const s_errno = os::errno_name(errno);
2460     warning("mprotect(" PTR_FORMAT "-" PTR_FORMAT ", 0x%X) failed (%s).", addr, addr + size, prot, s_errno);
2461     return false;
2462   }
2463 
2464   // mprotect success check
2465   //
2466   // Mprotect said it changed the protection but can I believe it?
2467   //
2468   // To be sure I need to check the protection afterwards. Try to
2469   // read from protected memory and check whether that causes a segfault.
2470   //
2471   if (!os::Aix::xpg_sus_mode()) {
2472 
2473     if (CanUseSafeFetch32()) {
2474 
2475       const bool read_protected =
2476         (SafeFetch32((int*)addr, 0x12345678) == 0x12345678 &&
2477          SafeFetch32((int*)addr, 0x76543210) == 0x76543210) ? true : false;
2478 
2479       if (prot & PROT_READ) {
2480         rc = !read_protected;
2481       } else {
2482         rc = read_protected;
2483       }
2484 
2485       if (!rc) {
2486         if (os::Aix::on_pase()) {
2487           // There is an issue on older PASE systems where mprotect() will return success but the
2488           // memory will not be protected.
2489           // This has nothing to do with the problem of using mproect() on SPEC1170 incompatible
2490           // machines; we only see it rarely, when using mprotect() to protect the guard page of
2491           // a stack. It is an OS error.
2492           //
2493           // A valid strategy is just to try again. This usually works. :-/
2494 
2495           ::usleep(1000);
2496           Events::log(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(addr), p2i(addr+size), prot);
2497           if (::mprotect(addr, size, prot) == 0) {
2498             const bool read_protected_2 =
2499               (SafeFetch32((int*)addr, 0x12345678) == 0x12345678 &&
2500               SafeFetch32((int*)addr, 0x76543210) == 0x76543210) ? true : false;
2501             rc = true;
2502           }
2503         }
2504       }
2505     }
2506   }
2507 
2508   assert(rc == true, "mprotect failed.");
2509 
2510   return rc;
2511 }
2512 
2513 // Set protections specified
2514 bool os::protect_memory(char* addr, size_t size, ProtType prot, bool is_committed) {
2515   unsigned int p = 0;
2516   switch (prot) {


< prev index next >