diff src/share/vm/runtime/javaCalls.cpp @ 465:dc16daa0329d

6739363: Xcheck jni doesn't check native function arguments Summary: Fix adds support for verifying arguments with -Xcheck:jni. Reviewed-by: coleenp
author poonam
date Thu, 04 Dec 2008 17:29:56 -0800
parents a61af66fc99e
children ad8c8ca4ab0f c6065343356f
line wrap: on
line diff
--- a/src/share/vm/runtime/javaCalls.cpp	Fri Oct 31 10:34:20 2008 -0700
+++ b/src/share/vm/runtime/javaCalls.cpp	Thu Dec 04 17:29:56 2008 -0800
@@ -309,8 +309,12 @@
 
   CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
 
-  // Make sure that the arguments have the right type
-  debug_only(args->verify(method, result->get_type(), thread));
+  // Verify the arguments
+
+  if (CheckJNICalls)  {
+    args->verify(method, result->get_type(), thread);
+  }
+  else debug_only(args->verify(method, result->get_type(), thread));
 
   // Ignore call if method is empty
   if (method->is_empty_method()) {
@@ -431,24 +435,26 @@
   return TaggedStackInterpreter ? _parameters : _value;
 }
 
-//--------------------------------------------------------------------------------------
-// Non-Product code
-#ifndef PRODUCT
 
 class SignatureChekker : public SignatureIterator {
  private:
    bool *_is_oop;
    int   _pos;
    BasicType _return_type;
+   intptr_t*   _value;
+   Thread* _thread;
 
  public:
   bool _is_return;
 
-  SignatureChekker(symbolHandle signature, BasicType return_type, bool is_static, bool* is_oop) : SignatureIterator(signature) {
+  SignatureChekker(symbolHandle signature, BasicType return_type, bool is_static, bool* is_oop, intptr_t* value, Thread* thread) : SignatureIterator(signature) {
     _is_oop = is_oop;
     _is_return = false;
     _return_type = return_type;
     _pos = 0;
+    _value = value;
+    _thread = thread;
+
     if (!is_static) {
       check_value(true); // Receiver must be an oop
     }
@@ -489,6 +495,24 @@
       check_return_type(t);
       return;
     }
+
+    // verify handle and the oop pointed to by handle
+    int p = _pos;
+    bool bad = false;
+    // If argument is oop
+    if (_is_oop[p]) {
+      intptr_t v = _value[p];
+      if (v != 0 ) {
+        size_t t = (size_t)v;
+        bad = (t < (size_t)os::vm_page_size() ) || !(*(oop*)v)->is_oop_or_null(true);
+        if (CheckJNICalls && bad) {
+          ReportJNIFatalError((JavaThread*)_thread, "Bad JNI oop argument");
+        }
+      }
+      // for the regular debug case.
+      assert(!bad, "Bad JNI oop argument");
+    }
+
     check_value(true);
   }
 
@@ -505,6 +529,7 @@
   void do_array(int begin, int end)    { check_obj(T_OBJECT);        }
 };
 
+
 void JavaCallArguments::verify(methodHandle method, BasicType return_type,
   Thread *thread) {
   guarantee(method->size_of_parameters() == size_of_parameters(), "wrong no. of arguments pushed");
@@ -515,10 +540,9 @@
   // Check that oop information is correct
   symbolHandle signature (thread,  method->signature());
 
-  SignatureChekker sc(signature, return_type, method->is_static(),_is_oop);
+  SignatureChekker sc(signature, return_type, method->is_static(),_is_oop, _value, thread);
   sc.iterate_parameters();
   sc.check_doing_return(true);
   sc.iterate_returntype();
 }
 
-#endif // PRODUCT