< prev index next >

src/hotspot/share/prims/jniCheck.cpp

Print this page

 264   fieldDescriptor fd;
 265 
 266   /* make sure it is a static field */
 267   if (!jfieldIDWorkaround::is_static_jfieldID(fid))
 268     ReportJNIFatalError(thr, fatal_should_be_static);
 269 
 270   /* validate the class being passed */
 271   ASSERT_OOPS_ALLOWED;
 272   Klass* k_oop = jniCheck::validate_class(thr, cls, false);
 273 
 274   /* check for proper subclass hierarchy */
 275   JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fid);
 276   Klass* f_oop = id->holder();
 277   if (!k_oop->is_subtype_of(f_oop))
 278     ReportJNIFatalError(thr, fatal_wrong_static_field);
 279 
 280   /* check for proper field type */
 281   if (!id->find_local_field(&fd))
 282     ReportJNIFatalError(thr, fatal_static_field_not_found);
 283   if ((fd.field_type() != ftype) &&
 284       !(fd.field_type() == T_ARRAY && ftype == T_OBJECT)) {

 285     ReportJNIFatalError(thr, fatal_static_field_mismatch);
 286   }
 287 }
 288 
 289 static inline void
 290 checkInstanceFieldID(JavaThread* thr, jfieldID fid, jobject obj, int ftype)
 291 {
 292   fieldDescriptor fd;
 293 
 294   /* make sure it is an instance field */
 295   if (jfieldIDWorkaround::is_static_jfieldID(fid))
 296     ReportJNIFatalError(thr, fatal_should_be_nonstatic);
 297 
 298   /* validate the object being passed and then get its class */
 299   ASSERT_OOPS_ALLOWED;
 300   oop oopObj = jniCheck::validate_object(thr, obj);
 301   if (oopObj == NULL) {
 302     ReportJNIFatalError(thr, fatal_null_object);
 303   }
 304   Klass* k_oop = oopObj->klass();
 305 
 306   if (!jfieldIDWorkaround::is_valid_jfieldID(k_oop, fid)) {
 307     ReportJNIFatalError(thr, fatal_wrong_field);
 308   }
 309 
 310   /* make sure the field exists */
 311   int offset = jfieldIDWorkaround::from_instance_jfieldID(k_oop, fid);
 312   if (!InstanceKlass::cast(k_oop)->contains_field_offset(offset))
 313     ReportJNIFatalError(thr, fatal_wrong_field);
 314 
 315   /* check for proper field type */
 316   if (!InstanceKlass::cast(k_oop)->find_field_from_offset(offset,
 317                                                               false, &fd))
 318     ReportJNIFatalError(thr, fatal_instance_field_not_found);
 319 
 320   if ((fd.field_type() != ftype) &&
 321       !(fd.field_type() == T_ARRAY && ftype == T_OBJECT)) {

 322     ReportJNIFatalError(thr, fatal_instance_field_mismatch);
 323   }
 324 }
 325 
 326 static inline void
 327 checkString(JavaThread* thr, jstring js)
 328 {
 329   ASSERT_OOPS_ALLOWED;
 330   oop s = jniCheck::validate_object(thr, js);
 331   if ((s == NULL) || !java_lang_String::is_instance(s))
 332     ReportJNIFatalError(thr, fatal_non_string);
 333 }
 334 
 335 static inline arrayOop
 336 check_is_array(JavaThread* thr, jarray jArray)
 337 {
 338   ASSERT_OOPS_ALLOWED;
 339   arrayOop aOop;
 340 
 341   aOop = (arrayOop)jniCheck::validate_object(thr, jArray);

 352   if (!aOop->is_typeArray()) {
 353      ReportJNIFatalError(thr, fatal_prim_type_array_expected);
 354   }
 355   return aOop;
 356 }
 357 
 358 static inline void
 359 check_primitive_array_type(JavaThread* thr, jarray jArray, BasicType elementType)
 360 {
 361   BasicType array_type;
 362   arrayOop aOop;
 363 
 364   aOop = check_is_primitive_array(thr, jArray);
 365   array_type = TypeArrayKlass::cast(aOop->klass())->element_type();
 366   if (array_type != elementType) {
 367     ReportJNIFatalError(thr, fatal_element_type_mismatch);
 368   }
 369 }
 370 
 371 static inline void
 372 check_is_obj_array(JavaThread* thr, jarray jArray) {
 373   arrayOop aOop = check_is_array(thr, jArray);
 374   if (!aOop->is_objArray()) {
 375     ReportJNIFatalError(thr, fatal_object_array_expected);
 376   }
 377 }
 378 
 379 /*
 380  * Copy and wrap array elements for bounds checking.
 381  * Remember the original elements (GuardedMemory::get_tag())
 382  */
 383 static void* check_jni_wrap_copy_array(JavaThread* thr, jarray array,
 384     void* orig_elements) {
 385   void* result;
 386   IN_VM(
 387     oop a = JNIHandles::resolve_non_null(array);
 388     size_t len = arrayOop(a)->length() <<
 389         TypeArrayKlass::cast(a->klass())->log2_element_size();
 390     result = GuardedMemory::wrap_copy(orig_elements, len, orig_elements);
 391   )
 392   return result;
 393 }
 394 

 474 
 475 oop jniCheck::validate_object(JavaThread* thr, jobject obj) {
 476   if (obj == NULL) return NULL;
 477   ASSERT_OOPS_ALLOWED;
 478   oop oopObj = jniCheck::validate_handle(thr, obj);
 479   if (oopObj == NULL) {
 480     ReportJNIFatalError(thr, fatal_bad_ref_to_jni);
 481   }
 482   return oopObj;
 483 }
 484 
 485 // Warn if a class descriptor is in decorated form; class descriptors
 486 // passed to JNI findClass should not be decorated unless they are
 487 // array descriptors.
 488 void jniCheck::validate_class_descriptor(JavaThread* thr, const char* name) {
 489   if (name == NULL) return;  // implementation accepts NULL so just return
 490 
 491   size_t len = strlen(name);
 492 
 493   if (len >= 2 &&
 494       name[0] == JVM_SIGNATURE_CLASS &&            // 'L'
 495       name[len-1] == JVM_SIGNATURE_ENDCLASS ) {    // ';'
 496     char msg[JVM_MAXPATHLEN];
 497     jio_snprintf(msg, JVM_MAXPATHLEN, "%s%s%s",
 498                  warn_bad_class_descriptor1, name, warn_bad_class_descriptor2);
 499     ReportJNIWarning(thr, msg);
 500   }
 501 
 502   // Verify that the class name given is a valid utf8 string
 503   if (!UTF8::is_legal_utf8((const unsigned char*)name, (int)strlen(name), false)) {
 504     char msg[JVM_MAXPATHLEN];
 505     jio_snprintf(msg, JVM_MAXPATHLEN, "%s%s%s", fatal_non_utf8_class_name1, name, fatal_non_utf8_class_name2);
 506     ReportJNIFatalError(thr, msg);
 507   }
 508 }
 509 
 510 Klass* jniCheck::validate_class(JavaThread* thr, jclass clazz, bool allow_primitive) {
 511   ASSERT_OOPS_ALLOWED;
 512   oop mirror = jniCheck::validate_handle(thr, clazz);
 513   if (mirror == NULL) {
 514     ReportJNIFatalError(thr, fatal_received_null_class);

1623     return result;
1624 JNI_END
1625 
1626 JNI_ENTRY_CHECKED(jobjectArray,
1627   checked_jni_NewObjectArray(JNIEnv *env,
1628                              jsize len,
1629                              jclass clazz,
1630                              jobject init))
1631     functionEnter(thr);
1632     jobjectArray result = UNCHECKED()->NewObjectArray(env,len,clazz,init);
1633     functionExit(thr);
1634     return result;
1635 JNI_END
1636 
1637 JNI_ENTRY_CHECKED(jobject,
1638   checked_jni_GetObjectArrayElement(JNIEnv *env,
1639                                     jobjectArray array,
1640                                     jsize index))
1641     functionEnter(thr);
1642     IN_VM(
1643       check_is_obj_array(thr, array);
1644     )
1645     jobject result = UNCHECKED()->GetObjectArrayElement(env,array,index);
1646     functionExit(thr);
1647     return result;
1648 JNI_END
1649 
1650 JNI_ENTRY_CHECKED(void,
1651   checked_jni_SetObjectArrayElement(JNIEnv *env,
1652                                     jobjectArray array,
1653                                     jsize index,
1654                                     jobject val))
1655     functionEnter(thr);
1656     IN_VM(
1657       check_is_obj_array(thr, array);
1658     )
1659     UNCHECKED()->SetObjectArrayElement(env,array,index,val);
1660     functionExit(thr);
1661 JNI_END
1662 
1663 #define WRAPPER_NewScalarArray(Return, Result) \
1664 JNI_ENTRY_CHECKED(Return, \
1665   checked_jni_New##Result##Array(JNIEnv *env, \
1666                                  jsize len)) \
1667     functionEnter(thr); \
1668     Return result = UNCHECKED()->New##Result##Array(env,len); \
1669     functionExit(thr); \
1670     return (Return) result; \
1671 JNI_END
1672 
1673 WRAPPER_NewScalarArray(jbooleanArray, Boolean)
1674 WRAPPER_NewScalarArray(jbyteArray, Byte)
1675 WRAPPER_NewScalarArray(jshortArray, Short)
1676 WRAPPER_NewScalarArray(jcharArray, Char)
1677 WRAPPER_NewScalarArray(jintArray, Int)

2287     checked_jni_ReleasePrimitiveArrayCritical,
2288 
2289     checked_jni_GetStringCritical,
2290     checked_jni_ReleaseStringCritical,
2291 
2292     checked_jni_NewWeakGlobalRef,
2293     checked_jni_DeleteWeakGlobalRef,
2294 
2295     checked_jni_ExceptionCheck,
2296 
2297     checked_jni_NewDirectByteBuffer,
2298     checked_jni_GetDirectBufferAddress,
2299     checked_jni_GetDirectBufferCapacity,
2300 
2301     // New 1.6 Features
2302 
2303     checked_jni_GetObjectRefType,
2304 
2305     // Module Features
2306 
2307     checked_jni_GetModule

2308 };
2309 
2310 
2311 // Returns the function structure
2312 struct JNINativeInterface_* jni_functions_check() {
2313 
2314   unchecked_jni_NativeInterface = jni_functions_nocheck();
2315 
2316   // make sure the last pointer in the checked table is not null, indicating
2317   // an addition to the JNINativeInterface_ structure without initializing
2318   // it in the checked table.
2319   debug_only(int *lastPtr = (int *)((char *)&checked_jni_NativeInterface + \
2320              sizeof(*unchecked_jni_NativeInterface) - sizeof(char *));)
2321   assert(*lastPtr != 0,
2322          "Mismatched JNINativeInterface tables, check for new entries");
2323 
2324   // with -verbose:jni this message will print
2325   log_debug(jni, resolve)("Checked JNI functions are being used to validate JNI usage");
2326 
2327   return &checked_jni_NativeInterface;

 264   fieldDescriptor fd;
 265 
 266   /* make sure it is a static field */
 267   if (!jfieldIDWorkaround::is_static_jfieldID(fid))
 268     ReportJNIFatalError(thr, fatal_should_be_static);
 269 
 270   /* validate the class being passed */
 271   ASSERT_OOPS_ALLOWED;
 272   Klass* k_oop = jniCheck::validate_class(thr, cls, false);
 273 
 274   /* check for proper subclass hierarchy */
 275   JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fid);
 276   Klass* f_oop = id->holder();
 277   if (!k_oop->is_subtype_of(f_oop))
 278     ReportJNIFatalError(thr, fatal_wrong_static_field);
 279 
 280   /* check for proper field type */
 281   if (!id->find_local_field(&fd))
 282     ReportJNIFatalError(thr, fatal_static_field_not_found);
 283   if ((fd.field_type() != ftype) &&
 284       !(fd.field_type() == T_ARRAY && ftype == T_OBJECT) &&
 285       !(fd.field_type() == T_INLINE_TYPE && ftype == T_OBJECT)) {
 286     ReportJNIFatalError(thr, fatal_static_field_mismatch);
 287   }
 288 }
 289 
 290 static inline void
 291 checkInstanceFieldID(JavaThread* thr, jfieldID fid, jobject obj, int ftype)
 292 {
 293   fieldDescriptor fd;
 294 
 295   /* make sure it is an instance field */
 296   if (jfieldIDWorkaround::is_static_jfieldID(fid))
 297     ReportJNIFatalError(thr, fatal_should_be_nonstatic);
 298 
 299   /* validate the object being passed and then get its class */
 300   ASSERT_OOPS_ALLOWED;
 301   oop oopObj = jniCheck::validate_object(thr, obj);
 302   if (oopObj == NULL) {
 303     ReportJNIFatalError(thr, fatal_null_object);
 304   }
 305   Klass* k_oop = oopObj->klass();
 306 
 307   if (!jfieldIDWorkaround::is_valid_jfieldID(k_oop, fid)) {
 308     ReportJNIFatalError(thr, fatal_wrong_field);
 309   }
 310 
 311   /* make sure the field exists */
 312   int offset = jfieldIDWorkaround::from_instance_jfieldID(k_oop, fid);
 313   if (!InstanceKlass::cast(k_oop)->contains_field_offset(offset))
 314     ReportJNIFatalError(thr, fatal_wrong_field);
 315 
 316   /* check for proper field type */
 317   if (!InstanceKlass::cast(k_oop)->find_field_from_offset(offset,
 318                                                               false, &fd))
 319     ReportJNIFatalError(thr, fatal_instance_field_not_found);
 320 
 321   if ((fd.field_type() != ftype) &&
 322       !(fd.field_type() == T_ARRAY && ftype == T_OBJECT) &&
 323       !(fd.field_type() == T_INLINE_TYPE && ftype == T_OBJECT)) {
 324     ReportJNIFatalError(thr, fatal_instance_field_mismatch);
 325   }
 326 }
 327 
 328 static inline void
 329 checkString(JavaThread* thr, jstring js)
 330 {
 331   ASSERT_OOPS_ALLOWED;
 332   oop s = jniCheck::validate_object(thr, js);
 333   if ((s == NULL) || !java_lang_String::is_instance(s))
 334     ReportJNIFatalError(thr, fatal_non_string);
 335 }
 336 
 337 static inline arrayOop
 338 check_is_array(JavaThread* thr, jarray jArray)
 339 {
 340   ASSERT_OOPS_ALLOWED;
 341   arrayOop aOop;
 342 
 343   aOop = (arrayOop)jniCheck::validate_object(thr, jArray);

 354   if (!aOop->is_typeArray()) {
 355      ReportJNIFatalError(thr, fatal_prim_type_array_expected);
 356   }
 357   return aOop;
 358 }
 359 
 360 static inline void
 361 check_primitive_array_type(JavaThread* thr, jarray jArray, BasicType elementType)
 362 {
 363   BasicType array_type;
 364   arrayOop aOop;
 365 
 366   aOop = check_is_primitive_array(thr, jArray);
 367   array_type = TypeArrayKlass::cast(aOop->klass())->element_type();
 368   if (array_type != elementType) {
 369     ReportJNIFatalError(thr, fatal_element_type_mismatch);
 370   }
 371 }
 372 
 373 static inline void
 374 check_is_obj_or_inline_array(JavaThread* thr, jarray jArray) {
 375   arrayOop aOop = check_is_array(thr, jArray);
 376   if (!aOop->is_objArray() && !aOop->is_flatArray()) {
 377     ReportJNIFatalError(thr, fatal_object_array_expected);
 378   }
 379 }
 380 
 381 /*
 382  * Copy and wrap array elements for bounds checking.
 383  * Remember the original elements (GuardedMemory::get_tag())
 384  */
 385 static void* check_jni_wrap_copy_array(JavaThread* thr, jarray array,
 386     void* orig_elements) {
 387   void* result;
 388   IN_VM(
 389     oop a = JNIHandles::resolve_non_null(array);
 390     size_t len = arrayOop(a)->length() <<
 391         TypeArrayKlass::cast(a->klass())->log2_element_size();
 392     result = GuardedMemory::wrap_copy(orig_elements, len, orig_elements);
 393   )
 394   return result;
 395 }
 396 

 476 
 477 oop jniCheck::validate_object(JavaThread* thr, jobject obj) {
 478   if (obj == NULL) return NULL;
 479   ASSERT_OOPS_ALLOWED;
 480   oop oopObj = jniCheck::validate_handle(thr, obj);
 481   if (oopObj == NULL) {
 482     ReportJNIFatalError(thr, fatal_bad_ref_to_jni);
 483   }
 484   return oopObj;
 485 }
 486 
 487 // Warn if a class descriptor is in decorated form; class descriptors
 488 // passed to JNI findClass should not be decorated unless they are
 489 // array descriptors.
 490 void jniCheck::validate_class_descriptor(JavaThread* thr, const char* name) {
 491   if (name == NULL) return;  // implementation accepts NULL so just return
 492 
 493   size_t len = strlen(name);
 494 
 495   if (len >= 2 &&
 496       (name[0] == JVM_SIGNATURE_CLASS || name[0] == JVM_SIGNATURE_INLINE_TYPE) && // 'L' or 'Q'
 497       name[len-1] == JVM_SIGNATURE_ENDCLASS ) {    // ';'
 498     char msg[JVM_MAXPATHLEN];
 499     jio_snprintf(msg, JVM_MAXPATHLEN, "%s%s%s",
 500                  warn_bad_class_descriptor1, name, warn_bad_class_descriptor2);
 501     ReportJNIWarning(thr, msg);
 502   }
 503 
 504   // Verify that the class name given is a valid utf8 string
 505   if (!UTF8::is_legal_utf8((const unsigned char*)name, (int)strlen(name), false)) {
 506     char msg[JVM_MAXPATHLEN];
 507     jio_snprintf(msg, JVM_MAXPATHLEN, "%s%s%s", fatal_non_utf8_class_name1, name, fatal_non_utf8_class_name2);
 508     ReportJNIFatalError(thr, msg);
 509   }
 510 }
 511 
 512 Klass* jniCheck::validate_class(JavaThread* thr, jclass clazz, bool allow_primitive) {
 513   ASSERT_OOPS_ALLOWED;
 514   oop mirror = jniCheck::validate_handle(thr, clazz);
 515   if (mirror == NULL) {
 516     ReportJNIFatalError(thr, fatal_received_null_class);

1625     return result;
1626 JNI_END
1627 
1628 JNI_ENTRY_CHECKED(jobjectArray,
1629   checked_jni_NewObjectArray(JNIEnv *env,
1630                              jsize len,
1631                              jclass clazz,
1632                              jobject init))
1633     functionEnter(thr);
1634     jobjectArray result = UNCHECKED()->NewObjectArray(env,len,clazz,init);
1635     functionExit(thr);
1636     return result;
1637 JNI_END
1638 
1639 JNI_ENTRY_CHECKED(jobject,
1640   checked_jni_GetObjectArrayElement(JNIEnv *env,
1641                                     jobjectArray array,
1642                                     jsize index))
1643     functionEnter(thr);
1644     IN_VM(
1645       check_is_obj_or_inline_array(thr, array);
1646     )
1647     jobject result = UNCHECKED()->GetObjectArrayElement(env,array,index);
1648     functionExit(thr);
1649     return result;
1650 JNI_END
1651 
1652 JNI_ENTRY_CHECKED(void,
1653   checked_jni_SetObjectArrayElement(JNIEnv *env,
1654                                     jobjectArray array,
1655                                     jsize index,
1656                                     jobject val))
1657     functionEnter(thr);
1658     IN_VM(
1659       check_is_obj_or_inline_array(thr, array);
1660     )
1661     UNCHECKED()->SetObjectArrayElement(env,array,index,val);
1662     functionExit(thr);
1663 JNI_END
1664 
1665 #define WRAPPER_NewScalarArray(Return, Result) \
1666 JNI_ENTRY_CHECKED(Return, \
1667   checked_jni_New##Result##Array(JNIEnv *env, \
1668                                  jsize len)) \
1669     functionEnter(thr); \
1670     Return result = UNCHECKED()->New##Result##Array(env,len); \
1671     functionExit(thr); \
1672     return (Return) result; \
1673 JNI_END
1674 
1675 WRAPPER_NewScalarArray(jbooleanArray, Boolean)
1676 WRAPPER_NewScalarArray(jbyteArray, Byte)
1677 WRAPPER_NewScalarArray(jshortArray, Short)
1678 WRAPPER_NewScalarArray(jcharArray, Char)
1679 WRAPPER_NewScalarArray(jintArray, Int)

2289     checked_jni_ReleasePrimitiveArrayCritical,
2290 
2291     checked_jni_GetStringCritical,
2292     checked_jni_ReleaseStringCritical,
2293 
2294     checked_jni_NewWeakGlobalRef,
2295     checked_jni_DeleteWeakGlobalRef,
2296 
2297     checked_jni_ExceptionCheck,
2298 
2299     checked_jni_NewDirectByteBuffer,
2300     checked_jni_GetDirectBufferAddress,
2301     checked_jni_GetDirectBufferCapacity,
2302 
2303     // New 1.6 Features
2304 
2305     checked_jni_GetObjectRefType,
2306 
2307     // Module Features
2308 
2309     checked_jni_GetModule,
2310 
2311 };
2312 
2313 
2314 // Returns the function structure
2315 struct JNINativeInterface_* jni_functions_check() {
2316 
2317   unchecked_jni_NativeInterface = jni_functions_nocheck();
2318 
2319   // make sure the last pointer in the checked table is not null, indicating
2320   // an addition to the JNINativeInterface_ structure without initializing
2321   // it in the checked table.
2322   debug_only(int *lastPtr = (int *)((char *)&checked_jni_NativeInterface + \
2323              sizeof(*unchecked_jni_NativeInterface) - sizeof(char *));)
2324   assert(*lastPtr != 0,
2325          "Mismatched JNINativeInterface tables, check for new entries");
2326 
2327   // with -verbose:jni this message will print
2328   log_debug(jni, resolve)("Checked JNI functions are being used to validate JNI usage");
2329 
2330   return &checked_jni_NativeInterface;
< prev index next >