< prev index next >

src/os_cpu/linux_x86/vm/os_linux_x86.cpp

Print this page
rev 8669 : 8197429: Increased stack guard causes segfaults on x86-32
Reviewed-by: dholmes


 875                       : "r" (fpu_cntrl) : "memory");
 876 #endif // !AMD64
 877 }
 878 
 879 #ifndef PRODUCT
 880 void os::verify_stack_alignment() {
 881 #ifdef AMD64
 882   assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment");
 883 #endif
 884 }
 885 #endif
 886 
 887 
 888 /*
 889  * IA32 only: execute code at a high address in case buggy NX emulation is present. I.e. avoid CS limit
 890  * updates (JDK-8023956).
 891  */
 892 void os::workaround_expand_exec_shield_cs_limit() {
 893 #if defined(IA32)
 894   size_t page_size = os::vm_page_size();





















 895   /*
 896    * Take the highest VA the OS will give us and exec
 897    *
 898    * Although using -(pagesz) as mmap hint works on newer kernel as you would
 899    * think, older variants affected by this work-around don't (search forward only).
 900    *
 901    * On the affected distributions, we understand the memory layout to be:
 902    *
 903    *   TASK_LIMIT= 3G, main stack base close to TASK_LIMT.
 904    *
 905    * A few pages south main stack will do it.
 906    *
 907    * If we are embedded in an app other than launcher (initial != main stack),
 908    * we don't have much control or understanding of the address space, just let it slide.
 909    */
 910   char* hint = (char*) (Linux::initial_thread_stack_bottom() -
 911                         ((StackYellowPages + StackRedPages + 1) * page_size));
 912   char* codebuf = os::attempt_reserve_memory_at(page_size, hint);










 913   if ( (codebuf == NULL) || (!os::commit_memory(codebuf, page_size, true)) ) {
 914     return; // No matter, we tried, best effort.
 915   }
 916   if (PrintMiscellaneous && (Verbose || WizardMode)) {
 917      tty->print_cr("[CS limit NX emulation work-around, exec code at: %p]", codebuf);
 918   }
 919 
 920   // Some code to exec: the 'ret' instruction
 921   codebuf[0] = 0xC3;
 922 
 923   // Call the code in the codebuf
 924   __asm__ volatile("call *%0" : : "r"(codebuf));
 925 
 926   // keep the page mapped so CS limit isn't reduced.
 927 #endif
 928 }


 875                       : "r" (fpu_cntrl) : "memory");
 876 #endif // !AMD64
 877 }
 878 
 879 #ifndef PRODUCT
 880 void os::verify_stack_alignment() {
 881 #ifdef AMD64
 882   assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment");
 883 #endif
 884 }
 885 #endif
 886 
 887 
 888 /*
 889  * IA32 only: execute code at a high address in case buggy NX emulation is present. I.e. avoid CS limit
 890  * updates (JDK-8023956).
 891  */
 892 void os::workaround_expand_exec_shield_cs_limit() {
 893 #if defined(IA32)
 894   size_t page_size = os::vm_page_size();
 895 
 896   /*
 897    * JDK-8197429
 898    *
 899    * Expand the stack mapping to the end of the initial stack before
 900    * attempting to install the codebuf.  This is needed because newer
 901    * Linux kernels impose a distance of a megabyte between stack
 902    * memory and other memory regions.  If we try to install the
 903    * codebuf before expanding the stack the installation will appear
 904    * to succeed but we'll get a segfault later if we expand the stack
 905    * in Java code.
 906    *
 907    */
 908   if (os::is_primordial_thread()) {
 909     address limit = Linux::initial_thread_stack_bottom();
 910     if (! DisablePrimordialThreadGuardPages) {
 911       limit += (StackYellowPages + StackRedPages) * page_size;
 912     }
 913     os::Linux::expand_stack_to(limit);
 914   }
 915 
 916   /*
 917    * Take the highest VA the OS will give us and exec
 918    *
 919    * Although using -(pagesz) as mmap hint works on newer kernel as you would
 920    * think, older variants affected by this work-around don't (search forward only).
 921    *
 922    * On the affected distributions, we understand the memory layout to be:
 923    *
 924    *   TASK_LIMIT= 3G, main stack base close to TASK_LIMT.
 925    *
 926    * A few pages south main stack will do it.
 927    *
 928    * If we are embedded in an app other than launcher (initial != main stack),
 929    * we don't have much control or understanding of the address space, just let it slide.
 930    */
 931   char* hint = (char*) (Linux::initial_thread_stack_bottom() -
 932                         ((StackYellowPages + StackRedPages + 1) * page_size));
 933   char* codebuf = os::attempt_reserve_memory_at(page_size, hint);
 934 
 935   if (codebuf == NULL) {
 936     // JDK-8197429: There may be a stack gap of one megabyte between
 937     // the limit of the stack and the nearest memory region: this is a
 938     // Linux kernel workaround for CVE-2017-1000364.  If we failed to
 939     // map our codebuf, try again at an address one megabyte lower.
 940     hint -= 1 * M;
 941     codebuf = os::attempt_reserve_memory_at(page_size, hint);
 942   }
 943 
 944   if ( (codebuf == NULL) || (!os::commit_memory(codebuf, page_size, true)) ) {
 945     return; // No matter, we tried, best effort.
 946   }
 947   if (PrintMiscellaneous && (Verbose || WizardMode)) {
 948      tty->print_cr("[CS limit NX emulation work-around, exec code at: %p]", codebuf);
 949   }
 950 
 951   // Some code to exec: the 'ret' instruction
 952   codebuf[0] = 0xC3;
 953 
 954   // Call the code in the codebuf
 955   __asm__ volatile("call *%0" : : "r"(codebuf));
 956 
 957   // keep the page mapped so CS limit isn't reduced.
 958 #endif
 959 }
< prev index next >