Author: kumpera
Date: 2008-01-11 10:37:33 -0500 (Fri, 11 Jan 2008)
New Revision: 92674

Modified:
   trunk/mono/mono/metadata/ChangeLog
   trunk/mono/mono/metadata/verify.c
Log:
2008-01-11  Rodrigo Kumpera  <[EMAIL PROTECTED]>

        * verify.c (get_boxable_mono_type): check if the token is valid.

        * verify.c (set_stack_value): changed to add an error if an
        invalid type is set on stack. Changed all callers due to signature 
change.

        * verify.c (do_stobj): implement stobj validation.



Modified: trunk/mono/mono/metadata/ChangeLog
===================================================================
--- trunk/mono/mono/metadata/ChangeLog  2008-01-11 15:37:14 UTC (rev 92673)
+++ trunk/mono/mono/metadata/ChangeLog  2008-01-11 15:37:33 UTC (rev 92674)
@@ -1,3 +1,12 @@
+2008-01-11  Rodrigo Kumpera  <[EMAIL PROTECTED]>
+
+       * verify.c (get_boxable_mono_type): check if the token is valid.
+
+       * verify.c (set_stack_value): changed to add an error if an
+       invalid type is set on stack. Changed all callers due to signature 
change.
+
+       * verify.c (do_stobj): implement stobj validation.
+
 2008-01-11  Zoltan Varga  <[EMAIL PROTECTED]>
 
        * reflection.c (reflection_methodbuilder_to_mono_method): No need to

Modified: trunk/mono/mono/metadata/verify.c
===================================================================
--- trunk/mono/mono/metadata/verify.c   2008-01-11 15:37:14 UTC (rev 92673)
+++ trunk/mono/mono/metadata/verify.c   2008-01-11 15:37:33 UTC (rev 92674)
@@ -199,7 +199,11 @@
 #define IS_METHOD_DEF(token) (mono_metadata_token_table (token) == 
MONO_TABLE_METHOD)
 #define IS_METHOD_SPEC(token) (mono_metadata_token_table (token) == 
MONO_TABLE_METHODSPEC)
 
+#define IS_TYPE_REF(token) (mono_metadata_token_table (token) == 
MONO_TABLE_TYPEREF)
+#define IS_TYPE_DEF(token) (mono_metadata_token_table (token) == 
MONO_TABLE_TYPEDEF)
+#define IS_TYPE_SPEC(token) (mono_metadata_token_table (token) == 
MONO_TABLE_TYPESPEC)
 #define IS_METHOD_DEF_OR_REF_OR_SPEC(token) (IS_METHOD_DEF (token) || 
IS_MEMBER_REF (token) || IS_METHOD_SPEC (token))
+#define IS_TYPE_DEF_OR_REF_OR_SPEC(token) (IS_TYPE_DEF (token) || IS_TYPE_REF 
(token) || IS_TYPE_SPEC (token))
 
 /*
  * Verify if @token refers to a valid row on int's table.
@@ -1339,7 +1343,13 @@
 static MonoType*
 get_boxable_mono_type (VerifyContext* ctx, int token)
 {
-       MonoType *type = mono_type_get_full (ctx->image, token, 
ctx->generic_context);
+       MonoType *type;
+       if (!IS_TYPE_DEF_OR_REF_OR_SPEC (token) || !token_bounds_check 
(ctx->image, token)) {
+               ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Invalid type token %x 
at 0x%04x", token, ctx->ip_offset));
+               return NULL;
+       }
+       
+       type = mono_type_get_full (ctx->image, token, ctx->generic_context);
 
        if (!type) {
                ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Type (0x%08x) not 
found at 0x%04x", token, ctx->ip_offset));
@@ -1618,8 +1628,8 @@
 }
 
 /* convert MonoType to ILStackDesc format (stype) */
