JDK-6478739 : -Xcheck:jni Protect the system stack with a NULL page
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 6
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: solaris
  • CPU: generic
  • Submitted: 2006-10-05
  • Updated: 2012-10-13
  • Resolved: 2007-01-31
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7 Other
6u4Fixed 7Fixed hs10Fixed
Related Reports
Relates :  
Relates :  
Relates :  
We should protect the VM  by making the addr 0x0 non-writeable by creating 
a  Read-only page mapped
at address 0x0, this will prevent (very hard to find) Bugs. 
There are two case this can happen:
1) An OS bug which decides to map over the 0x0 and make it legal 
see Bug: 6374692
2) User code preceding CreateJavaVM may do something like this 
   mmap(0, MAP_FIXED). The OS could map 0x0, and this very be allowed, 
   as mmap(2) spec. is not very clear, whether it is legal or not.

SUGGESTED FIX src/os/solaris/vm/os_solaris.cpp *************** *** 2002,2007 **** --- 2004,2033 ---- st->cr(); } + + static jboolean check_addr0(outputStream* st) { + jboolean status = false; + int fd = open("/proc/self/map",O_RDONLY); + if (fd >= 0) { + prmap_t p; + while(read(fd, &p, sizeof(p)) > 0) { + if (p.pr_vaddr == 0x0) { + st->print("Warning: Address: 0x%x, Size: %dK, ",p.pr_vaddr, p.pr_size/1024, p.pr_mapname); + st->print("Mapped file: %s, ", p.pr_mapname[0] == '\0' ? "None" : p.pr_mapname); + st->print("Access:"); + st->print("%s",(p.pr_mflags & MA_READ) ? "r" : "-"); + st->print("%s",(p.pr_mflags & MA_WRITE) ? "w" : "-"); + st->print("%s",(p.pr_mflags & MA_EXEC) ? "x" : "-"); + st->cr(); + status = true; + } + close(fd); + } + } + return status; + } + + void os::print_memory_info(outputStream* st) { st->print("Memory:"); st->print(" %dk page", os::vm_page_size()>>10); *************** *** 2008,2013 **** --- 2034,2040 ---- st->print(", physical " UINT64_FORMAT "k", os::physical_memory()>>10); st->print("(" UINT64_FORMAT "k free)", os::available_memory() >> 10); st->cr(); + (void) check_addr0(st); } This addresses part of the issue where an application crashes, there are cases there might not be a crash, instead wierd behavior such as an unexpected NPE. In which case we may want to augment -Xcheck:jni to do the above check periodically using the watcher thread, though it is expensive and slow but will aid immensely in debugging errant JNI applications, also this fix is not required for Linux and Windows, as mmap(0...) is not allowed, only Solaris requires this.

EVALUATION Case 1: is a solaris bug and will be fixed as such. Case 2: is what needs to be addressed as follows: After discussing this with Dice, the right way thing to do is warn users that addr 0x0 is hijacked. In the suggested fix the code segment probes the proc/self/map to check for this case. Reserving the memory in the launcher only protects applications started from the laucher, also a user application may rely on 0x0 to be owned and protected. The above approach at the very least can point to some clues.