United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6478739 -Xcheck:jni Protect the system stack with a NULL page
JDK-6478739 : -Xcheck:jni Protect the system stack with a NULL page

Details
Type:
Enhancement
Submit Date:
2006-10-05
Status:
Closed
Updated Date:
2012-10-13
Project Name:
JDK
Resolved Date:
2007-01-31
Component:
hotspot
OS:
solaris
Sub-Component:
runtime
CPU:
generic
Priority:
P4
Resolution:
Fixed
Affected Versions:
6
Fixed Versions:
hs10 (b07)

Related Reports
Backport:
Backport:
Relates:
Relates:
Relates:

Sub Tasks

Description
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.

                                    

Comments
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.
                                     
2006-11-07
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.
                                     
2006-11-07



Hardware and Software, Engineered to Work Together