You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by gs...@apache.org on 2007/02/19 16:37:33 UTC
svn commit: r509222 - in /harmony/enhanced/drlvm/trunk/vm/vmcore:
include/Class.h include/class_member.h include/classloader.h
src/class_support/Class_File_Loader.cpp src/class_support/classloader.cpp
Author: gshimansky
Date: Mon Feb 19 07:37:32 2007
New Revision: 509222
URL: http://svn.apache.org/viewvc?view=rev&rev=509222
Log:
Applied HARMONY-3134 [drlvm][classloader] Different condition of checks for system and user classloader
Tests passed on Ubuntu6 x86, Windows 2003 server x86 and SuSE9 x86_64
Modified:
harmony/enhanced/drlvm/trunk/vm/vmcore/include/Class.h
harmony/enhanced/drlvm/trunk/vm/vmcore/include/class_member.h
harmony/enhanced/drlvm/trunk/vm/vmcore/include/classloader.h
harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Class_File_Loader.cpp
harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/classloader.cpp
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/Class.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/Class.h?view=diff&rev=509222&r1=509221&r2=509222
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/Class.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/Class.h Mon Feb 19 07:37:32 2007
@@ -630,10 +630,13 @@
* <li>Sets #CONSTANT_String entries to point directly to the
* <code>String</code> representation.
* <li>Preresolves #CONSTANT_NameAndType entries to signatures. </ul>
- * @param[in] clss - the class that the given constant pool belongs to
+ * @param[in] env - VM environment
+ * @param[in] clss - the class that the given constant pool belongs to
+ * @param[in] is_trusted_cl - defines whether class was loaded by
+ * trusted classloader. User defined classloaders are not trusted.
* @return <code>true</code> if the constant pool of clss is valid;
* otherwise <code>false</code>.*/
- bool check(Global_Env *, Class* clss);
+ bool check(Global_Env * env, Class* clss, bool is_trusted_cl);
/** Clears the constant-pool content: tags and entries arrays.*/
void clear() {
@@ -1836,18 +1839,22 @@
bool parse_interfaces(ByteReader &cfs);
/** Parses class fields from a class-file stream.
- * @param[in] env - VM enviroment
- * @param[in] cfs - a class-file stream
+ * @param[in] env - VM enviroment
+ * @param[in] cfs - a class-file stream
+ * @param[in] is_trusted_cl - defines whether class was loaded by
+ * trusted classloader. User defined classloaders are not trusted.
* @return <code>true</code> if successfully parses fields; <code>false</code>
* if any parse error occurs.*/
- bool parse_fields(Global_Env* env, ByteReader &cfs);
+ bool parse_fields(Global_Env* env, ByteReader &cfs, bool is_trusted_cl);
/** Parses class methods from a class-file stream.
- * @param[in] env - VM enviroment
- * @param[in] cfs - a class file stream
+ * @param[in] env - VM enviroment
+ * @param[in] cfs - a class file stream
+ * @param[in] is_trusted_cl - defines whether class was loaded by
+ * trusted classloader. User defined classloaders are not trusted.
* @return <code>true</code> if successfully parses methods; <code>false</code>
* if any parse error occurs.*/
- bool parse_methods(Global_Env* env, ByteReader &cfs);
+ bool parse_methods(Global_Env* env, ByteReader &cfs, bool is_trusted_cl);
/** Calculates and assigns offsets to class fields during preparation.*/
void assign_offsets_to_fields();
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/class_member.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/class_member.h?view=diff&rev=509222&r1=509221&r2=509222
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/class_member.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/class_member.h Mon Feb 19 07:37:32 2007
@@ -214,7 +214,7 @@
unsigned is_transient() {return (_access_flags&ACC_TRANSIENT);}
bool is_enum() {return (_access_flags&ACC_ENUM)?true:false;}
- bool parse(Global_Env& env, Class* clss, ByteReader& cfs);
+ bool parse(Global_Env& env, Class* clss, ByteReader& cfs, bool is_trusted_cl);
unsigned calculate_size();
@@ -637,7 +637,7 @@
bool is_fake_method() {return (_intf_method_for_fake_method != NULL);}
Method *get_real_intf_method() {return _intf_method_for_fake_method;}
- bool parse(Global_Env& env, Class* clss, ByteReader& cfs);
+ bool parse(Global_Env& env, Class* clss, ByteReader& cfs, bool is_trusted_cl);
void calculate_arguments_slot_num();
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/classloader.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/classloader.h?view=diff&rev=509222&r1=509221&r2=509222
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/classloader.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/classloader.h Mon Feb 19 07:37:32 2007
@@ -153,7 +153,7 @@
friend class GlobalClassLoaderIterator;
public:
- ClassLoader() : m_loader(NULL), m_parent(NULL), m_package_table(NULL),
+ ClassLoader() : m_loader(NULL), m_parent(NULL), m_name(NULL), m_package_table(NULL),
m_loadedClasses(NULL), m_loadingClasses(NULL), m_reportedClasses(NULL),
m_javaTypes(NULL), m_nativeLibraries(NULL), m_markBit(0),
m_unloading(false), m_fullSize(0), m_verifyData(NULL)
@@ -211,6 +211,7 @@
bool NotMarked() { return (m_markBit == 0); }
unsigned GetFullSize();
ManagedObject* GetLoader() { return m_loader; }
+ const String* GetName() { return m_name; }
ClassLoader* GetParent() { return m_parent; }
Package_Table* getPackageTable() { return m_package_table; }
ClassTable* GetLoadedClasses() { return m_loadedClasses; }
@@ -267,6 +268,7 @@
// data
ManagedObject* m_loader;
ClassLoader* m_parent;
+ const String* m_name;
Package_Table* m_package_table;
ClassTable* m_loadedClasses;
ClassTable* m_initiatedClasses;
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Class_File_Loader.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Class_File_Loader.cpp?view=diff&rev=509222&r1=509221&r2=509222
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Class_File_Loader.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Class_File_Loader.cpp Mon Feb 19 07:37:32 2007
@@ -679,7 +679,8 @@
static inline bool
check_field_descriptor( const char *descriptor,
const char **next,
- bool is_void_legal)
+ bool is_void_legal,
+ bool old_version)
{
switch (*descriptor)
{
@@ -715,7 +716,7 @@
return false;
}
if(*iterator == '/') {
- if(!check_member_name(descriptor, id_len, false, false))
+ if(!check_member_name(descriptor, id_len, old_version, false))
return false;
id_len = 0;
descriptor = iterator + 1;
@@ -723,7 +724,7 @@
id_len++;
}
}
- if(!check_member_name(descriptor, id_len, false, false))
+ if(!check_member_name(descriptor, id_len, old_version, false))
return false;
*next = iterator + 1;
return true;
@@ -734,7 +735,7 @@
unsigned dim = 1;
while(*(++descriptor) == '[') dim++;
if (dim > 255) return false;
- if(!check_field_descriptor(descriptor, next, is_void_legal ))
+ if(!check_field_descriptor(descriptor, next, is_void_legal, old_version))
return false;
return true;
}
@@ -761,24 +762,50 @@
return false;
}
+static bool
+is_trusted_classloader(const String *name) {
+ if(name == NULL) //bootstrap classloader
+ return true;
+ if(name->len < 4)
+ return false;
+ static const char* buf = "java";
+ if (0 == memcmp(name->bytes, buf, 4)) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
//checks of field and method name depend on class version
static const uint16 JAVA5_CLASS_FILE_VERSION = 49;
-bool Field::parse(Global_Env& env, Class *clss, ByteReader &cfs )
+bool Field::parse(Global_Env& env, Class *clss, ByteReader &cfs, bool is_trusted_cl)
{
if(!Class_Member::parse(clss, cfs))
return false;
- if(env.verify_all
- && !check_member_name(_name->bytes, _name->len,
- clss->get_version() < JAVA5_CLASS_FILE_VERSION, false))
- {
- REPORT_FAILED_CLASS_FORMAT(clss, "illegal field name : " << _name->bytes);
- return false;
+ //check field name
+ if(is_trusted_cl) {
+ if(env.verify_all
+ && !check_member_name(_name->bytes, _name->len,
+ clss->get_version() < JAVA5_CLASS_FILE_VERSION, false))
+ {
+ REPORT_FAILED_CLASS_FORMAT(clss, "illegal field name : " << _name->bytes);
+ return false;
+ }
+ } else {//always check field name if classloader is not trusted
+ if(!check_member_name(_name->bytes, _name->len,
+ clss->get_version() < JAVA5_CLASS_FILE_VERSION, false))
+ {
+ REPORT_FAILED_CLASS_FORMAT(clss, "illegal field name : " << _name->bytes);
+ return false;
+ }
}
// check field descriptor
//See specification 4.4.2 about field descriptors.
const char* next;
- if(!check_field_descriptor(_descriptor->bytes, &next, false) || *next != '\0') {
+ if(!check_field_descriptor(_descriptor->bytes, &next, false, clss->get_version() < JAVA5_CLASS_FILE_VERSION)
+ || *next != '\0')
+ {
REPORT_FAILED_CLASS_FORMAT(clss, "illegal field descriptor : " << _descriptor->bytes);
return false;
}
@@ -1366,7 +1393,8 @@
if(attribute == ATTR_LocalVariableTable)
{
const char *next;
- if(!check_field_descriptor(descriptor->bytes, &next, false) || *next != '\0')
+ if(!check_field_descriptor(descriptor->bytes, &next, false, _class->get_version() < JAVA5_CLASS_FILE_VERSION)
+ || *next != '\0')
{
REPORT_FAILED_METHOD("illegal field descriptor: " << descriptor->bytes <<
" in " << attr_name << " attribute for local variable: " << name->bytes);
@@ -1759,7 +1787,7 @@
} //Method::_parse_code
static inline bool
-check_method_descriptor( const char *descriptor )
+check_method_descriptor(const char *descriptor, bool old_version)
{
const char *next;
bool result;
@@ -1769,36 +1797,47 @@
next = ++descriptor;
while( descriptor[0] != ')' )
{
- result = check_field_descriptor(descriptor, &next, false);
+ result = check_field_descriptor(descriptor, &next, false, old_version);
if( !result || *next == '\0' ) {
return result;
}
descriptor = next;
}
next = ++descriptor;
- result = check_field_descriptor(descriptor, &next, true);
+ result = check_field_descriptor(descriptor, &next, true, old_version);
if( *next != '\0' ) return false;
return result;
}
bool Method::parse(Global_Env& env, Class* clss,
- ByteReader &cfs)
+ ByteReader &cfs, bool is_trusted_cl)
{
if(!Class_Member::parse(clss, cfs))
return false;
- //check name only if flag verify_all is set from command line
- if(env.verify_all && !(_name == env.Init_String || _name == env.Clinit_String))
- {
- if(!check_member_name(_name->bytes, _name->len,
- clss->get_version() < JAVA5_CLASS_FILE_VERSION, true))
+ //check method name
+ if(is_trusted_cl) {
+ if(env.verify_all && !(_name == env.Init_String || _name == env.Clinit_String))
+ {
+ if(!check_member_name(_name->bytes, _name->len,
+ clss->get_version() < JAVA5_CLASS_FILE_VERSION, true))
+ {
+ REPORT_FAILED_CLASS_FORMAT(clss, "illegal method name : " << _name->bytes);
+ return false;
+ }
+ }
+ } else {
+ if(!(_name == env.Init_String || _name == env.Clinit_String)
+ && !check_member_name(_name->bytes, _name->len,
+ clss->get_version() < JAVA5_CLASS_FILE_VERSION, true))
{
REPORT_FAILED_CLASS_FORMAT(clss, "illegal method name : " << _name->bytes);
return false;
}
}
-
// check method descriptor
- if(!check_method_descriptor(_descriptor->bytes)) {
+ if(!check_method_descriptor(_descriptor->bytes,
+ clss->get_version() < JAVA5_CLASS_FILE_VERSION))
+ {
REPORT_FAILED_CLASS_CLASS(_class->get_class_loader(), _class, "java/lang/ClassFormatError",
_class->get_name()->bytes << ": invalid descriptor "
"while parsing method "
@@ -2178,7 +2217,7 @@
} //Method::parse
-bool Class::parse_fields(Global_Env* env, ByteReader& cfs)
+bool Class::parse_fields(Global_Env* env, ByteReader& cfs, bool is_trusted_cl)
{
// Those fields are added by the loader even though they are nor defined
// in their corresponding class files.
@@ -2219,7 +2258,7 @@
unsigned short last_nonstatic_field = (unsigned short)num_fields_in_class_file;
for(i=0; i < num_fields_in_class_file; i++) {
Field fd;
- if(!fd.parse(*env, this, cfs))
+ if(!fd.parse(*env, this, cfs, is_trusted_cl))
return false;
if(fd.is_static()) {
m_fields[m_num_static_fields] = fd;
@@ -2270,7 +2309,7 @@
long _total_method_bytes = 0;
-bool Class::parse_methods(Global_Env* env, ByteReader &cfs)
+bool Class::parse_methods(Global_Env* env, ByteReader &cfs, bool is_trusted_cl)
{
if(!cfs.parse_u2_be(&m_num_methods)) {
REPORT_FAILED_CLASS_CLASS(m_class_loader, this, "java/lang/ClassFormatError",
@@ -2284,7 +2323,7 @@
_total_method_bytes += sizeof(Method)*m_num_methods;
for(unsigned i = 0; i < m_num_methods; i++) {
- if(!m_methods[i].parse(*env, this, cfs)) {
+ if(!m_methods[i].parse(*env, this, cfs, is_trusted_cl)) {
return false;
}
@@ -2325,7 +2364,7 @@
} //class_parse_methods
static inline bool
-check_class_name(const char *name, unsigned len)
+check_class_name(const char *name, unsigned len, bool old_version)
{
if(len == 0)
return false;
@@ -2334,7 +2373,7 @@
if(name[0] == '[')
{
const char *next = name + 1;
- if(!check_field_descriptor(name, &next, false) || *next != '\0') {
+ if(!check_field_descriptor(name, &next, false, old_version) || *next != '\0') {
return false;
} else {
return true;
@@ -2345,14 +2384,14 @@
if(*iterator != '/') {
id_len++;
} else {
- if(!check_member_name(name, id_len, false, false))
+ if(!check_member_name(name, id_len, old_version, false))
return false;
id_len = 0;
name = iterator;
name++;
}
}
- return check_member_name(name, id_len, false, false);
+ return check_member_name(name, id_len, old_version, false);
}
return false; //unreachable code
}
@@ -2557,7 +2596,7 @@
} // ConstantPool::parse
-bool ConstantPool::check(Global_Env* env, Class* clss)
+bool ConstantPool::check(Global_Env* env, Class* clss, bool is_trusted_cl)
{
for(unsigned i = 1; i < m_size; i++) {
switch(unsigned char tag = get_tag(i))
@@ -2569,7 +2608,9 @@
// illegal name index
return false;
}
- if(env->verify_all && !check_class_name(get_utf8_string(name_index)->bytes, get_utf8_string(name_index)->len))
+ if(env->verify_all
+ && !check_class_name(get_utf8_string(name_index)->bytes, get_utf8_string(name_index)->len,
+ clss->get_version() < JAVA5_CLASS_FILE_VERSION))
{
REPORT_FAILED_CLASS_CLASS(clss->get_class_loader(), clss, "java/lang/ClassFormatError",
clss->get_name()->bytes << ": illegal CONSTANT_Class name "
@@ -2608,15 +2649,25 @@
if(tag == CONSTANT_Methodref)
{
//check method name
- if(env->verify_all && (name != env->Init_String)
- && !check_member_name(name->bytes,name->len, clss->get_version() < JAVA5_CLASS_FILE_VERSION, true))
- {
+ if(is_trusted_cl) {
+ if(env->verify_all && (name != env->Init_String)
+ && !check_member_name(name->bytes,name->len, clss->get_version() < JAVA5_CLASS_FILE_VERSION, true))
+ {
REPORT_FAILED_CLASS_CLASS(clss->get_class_loader(), clss, "java/lang/ClassFormatError",
- clss->get_name()->bytes << ": illegal method name for CONSTANT_Methodref entry: " << name->bytes);
+ clss->get_name()->bytes << ": illegal method name for CONSTANT_Methodref entry: " << name->bytes);
return false;
+ }
+ } else { //always check method name if classloader is not system
+ if((name != env->Init_String)
+ && !check_member_name(name->bytes,name->len, clss->get_version() < JAVA5_CLASS_FILE_VERSION, true))
+ {
+ REPORT_FAILED_CLASS_CLASS(clss->get_class_loader(), clss, "java/lang/ClassFormatError",
+ clss->get_name()->bytes << ": illegal method name for CONSTANT_Methodref entry: " << name->bytes);
+ return false;
+ }
}
//check method descriptor
- if(!check_method_descriptor(descriptor->bytes))
+ if(!check_method_descriptor(descriptor->bytes, clss->get_version() < JAVA5_CLASS_FILE_VERSION))
{
REPORT_FAILED_CLASS_CLASS(clss->get_class_loader(), clss, "java/lang/ClassFormatError",
clss->get_name()->bytes << ": illegal method descriptor at CONSTANT_Methodref entry: "
@@ -2639,15 +2690,27 @@
if(tag == CONSTANT_Fieldref)
{
//check field name
- if(env->verify_all && !check_member_name(name->bytes, name->len,
- clss->get_version() < JAVA5_CLASS_FILE_VERSION, false))
- {
- REPORT_FAILED_CLASS_CLASS(clss->get_class_loader(), clss, "java/lang/ClassFormatError",
- clss->get_name()->bytes << ": illegal field name for CONSTANT_Filedref entry: " << name->bytes);
- return false;
+ if(is_trusted_cl) {
+ if(env->verify_all && !check_member_name(name->bytes, name->len,
+ clss->get_version() < JAVA5_CLASS_FILE_VERSION, false))
+ {
+ REPORT_FAILED_CLASS_CLASS(clss->get_class_loader(), clss, "java/lang/ClassFormatError",
+ clss->get_name()->bytes << ": illegal field name for CONSTANT_Filedref entry: " << name->bytes);
+ return false;
+ }
+ } else {
+ if(!check_member_name(name->bytes, name->len,
+ clss->get_version() < JAVA5_CLASS_FILE_VERSION, false))
+ {
+ REPORT_FAILED_CLASS_CLASS(clss->get_class_loader(), clss, "java/lang/ClassFormatError",
+ clss->get_name()->bytes << ": illegal field name for CONSTANT_Filedref entry: " << name->bytes);
+ return false;
+ }
+
}
//check field descriptor
- if(!check_field_descriptor(descriptor->bytes, &next, false) || *next != '\0' )
+ if(!check_field_descriptor(descriptor->bytes, &next, false,
+ clss->get_version() < JAVA5_CLASS_FILE_VERSION) || *next != '\0' )
{
REPORT_FAILED_CLASS_CLASS(clss->get_class_loader(), clss, "java/lang/ClassFormatError",
clss->get_name()->bytes << ": illegal field descriptor at CONSTANT_Fieldref entry: " << descriptor->bytes);
@@ -2656,17 +2719,28 @@
}
if(tag == CONSTANT_InterfaceMethodref)
{
- //check method name, name can't be <init> or <clinit>
+ //check method name, name can't be <init>
//See specification 4.5.2 about name_and_type_index last sentence.
- if(!check_member_name(name->bytes, name->len,
- clss->get_version() < JAVA5_CLASS_FILE_VERSION, true))
- {
- REPORT_FAILED_CLASS_CLASS(clss->get_class_loader(), clss, "java/lang/ClassFormatError",
- clss->get_name()->bytes << ": illegal field name for CONSTANT_InterfaceMethod entry: " << name->bytes);
- return false;
+ if(is_trusted_cl) {
+ if(env->verify_all && (name != env->Clinit_String)
+ && !check_member_name(name->bytes, name->len,
+ clss->get_version() < JAVA5_CLASS_FILE_VERSION, true))
+ {
+ REPORT_FAILED_CLASS_CLASS(clss->get_class_loader(), clss, "java/lang/ClassFormatError",
+ clss->get_name()->bytes << ": illegal method name for CONSTANT_InterfaceMethod entry: " << name->bytes);
+ return false;
+ }
+ } else {
+ if(!check_member_name(name->bytes, name->len,
+ clss->get_version() < JAVA5_CLASS_FILE_VERSION, true))
+ {
+ REPORT_FAILED_CLASS_CLASS(clss->get_class_loader(), clss, "java/lang/ClassFormatError",
+ clss->get_name()->bytes << ": illegal method name for CONSTANT_InterfaceMethod entry: " << name->bytes);
+ return false;
+ }
}
//check method descriptor
- if(!check_method_descriptor(descriptor->bytes))
+ if(!check_method_descriptor(descriptor->bytes, clss->get_version() < JAVA5_CLASS_FILE_VERSION))
{
REPORT_FAILED_CLASS_CLASS(clss->get_class_loader(), clss, "java/lang/ClassFormatError",
clss->get_name()->bytes << ": illegal method descriptor at CONSTANT_InterfaceMethodref entry: " << descriptor->bytes);
@@ -2797,6 +2871,12 @@
ByteReader& cfs)
{
/*
+ * find out if classloader is system or user defined
+ */
+ bool is_trusted_cl = is_trusted_classloader(m_class_loader->GetName());
+ TRACE2("classloader.name", "classloader_name: " << m_class_loader->GetName() << " is trusted: " << is_trusted_cl);
+
+ /*
* get and check magic number (Oxcafebabe)
*/
uint32 magic;
@@ -2854,7 +2934,7 @@
/*
* check and preprocess the constant pool
*/
- if(!m_const_pool.check(env, this))
+ if(!m_const_pool.check(env, this, is_trusted_cl))
return false;
/*
@@ -2997,13 +3077,13 @@
/*
* allocate and parse class' fields
*/
- if(!parse_fields(env, cfs))
+ if(!parse_fields(env, cfs, is_trusted_cl))
return false;
/*
* allocate and parse class' methods
*/
- if(!parse_methods(env, cfs))
+ if(!parse_methods(env, cfs, is_trusted_cl))
return false;
/*
* parse attributes
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/classloader.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/classloader.cpp?view=diff&rev=509222&r1=509221&r2=509222
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/classloader.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/classloader.cpp Mon Feb 19 07:37:32 2007
@@ -67,6 +67,9 @@
bool ClassLoader::Initialize( ManagedObject* loader )
{
m_loader = loader;
+ if(m_loader != NULL) {
+ m_name = m_loader->vt()->clss->get_name();
+ }
if(!(m_package_table = new Package_Table())){
return false;
}