JDK-4836743 : Backward compatibility - jni apps need to dereference bogus returned reference
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 1.4.2
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: generic,windows_xp
  • CPU: generic,x86
  • Submitted: 2003-03-24
  • Updated: 2003-11-17
  • Resolved: 2003-04-08
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.
Other Other Other
1.3.1_09 09Fixed 1.4.1_07Fixed 1.4.2Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Description
Calls to the JNI function Get<type>ArrayElements() normally return a
pointer to a copy of the specified array.  Callers can use this pointer
to access elements of the array.  If the array is empty, there are no
elements to access, and the returned pointer should not be used.

The fix for bug 4804447 handled this special (empty array) case, by
returning a pointer to an invalid page.  Previously, a pointer to an
arbitrary block of memory (with zero data elements) was returned.  

Unfortunately, there are one or more customer applications which
(indirectly) rely on the initial zero bytes being present.  One customer
passes the zero length array to a Microsoft API (DirectDraw) which
accesses the first character in the zero length array.  This is clearly
a bug in the Microsoft code.  The VM needs to be compatible with this
buggy behavior to avoid breaking the customer's app.

A test case is attached.  Just compile and run.


Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: 1.3.1_09 1.4.1_07 generic mantis-rc tiger FIXED IN: 1.3.1_09 1.4.1_07 mantis-rc tiger INTEGRATED IN: 1.3.1_09 1.4.1_07 mantis-b20 mantis-rc tiger tiger-b05 tiger-b08 VERIFIED IN: 1.3.1_09
14-06-2004

SUGGESTED FIX ###@###.### 2003-03-24 Instead of returning a pointer to an inaccessible page, return a pointer to a read-only page (containing zeros). *** /tmp/geta6049 Mon Mar 24 17:24:13 2003 --- jni.cpp Fri Mar 21 17:28:15 2003 *************** *** 1510,1516 **** size_t size = os::vm_page_size(); bad_address = os::reserve_memory(size); if (bad_address != NULL) { ! os::guard_memory(bad_address, size); } } return bad_address; --- 1510,1516 ---- size_t size = os::vm_page_size(); bad_address = os::reserve_memory(size); if (bad_address != NULL) { ! os::protect_memory(bad_address, size); } } return bad_address; *** /tmp/geta6056 Mon Mar 24 17:25:04 2003 --- os_win32.cpp Fri Mar 21 17:27:12 2003 *************** *** 1835,1840 **** --- 1835,1846 ---- } + bool os::protect_memory(char* addr, size_t bytes) { + DWORD old_status; + return VirtualProtect(addr, bytes, PAGE_READONLY, &old_status); + } + + bool os::guard_memory(char* addr, size_t bytes) { DWORD old_status; return VirtualProtect(addr, bytes, PAGE_EXECUTE_READWRITE | PAGE_GUARD, &old_status); *** /tmp/geta6063 Mon Mar 24 17:25:37 2003 --- os_solaris.cpp Fri Mar 21 17:25:36 2003 *************** *** 1724,1729 **** --- 1724,1741 ---- // guard_memory and unguard_memory only happens within stack guard pages. // Since ISM pertains only to the heap, guard and unguard memory should not /// happen with an ISM region. + bool os::protect_memory(char* addr, size_t bytes) { + if ((UseISM || UsePermISM) && os::Solaris::largepage_range(addr, bytes)) { + fatal("guard_memory should not happen within an ISM region."); + } else { + int retVal = mprotect(addr, (size_t)bytes, PROT_READ); + return retVal == 0; + } + } + + // guard_memory and unguard_memory only happens within stack guard pages. + // Since ISM pertains only to the heap, guard and unguard memory should not + /// happen with an ISM region. bool os::guard_memory(char* addr, size_t bytes) { if ((UseISM || UsePermISM) && os::Solaris::largepage_range(addr, bytes)) { fatal("guard_memory should not happen within an ISM region."); *** /tmp/geta6070 Mon Mar 24 17:27:15 2003 --- os_linux.cpp Fri Mar 21 17:24:59 2003 *************** *** 1002,1007 **** --- 1002,1011 ---- return ::munmap(addr, size) == 0; } + bool os::protect_memory(char* addr, size_t size) { + return ::mprotect(addr, (size_t) size, PROT_READ) == 0; + } + bool os::guard_memory(char* addr, size_t size) { return ::mprotect(addr, (size_t) size, PROT_NONE) == 0; }
11-06-2004

EVALUATION ###@###.### 2003-03-24 Valid problem, fix or not to fix? ###@###.### 2003-03-24 Fix is simple, but requires a simple method be added for each OS supported.
24-03-2003