8023956: Provide a work-around to broken Linux 32 bit "Exec Shield" using CS for NX emulation (crashing with SI_KERNEL)

Wed, 25 Sep 2013 13:58:13 +0200

author
dsimms
date
Wed, 25 Sep 2013 13:58:13 +0200
changeset 5781
899ecf76b570
parent 5760
084b21cd0228
child 5782
5b1191bf0b4b

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

src/os/linux/vm/os_linux.cpp file | annotate | diff | comparison | revisions
src/os_cpu/linux_x86/vm/os_linux_x86.cpp file | annotate | diff | comparison | revisions
src/os_cpu/linux_x86/vm/os_linux_x86.hpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/os/linux/vm/os_linux.cpp	Mon Sep 23 08:56:19 2013 -0700
     1.2 +++ b/src/os/linux/vm/os_linux.cpp	Wed Sep 25 13:58:13 2013 +0200
     1.3 @@ -4839,6 +4839,10 @@
     1.4  
     1.5    Linux::capture_initial_stack(JavaThread::stack_size_at_create());
     1.6  
     1.7 +#if defined(IA32)
     1.8 +  workaround_expand_exec_shield_cs_limit();
     1.9 +#endif
    1.10 +
    1.11    Linux::libpthread_init();
    1.12    if (PrintMiscellaneous && (Verbose || WizardMode)) {
    1.13       tty->print_cr("[HotSpot is running with %s, %s(%s)]\n",
     2.1 --- a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Mon Sep 23 08:56:19 2013 -0700
     2.2 +++ b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Wed Sep 25 13:58:13 2013 +0200
     2.3 @@ -876,3 +876,46 @@
     2.4  #endif
     2.5  }
     2.6  #endif
     2.7 +
     2.8 +
     2.9 +/*
    2.10 + * IA32 only: execute code at a high address in case buggy NX emulation is present. I.e. avoid CS limit
    2.11 + * updates (JDK-8023956).
    2.12 + */
    2.13 +void os::workaround_expand_exec_shield_cs_limit() {
    2.14 +#if defined(IA32)
    2.15 +  size_t page_size = os::vm_page_size();
    2.16 +  /*
    2.17 +   * Take the highest VA the OS will give us and exec
    2.18 +   *
    2.19 +   * Although using -(pagesz) as mmap hint works on newer kernel as you would
    2.20 +   * think, older variants affected by this work-around don't (search forward only).
    2.21 +   *
    2.22 +   * On the affected distributions, we understand the memory layout to be:
    2.23 +   *
    2.24 +   *   TASK_LIMIT= 3G, main stack base close to TASK_LIMT.
    2.25 +   *
    2.26 +   * A few pages south main stack will do it.
    2.27 +   *
    2.28 +   * If we are embedded in an app other than launcher (initial != main stack),
    2.29 +   * we don't have much control or understanding of the address space, just let it slide.
    2.30 +   */
    2.31 +  char* hint = (char*) (Linux::initial_thread_stack_bottom() -
    2.32 +                        ((StackYellowPages + StackRedPages + 1) * page_size));
    2.33 +  char* codebuf = os::reserve_memory(page_size, hint);
    2.34 +  if ( (codebuf == NULL) || (!os::commit_memory(codebuf, page_size, true)) ) {
    2.35 +    return; // No matter, we tried, best effort.
    2.36 +  }
    2.37 +  if (PrintMiscellaneous && (Verbose || WizardMode)) {
    2.38 +     tty->print_cr("[CS limit NX emulation work-around, exec code at: %p]", codebuf);
    2.39 +  }
    2.40 +
    2.41 +  // Some code to exec: the 'ret' instruction
    2.42 +  codebuf[0] = 0xC3;
    2.43 +
    2.44 +  // Call the code in the codebuf
    2.45 +  __asm__ volatile("call *%0" : : "r"(codebuf));
    2.46 +
    2.47 +  // keep the page mapped so CS limit isn't reduced.
    2.48 +#endif
    2.49 +}
     3.1 --- a/src/os_cpu/linux_x86/vm/os_linux_x86.hpp	Mon Sep 23 08:56:19 2013 -0700
     3.2 +++ b/src/os_cpu/linux_x86/vm/os_linux_x86.hpp	Wed Sep 25 13:58:13 2013 +0200
     3.3 @@ -36,4 +36,17 @@
     3.4    // Note: Currently only used in 64 bit Windows implementations
     3.5    static bool register_code_area(char *low, char *high) { return true; }
     3.6  
     3.7 +  /*
     3.8 +   * Work-around for broken NX emulation using CS limit, Red Hat patch "Exec-Shield"
     3.9 +   * (IA32 only).
    3.10 +   *
    3.11 +   * Map and execute at a high VA to prevent CS lazy updates race with SMP MM
    3.12 +   * invalidation.Further code generation by the JVM will no longer cause CS limit
    3.13 +   * updates.
    3.14 +   *
    3.15 +   * Affects IA32: RHEL 5 & 6, Ubuntu 10.04 (LTS), 10.10, 11.04, 11.10, 12.04.
    3.16 +   * @see JDK-8023956
    3.17 +   */
    3.18 +  static void workaround_expand_exec_shield_cs_limit();
    3.19 +
    3.20  #endif // OS_CPU_LINUX_X86_VM_OS_LINUX_X86_HPP

mercurial