verifycode.c

来自「This is a resource based on j2me embedde」· C语言 代码 · 共 1,993 行 · 第 1/5 页

C
1,993
字号
/* * @(#)verifycode.c	1.165 06/10/10 * * Copyright  1990-2008 Sun Microsystems, Inc. All Rights Reserved.   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER   *    * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License version   * 2 only, as published by the Free Software Foundation.    *    * This program is distributed in the hope that it will be useful, but   * WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   * General Public License version 2 for more details (a copy is   * included at /legal/license.txt).    *    * You should have received a copy of the GNU General Public License   * version 2 along with this work; if not, write to the Free Software   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA   * 02110-1301 USA    *    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa   * Clara, CA 95054 or visit www.sun.com if you need additional   * information or have any questions.  * */ /*- *      Verify that the code within a method block doesn't exploit any  *      security holes. *//*   Exported function:   jboolean    VerifyClass(CVMExecEnv*, CVMClassBlock *cb, char *message_buffer,               jint buffer_length) */#ifdef CVM_CLASSLOADING#ifndef CVM_TRUSTED_CLASSLOADERS	#include "javavm/include/clib.h"#include "javavm/include/porting/ansi/setjmp.h"#include "javavm/include/porting/ansi/limits.h"#include "javavm/include/indirectmem.h"#include "jni.h"#include "jvm.h"#include "javavm/include/verify_impl.h"#include "javavm/include/verify.h"#include "javavm/include/globals.h"#include "javavm/include/opcodes.h"#include "opcodes.in_out"#ifdef __cplusplus#define this XthisX#define new XnewX#define class XclassX#define protected XprotectedX#endifstatic const unsigned char *JVM_GetMethodByteCode(CVMMethodBlock* mb){    CVMJavaMethodDescriptor* jmd = CVMmbJmd(mb);    if (jmd == NULL) {	return NULL;    } else {	return CVMmbJavaCode(mb);    }}static jintJVM_GetMethodByteCodeLength(CVMMethodBlock* mb){    CVMJavaMethodDescriptor* jmd = CVMmbJmd(mb);    if (jmd == NULL) {	return 0;    } else {	return CVMjmdCodeLength(jmd);    }}static CVMExceptionHandler *JVM_GetMethodExceptionTableEntry(CVMMethodBlock* mb, jint entry_index){    CVMJavaMethodDescriptor* jmd = CVMmbJmd(mb);    return CVMjmdExceptionTable(jmd) + entry_index;}static jintJVM_GetMethodExceptionTableLength(CVMMethodBlock* mb){    CVMJavaMethodDescriptor* jmd = CVMmbJmd(mb);    if (jmd == NULL) {	return 0;    } else {	return CVMjmdExceptionTableLength(jmd);    }}static jintJVM_GetMethodLocalsCount(CVMMethodBlock* mb){    CVMJavaMethodDescriptor* jmd = CVMmbJmd(mb);     if (jmd == NULL) {	return 0;    } else {	return CVMjmdMaxLocals(jmd);    }}#ifdef CVM_TRACEstatic CVMFieldTypeIDJVM_GetCPFieldName(CVMConstantPool* cp, jint cp_index){    CVMUint16 typeIDIdx = CVMcpGetMemberRefTypeIDIdx(cp, cp_index);    return CVMcpGetFieldTypeID(cp, typeIDIdx);}#endifstatic CVMMethodTypeIDJVM_GetCPMethodName(CVMConstantPool* cp, jint cp_index){    CVMUint16 typeIDIdx = CVMcpGetMemberRefTypeIDIdx(cp, cp_index);    return CVMcpGetMethodTypeID(cp, typeIDIdx);}static CVMClassTypeIDJVM_GetCPFieldSignature(CVMConstantPool* cp, jint cp_index){    CVMUint16 typeIDIdx = CVMcpGetMemberRefTypeIDIdx(cp, cp_index);    return CVMtypeidGetType(CVMcpGetFieldTypeID(cp, typeIDIdx));}static CVMMethodTypeIDJVM_GetCPMethodSignature(CVMConstantPool* cp, jint cp_index){    CVMUint16 typeIDIdx = CVMcpGetMemberRefTypeIDIdx(cp, cp_index);    return CVMcpGetMethodTypeID(cp, typeIDIdx);}static CVMClassTypeIDJVM_GetCPClassName(CVMExecEnv* ee, CVMConstantPool* cp, jint classIdx){    CVMClassTypeID classID;    if (CVMcpTypeIs(cp, classIdx, ClassBlock)) {	classID = CVMcbClassName(CVMcpGetCb(cp, classIdx));    } else {	CVMcpLock(ee);	if (CVMcpTypeIs(cp, classIdx, ClassBlock)) {	    classID = CVMcbClassName(CVMcpGetCb(cp, classIdx));	} else {	    classID = CVMcpGetClassTypeID(cp, classIdx);	}	CVMcpUnlock(ee);    }    return classID;}static CVMClassTypeIDJVM_GetCPFieldClassName(CVMExecEnv* ee, CVMConstantPool* cp, jint cp_index){    CVMUint16 classIdx = CVMcpGetMemberRefClassIdx(cp, cp_index);    return JVM_GetCPClassName(ee, cp, classIdx);}static CVMClassTypeIDJVM_GetCPMethodClassName(CVMExecEnv* ee, CVMConstantPool* cp, jint cp_index){    CVMUint16 classIdx = CVMcpGetMemberRefClassIdx(cp, cp_index);    return JVM_GetCPClassName(ee, cp, classIdx);}static jintJVM_GetCPFieldModifiers(CVMConstantPool* cp, int cp_index, 			CVMClassBlock *cbCalled){    CVMUint16 typeIDIdx = CVMcpGetMemberRefTypeIDIdx(cp, cp_index);    CVMFieldTypeID typeID = CVMcpGetFieldTypeID(cp, typeIDIdx);    int i;    for (i = 0; i < CVMcbFieldCount(cbCalled); i++) {	CVMFieldBlock* fb = CVMcbFieldSlot(cbCalled, i);	if (CVMtypeidIsSame(CVMfbNameAndTypeID(fb), typeID)) {	    return CVMfbAccessFlags(fb);	}    }    return -1;}    static jintJVM_GetCPMethodModifiers(CVMConstantPool* cp, int cp_index,			 CVMClassBlock *cbCalled){    CVMUint16 typeIDIdx = CVMcpGetMemberRefTypeIDIdx(cp, cp_index);    CVMMethodTypeID typeID = CVMcpGetMethodTypeID(cp, typeIDIdx);    int i;    for (i = 0; i < CVMcbMethodCount(cbCalled); i++) {	CVMMethodBlock* mb = CVMcbMethodSlot(cbCalled, i);	if (CVMtypeidIsSame(CVMmbNameAndTypeID(mb), typeID)) {	    return CVMmbAccessFlags(mb);	}    }    return -1;}typedef CVMOpcode opcode_type;#define MAX_ARRAY_DIMENSIONS 255/* align byte code */#ifndef ALIGN_UP#define ALIGN_UP(n,align_grain) (((n) + ((align_grain) - 1)) & ~((align_grain)-1))#endif /* ALIGN_UP *//*  * Casts from pointer types to scalar types have to * be casts to the type CVMAddr which is 4 byte on * 32 bit platforms and 8 byte on 64 bit platforms. */#define UCALIGN(n) ((unsigned char *)ALIGN_UP((CVMAddr)(n),sizeof(int)))#ifdef CVM_TRACE#define verify_verbose (CVMcheckDebugFlags(CVM_DEBUGFLAG(TRACE_VERIFIER)) != 0)#endif/* * an analyzed instruction's stack size and register count are initially unknown. */#define UNKNOWN_STACK_SIZE -1#define UNKNOWN_REGISTER_COUNT -1/* * The first time we encounter a jsr instruction, we set its operand2 field to the * following. Thereafter we use the instruction index of the ret instruction * corresponding to it. This helps us analyze flow and enforce the * correspondence between subroutines and ret instructions. */#define UNKNOWN_RET_INSTRUCTION -1#undef MAX#undef MIN #define MAX(a, b) ((a) > (b) ? (a) : (b))#define MIN(a, b) ((a) < (b) ? (a) : (b))#define BITS_PER_INT   (CHAR_BIT * sizeof(int)/sizeof(char))#define SET_BIT(flags, i)  (flags[(i)/BITS_PER_INT] |= \			               ((unsigned)1 << ((i) % BITS_PER_INT)))#define	IS_BIT_SET(flags, i) (flags[(i)/BITS_PER_INT] & \			               ((unsigned)1 << ((i) % BITS_PER_INT)))typedef unsigned int *bitvector;/* opc_invokespecial calls to <init> need to be treated special */#define opc_invokeinit ((CVMOpcode)0x100)/* A hash mechanism used by the verifier. * Maps class names to unique 16 bit integers. * This is very similar to the classic VM's string intern table. * The good thing about this one is that it is part of the context * so requires less management when we're done. */#define HASH_TABLE_SIZE 503/* The buckets are managed as a 256 by 256 matrix. We allocate an entire * row (256 buckets) at a time to minimize fragmentation. Rows are  * allocated on demand so that we don't waste too much space. */ #define MAX_HASH_ENTRIES 65536#define HASH_ROW_SIZE 256typedef struct hash_bucket_type {    CVMClassTypeID name;  /* also used as the hash */    CVMClassBlock* class;    unsigned short next;    unsigned loadable:1;  /* from context->class loader */} hash_bucket_type;typedef struct {    hash_bucket_type **buckets;    unsigned short *table;    int entries_used;} hash_table_type;#define GET_BUCKET(class_hash, ID)\    (class_hash->buckets[ID / HASH_ROW_SIZE] + ID % HASH_ROW_SIZE)#undef CVM_VERIFY_OPERAND_BUF_SIZE /* operand buffer size used in pop_stack */#define CVM_VERIFY_OPERAND_BUF_SIZE 257#undef CVM_VERIFY_TYPE_BUF_SIZE    /* type buffer size used in pop_stack */#define CVM_VERIFY_TYPE_BUF_SIZE 256/* The context type encapsulates the current invocation of the byte * code verifier. This permits simultaneous invocation of it in multiple threads. */struct context_type {    CVMExecEnv *ee;             /* current CVMExecEnv */    /* buffers etc. */    char stack_operand_buffer[CVM_VERIFY_OPERAND_BUF_SIZE];    fullinfo_type stack_info_buffer[CVM_VERIFY_TYPE_BUF_SIZE];    char *message;    jint message_buf_len;    /* these fields are per class */    CVMClassBlock *class;		/* current class */    CVMUint16 nconstants;    CVMConstantPool *constant_pool;    hash_table_type class_hash;    fullinfo_type object_info;	/* fullinfo for java/lang/Object */    fullinfo_type string_info;	/* fullinfo for java/lang/String */    fullinfo_type class_info;	/* fullinfo for java/lang/Class */    fullinfo_type throwable_info; /* fullinfo for java/lang/Throwable */    fullinfo_type cloneable_info; /* fullinfo for java/lang/Cloneable */    fullinfo_type serializable_info; /* fullinfo for java/io/Serializable */    fullinfo_type currentclass_info; /* fullinfo for context->class */    fullinfo_type superclass_info;   /* fullinfo for superclass */    /* these fields are per method */    CVMMethodBlock *mb;	        /* current method */    const unsigned char *code;	/* current code object */    jint code_length;    int *code_data;		/* offset to instruction number */    struct instruction_data_type *instruction_data; /* info about each */    struct handler_info_type *handler_info;    fullinfo_type *superclasses; /* null terminated superclasses */    int instruction_count;	/* number of instructions */    fullinfo_type return_type;	/* function return type */    fullinfo_type swap_table[4]; /* used for passing information */    int bitmask_size;		/* words needed to hold bitmap of arguments */    CVMBool	method_has_jsr;    CVMBool	method_has_switch;#if 0 /* See comment in verify_field(). */    /* these fields are per field */    CVMFieldBlock *fb;#endif    /* Used by the space allocator */    struct CCpool *CCroot, *CCcurrent;    char *CCfree_ptr;    int CCfree_size;    /* Jump here on any error. */    jmp_buf jump_buffer;    /* Class file version we are checking against */    int major_version;};/* * The state of the stack is a linked list of stack_item_type. * The first item is the stack top: lower items are found by * following the next pointer. To pop an item from the stack * is to replace the "stack" pointer by stack->next and decrement * stack_size. To push an item, use *	stack_item_type *stack_item = NEW(stack_item_type, 1); *	stack_item->next = s->stack; *	s->stack = stack_item; *	s->stack_size++; * obviously, see stack_item_type below. */struct stack_info_type {    struct stack_item_type *stack;    int stack_size;};/* * For each of the register_count registers we know about at this point, * a fullinfo_type gives what we know about the content. See above, * especially ITEM_ReturnAddress. * There is also an array of mask_count mask bitsets. Frequently * mask_count == 0. The sets must be at least register_count long. * The registers information, as well as the masks information, is * modified at every store into a local "register." * See mask_type. */struct register_info_type {    int register_count;		/* number of registers used */    fullinfo_type *registers;    int mask_count;		/* number of masks in the following */    struct mask_type *masks;};/* * For most instructions, there are multiple code paths from the beginning of the * method to the start of the instruction. For code paths which can be * reached by way of a jsr (and are thus part of a subroutine as defined by a jsr/ret pair), * we keep a bit mask of registers modified (by store instruction) during the subroutine. * This helps us merge state information from the ret back to the instruction after the jsr.

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?