Пример #1
0
        private static bool DoVerifyIL(Resolver resolver, SandboxConfig config, PEReader peReader,
                                       MetadataReader reader)
        {
            Logger.DebugS("res.typecheck", "Verifying IL...");
            var sw  = Stopwatch.StartNew();
            var ver = new Verifier(resolver);

            ver.SetSystemModuleName(new AssemblyName(config.SystemAssemblyName));
            var verifyErrors = false;

            foreach (var res in ver.Verify(peReader))
            {
                if (config.AllowedVerifierErrors.Contains(res.Code))
                {
                    continue;
                }

                var msg = $"ILVerify: {res.Message}";

                try
                {
                    if (!res.Method.IsNil)
                    {
                        var method    = reader.GetMethodDefinition(res.Method);
                        var methodSig = method.DecodeSignature(new TypeProvider(), 0);
                        var type      = GetTypeFromDefinition(reader, method.GetDeclaringType());

                        var methodName =
                            $"{methodSig.ReturnType} {type}.{reader.GetString(method.Name)}({string.Join(", ", methodSig.ParameterTypes)})";

                        msg = $"{msg}, method: {methodName}";
                    }

                    if (!res.Type.IsNil)
                    {
                        var type = GetTypeFromDefinition(reader, res.Type);
                        msg = $"{msg}, type: {type}";
                    }
                }
                catch (UnsupportedMetadataException e)
                {
                    Logger.ErrorS("res.typecheck", $"{e}");
                }

                verifyErrors = true;
                Logger.ErrorS("res.typecheck", msg);
            }

            Logger.DebugS("res.typecheck", $"Verified IL in {sw.Elapsed.TotalMilliseconds}ms");

            if (verifyErrors)
            {
                return(false);
            }

            return(true);
        }
Пример #2
0
        private static void CheckMemberReferences(List <MMemberRef> members, SandboxConfig config,
                                                  ConcurrentBag <SandboxError> errors)
        {
            Parallel.ForEach(members, memberRef =>
            {
                MType baseType = memberRef.ParentType;
                while (!(baseType is MTypeReferenced))
                {
                    switch (baseType)
                    {
                    case MTypeGeneric generic:
                        {
                            baseType = generic.GenericType;

                            break;
                        }

                    case MTypeArray array:
                        {
                            // For this kind of array we just need access to the type itself.
                            if (!IsTypeAccessAllowed((MTypeReferenced)array.ElementType, config, out _))
                            {
                                errors.Add(new SandboxError($"Access to type not allowed: {array}"));
                            }

                            return; // Found
                        }

                    default:
                        {
                            throw new ArgumentOutOfRangeException();
                        }
                    }
                }

                var baseTypeReferenced = (MTypeReferenced)baseType;

                if (!IsTypeAccessAllowed(baseTypeReferenced, config, out var typeCfg))
                {
                    errors.Add(new SandboxError($"Access to type not allowed: {baseTypeReferenced}"));
                    return;
                }

                if (typeCfg.All)
                {
                    // Fully whitelisted for the type, we good.
                    return;
                }

                switch (memberRef)
                {
                case MMemberRefField mMemberRefField:
                    {
                        foreach (var field in typeCfg.FieldsParsed)
                        {
                            if (field.Name == mMemberRefField.Name &&
                                mMemberRefField.FieldType.WhitelistEquals(field.FieldType))
                            {
                                return; // Found
                            }
                        }

                        errors.Add(new SandboxError($"Access to field not allowed: {mMemberRefField}"));
                        break;
                    }

                case MMemberRefMethod mMemberRefMethod:
                    foreach (var parsed in typeCfg.MethodsParsed)
                    {
                        if (parsed.Name == mMemberRefMethod.Name &&
                            mMemberRefMethod.ReturnType.WhitelistEquals(parsed.ReturnType) &&
                            mMemberRefMethod.ParameterTypes.Length == parsed.ParameterTypes.Length &&
                            mMemberRefMethod.GenericParameterCount == parsed.GenericParameterCount)
                        {
                            for (var i = 0; i < mMemberRefMethod.ParameterTypes.Length; i++)
                            {
                                var a = mMemberRefMethod.ParameterTypes[i];
                                var b = parsed.ParameterTypes[i];

                                if (!a.WhitelistEquals(b))
                                {
                                    goto paramMismatch;
                                }
                            }

                            return;     // Found
                        }

                        paramMismatch:;
                    }

                    errors.Add(new SandboxError($"Access to method not allowed: {mMemberRefMethod}"));
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(memberRef));
                }
            });
        }