# HG changeset patch # User mikael # Date 1493827992 25200 # Wed May 03 09:13:12 2017 -0700 # Node ID cf92a17ccffcbe397273d0e7b3032666eb990914 # Parent 60bfd8d0aba50de2d0af690a695033de23fb4883 [mq]: paxcheck diff --git a/src/os/linux/vm/os_linux.cpp b/src/os/linux/vm/os_linux.cpp --- a/src/os/linux/vm/os_linux.cpp +++ b/src/os/linux/vm/os_linux.cpp @@ -4728,6 +4728,56 @@ extern void report_error(char* file_name, int line_no, char* title, char* format, ...); +// Some linux distributions (notably: Alpine Linux) include the +// grsecurity in the kernel by default. Of particular interest from a +// JVM perspective is PaX (https://pax.grsecurity.net/), which adds +// some security features related to page attributes. Specifically, +// the MPROTECT PaX functionality +// (https://pax.grsecurity.net/docs/mprotect.txt) prevents dynamic +// code generation by disallowing a (previously) writable page to be +// marked as executable. This is, of course, exactly what HotSpot does +// for both JIT compiled method, as well as for stubs, adapters, etc. +// +// Instead of crashing "lazily" when trying to make a page executable, +// this code probes for the presence of PaX and reports the failure +// eagerly. +static void check_pax(void) { + // Zero doesn't generate code dynamically, so no need to perform the PaX check +#ifndef ZERO + size_t size = os::Linux::page_size(); + + void* p = ::mmap(NULL, size, PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + if (p == MAP_FAILED) { + vm_exit_out_of_memory(size, OOM_MMAP_ERROR, "failed to allocate memory for PaX check."); + } + + int res = ::mprotect(p, size, PROT_WRITE|PROT_EXEC); + if (res == -1) { + vm_exit_during_initialization("failed to mark memory page as executable", + "Please check if grsecurity/PaX is enabled in your kernel.\n" + "\n" + "For example, you can do this by running (note: you may need root privileges):\n" + "\n" + " sysctl kernel.pax.softmode\n" + "\n" + "If PaX is included in the kernel you will see something like this:\n" + "\n" + " kernel.pax.softmode = 0\n" + "\n" + "In particular, if the value is 0 (zero), then PaX is enabled.\n" + "\n" + "PaX includes security functionality which interferes with the dynamic code\n" + "generation the JVM relies on. Specifically, the MPROTECT functionality as\n" + "described on https://pax.grsecurity.net/docs/mprotect.txt is not compatible\n" + "with the JVM. If you want to allow the JVM to run you will have to disable PaX.\n" + "You can do this on a per-executable basis using the paxctl tool.\n"); + + } + + ::munmap(p, size); +#endif +} + // this is called _before_ the most of global arguments have been parsed void os::init(void) { char dummy; // used to get a guess on initial stack address @@ -4779,6 +4829,7 @@ Linux::_pthread_setname_np = (int(*)(pthread_t, const char*))dlsym(RTLD_DEFAULT, "pthread_setname_np"); + check_pax(); } // To install functions for atexit system call # HG changeset patch # User mikael # Date 1493828010 25200 # Wed May 03 09:13:30 2017 -0700 # Node ID 7fd588534ad8256c8b9311ed859f683ecb0ffdde # Parent cf92a17ccffcbe397273d0e7b3032666eb990914 [mq]: paxcheck.01 diff --git a/src/os/linux/vm/os_linux.cpp b/src/os/linux/vm/os_linux.cpp --- a/src/os/linux/vm/os_linux.cpp +++ b/src/os/linux/vm/os_linux.cpp @@ -4753,7 +4753,7 @@ int res = ::mprotect(p, size, PROT_WRITE|PROT_EXEC); if (res == -1) { - vm_exit_during_initialization("failed to mark memory page as executable", + vm_exit_during_initialization("Failed to mark memory page as executable", "Please check if grsecurity/PaX is enabled in your kernel.\n" "\n" "For example, you can do this by running (note: you may need root privileges):\n" @@ -4770,7 +4770,14 @@ "generation the JVM relies on. Specifically, the MPROTECT functionality as\n" "described on https://pax.grsecurity.net/docs/mprotect.txt is not compatible\n" "with the JVM. If you want to allow the JVM to run you will have to disable PaX.\n" - "You can do this on a per-executable basis using the paxctl tool.\n"); + "You can do this on a per-executable basis using the paxctl tool, for example:\n" + "\n" + " paxctl -cm bin/java\n" + "\n" + "Please note that this modifies the executable binary in-place, so may want\n" + "to make a backup of it first. Also note that you have to repeat this for other\n" + "executables like javac, jar, jcmd, etc.\n" + ); }