-static void
-set_stack_value (ILStackDesc *stack, MonoType *type, int take_addr)
+static gboolean
+set_stack_value (VerifyContext *ctx, ILStackDesc *stack, MonoType *type, int 
take_addr)
 {
        int mask = 0;
        int type_kind = type->type;
@@ -1641,18 +1651,18 @@
        case MONO_TYPE_I4:
        case MONO_TYPE_U4:
                stack->stype = TYPE_I4 | mask;
-               return;
+               break;
        case MONO_TYPE_I:
        case MONO_TYPE_U:
                stack->stype = TYPE_NATIVE_INT | mask;
-               return;
+               break;
 
        /*FIXME: Do we need to check if it's a pointer to the method pointer? 
The spec says it' illegal to have that.*/
        case MONO_TYPE_FNPTR:
        case MONO_TYPE_PTR:
        case MONO_TYPE_TYPEDBYREF:
                stack->stype = TYPE_PTR | mask;
-               return;
+               break;
 
        case MONO_TYPE_CLASS:
        case MONO_TYPE_STRING:
@@ -1664,15 +1674,15 @@
        case MONO_TYPE_VAR:
        case MONO_TYPE_MVAR: 
                stack->stype = TYPE_COMPLEX | mask;
-               return;
+               break;
        case MONO_TYPE_I8:
        case MONO_TYPE_U8:
                stack->stype = TYPE_I8 | mask;
-               return;
+               break;
        case MONO_TYPE_R4:
        case MONO_TYPE_R8:
                stack->stype = TYPE_R8 | mask;
-               return;
+               break;
        case MONO_TYPE_VALUETYPE:
                if (type->data.klass->enumtype) {
                        type = type->data.klass->enum_basetype;
@@ -1680,13 +1690,14 @@
                        goto handle_enum;
                } else {
                        stack->stype = TYPE_COMPLEX | mask;
-                       return;
+                       break;
                }
        default:
                VERIFIER_DEBUG ( printf ("unknown type 0x%02x in eval stack 
type\n", type->type); );
-               g_assert_not_reached ();
+               ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Illegal value set on 
stack 0x%02x at %d", type->type, ctx->ip_offset));
+               return FALSE;
        }
-       return;
+       return TRUE;
 }
 
 /* 
@@ -1699,7 +1710,7 @@
 init_stack_with_value_at_exception_boundary (VerifyContext *ctx, ILCodeDesc 
*code, MonoClass *klass)
 {
        stack_init (ctx, code);
-       set_stack_value (code->stack, &klass->byval_arg, FALSE);
+       set_stack_value (ctx, code->stack, &klass->byval_arg, FALSE);
        code->size = 1;
        code->flags |= IL_CODE_FLAG_WAS_TARGET;
 }
@@ -2176,10 +2187,12 @@
                check_unverifiable_type (ctx, ctx->params [arg]);
                if (ctx->params [arg]->byref && take_addr)
                        CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("ByRef of 
ByRef at 0x%04x", ctx->ip_offset));
-               set_stack_value (stack_push (ctx), ctx->params [arg], 
take_addr);
+               if (!set_stack_value (ctx, stack_push (ctx), ctx->params [arg], 
take_addr))
+                       return;
+
+               if (arg == 0 && !take_addr && !(ctx->method->flags & 
METHOD_ATTRIBUTE_STATIC))
+                       stack_top (ctx)->stype |= THIS_POINTER_MASK;
        } 
-       if (arg == 0 && !take_addr && !(ctx->method->flags & 
METHOD_ATTRIBUTE_STATIC))
-               stack_top (ctx)->stype |= THIS_POINTER_MASK;
 }
 
 static void
@@ -2193,7 +2206,7 @@
                if (ctx->locals [arg]->byref && take_addr)
                        CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("ByRef of 
ByRef at 0x%04x", ctx->ip_offset));
 
-               set_stack_value (stack_push (ctx), ctx->locals [arg], 
take_addr);
+               set_stack_value (ctx, stack_push (ctx), ctx->locals [arg], 
take_addr);
        } 
 }
 
@@ -2502,7 +2515,7 @@
 
        if (sig->ret->type != MONO_TYPE_VOID) {
                if (check_overflow (ctx))
-                       set_stack_value (stack_push (ctx), sig->ret, FALSE);
+                       set_stack_value (ctx, stack_push (ctx), sig->ret, 
FALSE);
        }
 
        if (sig->ret->type == MONO_TYPE_TYPEDBYREF
@@ -2535,7 +2548,7 @@
        if (!mono_method_can_access_field (ctx->method, field))
                CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Type at stack is 
not accessible at 0x%04x", ctx->ip_offset));
 
-       set_stack_value (stack_push (ctx), field->type, take_addr);
+       set_stack_value (ctx, stack_push (ctx), field->type, take_addr);
 }
 
 static void
@@ -2646,7 +2659,7 @@
                !(field->parent == ctx->method->klass && 
mono_method_is_constructor (ctx->method)))
                CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Cannot take the 
address of a init-only field at 0x%04x", ctx->ip_offset));
 
-       set_stack_value (stack_push (ctx), field->type, take_addr);
+       set_stack_value (ctx, stack_push (ctx), field->type, take_addr);
 }
 
 static void
@@ -2720,7 +2733,7 @@
                CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid type %s at 
stack for unbox operation at 0x%04x", stack_slot_get_name (value), 
ctx->ip_offset));
 
        //TODO Pushed managed pointer is controled mutability (CMMP) 
-       set_stack_value (stack_push (ctx), mono_type_get_type_byref (type), 
FALSE);
+       set_stack_value (ctx, stack_push (ctx), mono_type_get_type_byref 
(type), FALSE);
 }
 
 static void
@@ -2742,7 +2755,7 @@
                (stack_slot_is_boxed_value (value) || 
!mono_class_from_mono_type (value->type)->valuetype)))
                CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid type %s at 
stack for unbox.any operation at 0x%04x", stack_slot_get_name (value), 
ctx->ip_offset));
  
-       set_stack_value (stack_push (ctx), type, FALSE);
+       set_stack_value (ctx, stack_push (ctx), type, FALSE);
 }
 
 static void
@@ -2847,13 +2860,36 @@
        if (!verify_type_compatibility_full (ctx, type, 
mono_type_get_type_byval (value->type), TRUE))
                CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid type at 
stack for ldojb operation at 0x%04x", ctx->ip_offset));
 
-       set_stack_value (stack_push (ctx), type, FALSE);
+       set_stack_value (ctx, stack_push (ctx), type, FALSE);
 }
 
-/* TODO implement delegate verification
- * TODO implement access verification
- */
+static void
+do_stobj (VerifyContext *ctx, int token) 
+{
+       ILStackDesc *dest, *src;
+       MonoType *type = get_boxable_mono_type (ctx, token);
+       if (!type)
+               return;
 
+       if (!check_underflow (ctx, 2))
+               return;
+
+       src = stack_pop (ctx);
+       dest = stack_pop (ctx);
+
+       if (!stack_slot_is_managed_pointer (dest)) 
+               CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid destination 
of stobj operation at 0x%04x", ctx->ip_offset));
+
+       if (!verify_stack_type_compatibility (ctx, type, src))
+               CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid source of 
stobj operation at 0x%04x", ctx->ip_offset));
+
+       if (!verify_type_compatibility (ctx, mono_type_get_type_byval 
(dest->type), type))
+               CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Destination and 
type token of stobj don't match at 0x%04x", ctx->ip_offset));
+
+}
+       
+
+/* TODO implement access verification */
 static void
 do_newobj (VerifyContext *ctx, int token) 
 {
@@ -2902,7 +2938,7 @@
        }
 
        if (check_overflow (ctx))
-               set_stack_value (stack_push (ctx),  &method->klass->byval_arg, 
FALSE);
+               set_stack_value (ctx, stack_push (ctx),  
&method->klass->byval_arg, FALSE);
 }
 
 static void
