Tue, 16 Jul 2013 07:33:29 +0200
6671508: JNI GetPrimitiveArrayCritical should not be callable on object arrays
Summary: Checked JNI now reports error for Get/ReleasePrimitiveArrayCritical on object arrays
Reviewed-by: dholmes, acorn
Contributed-by: david.simms@oracle.com
src/share/vm/prims/jniCheck.cpp | file | annotate | diff | comparison | revisions |
1.1 --- a/src/share/vm/prims/jniCheck.cpp Mon Jul 15 23:23:15 2013 -0400 1.2 +++ b/src/share/vm/prims/jniCheck.cpp Tue Jul 16 07:33:29 2013 +0200 1.3 @@ -126,6 +126,7 @@ 1.4 static const char * fatal_non_weak_method = "non-weak methodID passed to JNI call"; 1.5 static const char * fatal_unknown_array_object = "Unknown array object passed to JNI array operations"; 1.6 static const char * fatal_object_array_expected = "Object array expected but not received for JNI array operation"; 1.7 +static const char * fatal_prim_type_array_expected = "Primitive type array expected but not received for JNI array operation"; 1.8 static const char * fatal_non_array = "Non-array passed to JNI array operations"; 1.9 static const char * fatal_element_type_mismatch = "Array element type mismatch in JNI"; 1.10 static const char * fatal_should_be_static = "Non-static field ID passed to JNI"; 1.11 @@ -278,30 +279,53 @@ 1.12 ReportJNIFatalError(thr, fatal_non_string); 1.13 } 1.14 1.15 -static inline void 1.16 -checkArray(JavaThread* thr, jarray jArray, int elementType) 1.17 +static inline arrayOop 1.18 +check_is_array(JavaThread* thr, jarray jArray) 1.19 { 1.20 ASSERT_OOPS_ALLOWED; 1.21 arrayOop aOop; 1.22 1.23 aOop = (arrayOop)jniCheck::validate_object(thr, jArray); 1.24 - if (aOop == NULL || !aOop->is_array()) 1.25 + if (aOop == NULL || !aOop->is_array()) { 1.26 ReportJNIFatalError(thr, fatal_non_array); 1.27 + } 1.28 + return aOop; 1.29 +} 1.30 1.31 - if (elementType != -1) { 1.32 - if (aOop->is_typeArray()) { 1.33 - BasicType array_type = TypeArrayKlass::cast(aOop->klass())->element_type(); 1.34 - if (array_type != elementType) 1.35 - ReportJNIFatalError(thr, fatal_element_type_mismatch); 1.36 - } else if (aOop->is_objArray()) { 1.37 - if ( T_OBJECT != elementType) 1.38 - ReportJNIFatalError(thr, fatal_object_array_expected); 1.39 - } else { 1.40 - ReportJNIFatalError(thr, fatal_unknown_array_object); 1.41 - } 1.42 +static inline arrayOop 1.43 +check_is_primitive_array(JavaThread* thr, jarray jArray) { 1.44 + arrayOop aOop = check_is_array(thr, jArray); 1.45 + 1.46 + if (!aOop->is_typeArray()) { 1.47 + ReportJNIFatalError(thr, fatal_prim_type_array_expected); 1.48 + } 1.49 + return aOop; 1.50 +} 1.51 + 1.52 +static inline void 1.53 +check_primitive_array_type(JavaThread* thr, jarray jArray, BasicType elementType) 1.54 +{ 1.55 + BasicType array_type; 1.56 + arrayOop aOop; 1.57 + 1.58 + aOop = check_is_primitive_array(thr, jArray); 1.59 + array_type = TypeArrayKlass::cast(aOop->klass())->element_type(); 1.60 + if (array_type != elementType) { 1.61 + ReportJNIFatalError(thr, fatal_element_type_mismatch); 1.62 } 1.63 } 1.64 1.65 +static inline void 1.66 +check_is_obj_array(JavaThread* thr, jarray jArray) { 1.67 + BasicType array_type; 1.68 + arrayOop aOop; 1.69 + 1.70 + aOop = check_is_array(thr, jArray); 1.71 + array_type = TypeArrayKlass::cast(aOop->klass())->element_type(); 1.72 + if (array_type != T_OBJECT) { 1.73 + ReportJNIFatalError(thr, fatal_object_array_expected); 1.74 + } 1.75 +} 1.76 1.77 oop jniCheck::validate_handle(JavaThread* thr, jobject obj) { 1.78 if (JNIHandles::is_frame_handle(thr, obj) || 1.79 @@ -1417,7 +1441,7 @@ 1.80 jarray array)) 1.81 functionEnter(thr); 1.82 IN_VM( 1.83 - checkArray(thr, array, -1); 1.84 + check_is_array(thr, array); 1.85 ) 1.86 jsize result = UNCHECKED()->GetArrayLength(env,array); 1.87 functionExit(env); 1.88 @@ -1441,7 +1465,7 @@ 1.89 jsize index)) 1.90 functionEnter(thr); 1.91 IN_VM( 1.92 - checkArray(thr, array, T_OBJECT); 1.93 + check_is_obj_array(thr, array); 1.94 ) 1.95 jobject result = UNCHECKED()->GetObjectArrayElement(env,array,index); 1.96 functionExit(env); 1.97 @@ -1455,7 +1479,7 @@ 1.98 jobject val)) 1.99 functionEnter(thr); 1.100 IN_VM( 1.101 - checkArray(thr, array, T_OBJECT); 1.102 + check_is_obj_array(thr, array); 1.103 ) 1.104 UNCHECKED()->SetObjectArrayElement(env,array,index,val); 1.105 functionExit(env); 1.106 @@ -1487,7 +1511,7 @@ 1.107 jboolean *isCopy)) \ 1.108 functionEnter(thr); \ 1.109 IN_VM( \ 1.110 - checkArray(thr, array, ElementTag); \ 1.111 + check_primitive_array_type(thr, array, ElementTag); \ 1.112 ) \ 1.113 ElementType *result = UNCHECKED()->Get##Result##ArrayElements(env, \ 1.114 array, \ 1.115 @@ -1513,7 +1537,7 @@ 1.116 jint mode)) \ 1.117 functionEnterExceptionAllowed(thr); \ 1.118 IN_VM( \ 1.119 - checkArray(thr, array, ElementTag); \ 1.120 + check_primitive_array_type(thr, array, ElementTag); \ 1.121 ASSERT_OOPS_ALLOWED; \ 1.122 typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \ 1.123 /* cannot check validity of copy, unless every request is logged by 1.124 @@ -1543,7 +1567,7 @@ 1.125 ElementType *buf)) \ 1.126 functionEnter(thr); \ 1.127 IN_VM( \ 1.128 - checkArray(thr, array, ElementTag); \ 1.129 + check_primitive_array_type(thr, array, ElementTag); \ 1.130 ) \ 1.131 UNCHECKED()->Get##Result##ArrayRegion(env,array,start,len,buf); \ 1.132 functionExit(env); \ 1.133 @@ -1567,7 +1591,7 @@ 1.134 const ElementType *buf)) \ 1.135 functionEnter(thr); \ 1.136 IN_VM( \ 1.137 - checkArray(thr, array, ElementTag); \ 1.138 + check_primitive_array_type(thr, array, ElementTag); \ 1.139 ) \ 1.140 UNCHECKED()->Set##Result##ArrayRegion(env,array,start,len,buf); \ 1.141 functionExit(env); \ 1.142 @@ -1669,7 +1693,7 @@ 1.143 jboolean *isCopy)) 1.144 functionEnterCritical(thr); 1.145 IN_VM( 1.146 - checkArray(thr, array, -1); 1.147 + check_is_primitive_array(thr, array); 1.148 ) 1.149 void *result = UNCHECKED()->GetPrimitiveArrayCritical(env, array, isCopy); 1.150 functionExit(env); 1.151 @@ -1683,7 +1707,7 @@ 1.152 jint mode)) 1.153 functionEnterCriticalExceptionAllowed(thr); 1.154 IN_VM( 1.155 - checkArray(thr, array, -1); 1.156 + check_is_primitive_array(thr, array); 1.157 ) 1.158 /* The Hotspot JNI code does not use the parameters, so just check the 1.159 * array parameter as a minor sanity check