Mercurial > hg > truffle
comparison src/os_cpu/linux_x86/vm/os_linux_x86.cpp @ 12313:899ecf76b570
8023956: Provide a work-around to broken Linux 32 bit "Exec Shield" using CS for NX emulation (crashing with SI_KERNEL)
Summary: Execute some code at a high virtual address value, and keep mapped
Reviewed-by: coleenp, zgu
author | dsimms |
---|---|
date | Wed, 25 Sep 2013 13:58:13 +0200 |
parents | af21010d1062 |
children | cefad50507d8 de6a9e811145 |
comparison
equal
deleted
inserted
replaced
12292:084b21cd0228 | 12313:899ecf76b570 |
---|---|
874 #ifdef AMD64 | 874 #ifdef AMD64 |
875 assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment"); | 875 assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment"); |
876 #endif | 876 #endif |
877 } | 877 } |
878 #endif | 878 #endif |
879 | |
880 | |
881 /* | |
882 * IA32 only: execute code at a high address in case buggy NX emulation is present. I.e. avoid CS limit | |
883 * updates (JDK-8023956). | |
884 */ | |
885 void os::workaround_expand_exec_shield_cs_limit() { | |
886 #if defined(IA32) | |
887 size_t page_size = os::vm_page_size(); | |
888 /* | |
889 * Take the highest VA the OS will give us and exec | |
890 * | |
891 * Although using -(pagesz) as mmap hint works on newer kernel as you would | |
892 * think, older variants affected by this work-around don't (search forward only). | |
893 * | |
894 * On the affected distributions, we understand the memory layout to be: | |
895 * | |
896 * TASK_LIMIT= 3G, main stack base close to TASK_LIMT. | |
897 * | |
898 * A few pages south main stack will do it. | |
899 * | |
900 * If we are embedded in an app other than launcher (initial != main stack), | |
901 * we don't have much control or understanding of the address space, just let it slide. | |
902 */ | |
903 char* hint = (char*) (Linux::initial_thread_stack_bottom() - | |
904 ((StackYellowPages + StackRedPages + 1) * page_size)); | |
905 char* codebuf = os::reserve_memory(page_size, hint); | |
906 if ( (codebuf == NULL) || (!os::commit_memory(codebuf, page_size, true)) ) { | |
907 return; // No matter, we tried, best effort. | |
908 } | |
909 if (PrintMiscellaneous && (Verbose || WizardMode)) { | |
910 tty->print_cr("[CS limit NX emulation work-around, exec code at: %p]", codebuf); | |
911 } | |
912 | |
913 // Some code to exec: the 'ret' instruction | |
914 codebuf[0] = 0xC3; | |
915 | |
916 // Call the code in the codebuf | |
917 __asm__ volatile("call *%0" : : "r"(codebuf)); | |
918 | |
919 // keep the page mapped so CS limit isn't reduced. | |
920 #endif | |
921 } |