@@ -3017,18 +3053,18 @@
        value = stack_pop (ctx);
        if (!stack_slot_is_managed_pointer (value)) {
                CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Load indirect not 
using a manager pointer at 0x%04x", ctx->ip_offset));
-               set_stack_value (stack_push (ctx), mono_type_from_opcode 
(opcode), FALSE);
+               set_stack_value (ctx, stack_push (ctx), mono_type_from_opcode 
(opcode), FALSE);
                return;
        }
 
        if (opcode == CEE_LDIND_REF) {
                if (stack_slot_get_underlying_type (value) != TYPE_COMPLEX || 
mono_class_from_mono_type (value->type)->valuetype)
                        CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid 
type at stack for ldind_ref expected object byref operation at 0x%04x", 
ctx->ip_offset));
-               set_stack_value (stack_push (ctx), mono_type_get_type_byval 
(value->type), FALSE);
+               set_stack_value (ctx, stack_push (ctx), 
mono_type_get_type_byval (value->type), FALSE);
        } else {
                if (!verify_type_compatibility_full (ctx, mono_type_from_opcode 
(opcode), mono_type_get_type_byval (value->type), TRUE))
                        CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid 
type at stack for ldind 0x%x operation at 0x%04x", opcode, ctx->ip_offset));
-               set_stack_value (stack_push (ctx), mono_type_from_opcode 
(opcode), FALSE);
+               set_stack_value (ctx, stack_push (ctx), mono_type_from_opcode 
(opcode), FALSE);
        }
 }
 
@@ -3072,7 +3108,7 @@
        if (stack_slot_get_type (value) != TYPE_I4 && stack_slot_get_type 
(value) != TYPE_NATIVE_INT)
                CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Array size type on 
stack (%s) is not a verifiable type at 0x%04x", stack_slot_get_name (value), 
ctx->ip_offset));
 
-       set_stack_value (stack_push (ctx), mono_class_get_type 
(mono_array_class_get (mono_class_from_mono_type (type), 1)), FALSE);
+       set_stack_value (ctx, stack_push (ctx), mono_class_get_type 
(mono_array_class_get (mono_class_from_mono_type (type), 1)), FALSE);
 }
 
 /*FIXME handle arrays that are not 0-indexed*/
@@ -3127,7 +3163,7 @@
                }
        }
 
-       set_stack_value (stack_push (ctx), type, TRUE); 
+       set_stack_value (ctx, stack_push (ctx), type, TRUE);    
 }
 
 /*FIXME handle arrays that are not 0-indexed*/
@@ -3170,7 +3206,7 @@
                }
        }
 
-       set_stack_value (stack_push (ctx), type, FALSE);
+       set_stack_value (ctx, stack_push (ctx), type, FALSE);
 }
 
 /*FIXME handle arrays that are not 0-indexed*/
@@ -4103,11 +4139,9 @@
                        do_store_static_field (&ctx, read32 (ip + 1));
                        ip += 5;
                        break;
+
                case CEE_STOBJ:
-                       if (!check_underflow (&ctx, 2))
-                               break;
-                       ctx.eval.size -= 2;
-                       token = read32 (ip + 1);
+                       do_stobj (&ctx, read32 (ip + 1));
                        ip += 5;
                        break;
 

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to