Esempio n. 1
0
        public void ThrowsGuardException_ForLocalsThatExceedSizeLimit()
        {
            // found by Stanislav Lukeš‏ (@exyi)
            var compiled = TestHelper.Compile(@"
                using System;
                struct A_1 { public int A; public int B; }
                struct A_2 { public A_1 A; public A_1 B; }
                struct A_3 { public A_2 A; public A_2 B; }
                struct A_4 { public A_3 A; public A_3 B; }
                struct A_5 { public A_4 A; public A_4 B; }
                struct A_6 { public A_5 A; public A_5 B; }
                struct A_7 { public A_6 A; public A_6 B; }
                struct A_8 { public A_7 A; public A_7 B; }
                struct A_9 { public A_8 A; public A_8 B; }
                struct A_10 { public A_9 A; public A_9 B; }
                struct A_11 { public A_10 A; public A_10 B; }
                struct A_12 { public A_11 A; public A_11 B; }
                struct A_13 { public A_12 A; public A_12 B; }
                struct A_14 { public A_13 A; public A_13 B; }
                struct A_15 { public A_14 A; public A_14 B; }
                struct A_16 { public A_15 A; public A_15 B; }
                struct A_17 { public A_16 A; public A_16 B; }
                struct A_18 { public A_17 A; public A_17 B; }
                class C {
                    int M() {
                        A_18 a;
                        return 0;
                    }
                }
            ");

            Assert.Throws <AssemblyGuardException>(
                () => AssemblyGuard.Rewrite(compiled, new MemoryStream())
                );
        }
Esempio n. 2
0
        public void ThrowsGuardException_ForAsyncMethodWithTry()
        {
            var compiled = TestHelper.Compile(@"
                using System;
                using System.Threading.Tasks;

                class Program {
                    async Task Main() {
                        Console.WriteLine();

                        try {
                            await Task.Yield();
                        } catch { }
                    }
                }
            ");
            var ex       = Assert.Throws <AssemblyGuardException>(
                () => AssemblyGuard.Rewrite(compiled, Stream.Null, new AssemblyGuardSettings {
                ApiPolicy = ApiPolicy.SafeDefault()
                            .Namespace("System.Runtime.CompilerServices", ApiAccess.Allowed)
                            .Namespace("System.Threading.Tasks", ApiAccess.Allowed)
            })
                );

            Assert.Contains("System.Console", ex.Message);
        }
Esempio n. 3
0
        public ExecutionResult Execute(Stream assemblyStream, Stream symbolStream, IWorkSession session)
        {
            AssemblyDefinition assembly;

            using (assemblyStream)
                using (symbolStream) {
                    assembly = AssemblyDefinition.ReadAssembly(assemblyStream, new ReaderParameters {
                        ReadSymbols      = true,
                        SymbolStream     = symbolStream,
                        AssemblyResolver = PreCachedAssemblyResolver.Instance
                    });
                }

            /*
             #if DEBUG
             * assembly.Write(@"d:\Temp\assembly\" + DateTime.Now.Ticks + "-before-rewrite.dll");
             #endif
             */
            foreach (var rewriter in _rewriters)
            {
                rewriter.Rewrite(assembly, session);
            }
            if (assembly.EntryPoint == null)
            {
                throw new ArgumentException("Failed to find an entry point (Main?) in assembly.", nameof(assemblyStream));
            }

            var guardToken = AssemblyGuard.Rewrite(assembly, GuardSettings);

            using (var rewrittenStream = _memoryStreamManager.GetStream()) {
                assembly.Write(rewrittenStream);

                /*
                 #if DEBUG
                 * assembly.Write(@"d:\Temp\assembly\" + DateTime.Now.Ticks + ".dll");
                 #endif
                 */
                rewrittenStream.Seek(0, SeekOrigin.Begin);

                var currentSetup = AppDomain.CurrentDomain.SetupInformation;
                using (var context = AppDomainContext.Create(new AppDomainSetup {
                    ApplicationBase = currentSetup.ApplicationBase,
                    PrivateBinPath = currentSetup.PrivateBinPath
                })) {
                    context.LoadAssembly(LoadMethod.LoadFrom, Assembly.GetExecutingAssembly().GetAssemblyFile().FullName);
                    var(result, exception) = RemoteFunc.Invoke(context.Domain, rewrittenStream, guardToken, Remote.Execute);
                    if (ShouldMonitorException(exception))
                    {
                        _monitor.Exception(exception, session);
                    }
                    return(result);
                }
            }
        }
Esempio n. 4
0
        public void Allows_ReasonablySafePointerOperations(string code)
        {
            var compiled = TestHelper.Compile(@"
                // required for records
                namespace System.Runtime.CompilerServices { class IsExternalInit {} }
                " + code + @"
            ");

            // Assert.DoesNotThrow
            AssemblyGuard.Rewrite(compiled, new MemoryStream());
        }
Esempio n. 5
0
        [InlineData("void M(ref int i) => i++;")] //
        public void Allows_ReasonablySafePointerOperations(string code)
        {
            var compiled = TestHelper.Compile(@"
                class C {
                    " + code + @"
                }
            ");

            // Assert.DoesNotThrow
            AssemblyGuard.Rewrite(compiled, new MemoryStream());
        }
Esempio n. 6
0
        public void ThrowsGuardException_ForCustomTypesWithKnownTypeNames(string @namespace, string name)
        {
            var compiled = TestHelper.Compile(@"
                namespace " + @namespace + @" { class @" + name + @" {} }
            ");

            var exception = Record.Exception(
                () => AssemblyGuard.Rewrite(compiled, new MemoryStream())
                );

            Assert.IsType <AssemblyGuardException>(exception);
        }
Esempio n. 7
0
        private ResultViewModel Run(string code)
        {
            var totalStopwatch       = Stopwatch.StartNew();
            var compilationStopwatch = new Stopwatch();
            var rewriteStopwatch     = new Stopwatch();
            var executionStopwatch   = new Stopwatch();

            ResultViewModel resultModel(string?output) => new ResultViewModel(
                output,
                compilationStopwatch.Elapsed,
                rewriteStopwatch.Elapsed,
                executionStopwatch.Elapsed,
                totalStopwatch.Elapsed
                );

            try {
                compilationStopwatch.Start();
                CSharpRoslynGuard.Validate(code);
                var compilation = CSharpCompilation.Create(
                    "_",
                    new[] { CSharpSyntaxTree.ParseText(code) },
                    MetadataReferences,
                    new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
                    );
                using (var assemblyStream = MemoryStreamManager.GetStream())
                    using (var rewrittenStream = MemoryStreamManager.GetStream()) {
                        var compilationResult = compilation.Emit(assemblyStream);
                        compilationStopwatch.Stop();
                        if (!compilationResult.Success)
                        {
                            return(resultModel(string.Join("\r\n", compilationResult.Diagnostics)));
                        }
                        assemblyStream.Seek(0, SeekOrigin.Begin);
                        rewriteStopwatch.Start();
                        var guardToken = AssemblyGuard.Rewrite(assemblyStream, rewrittenStream);
                        rewriteStopwatch.Stop();
                        var currentSetup = AppDomain.CurrentDomain.SetupInformation;
                        using (var context = AppDomainContext.Create(new AppDomainSetup {
                            ApplicationBase = currentSetup.ApplicationBase,
                            PrivateBinPath = currentSetup.PrivateBinPath
                        })) {
                            context.LoadAssembly(LoadMethod.LoadFrom, Assembly.GetExecutingAssembly().GetAssemblyFile().FullName);
                            executionStopwatch.Start();
                            var result = RemoteFunc.Invoke(context.Domain, rewrittenStream, guardToken, RemoteRun);
                            executionStopwatch.Stop();
                            return(resultModel(result?.ToString()));
                        }
                    }
            }
            catch (Exception ex) {
                return(resultModel(ex.ToString()));
            }
        }
Esempio n. 8
0
        [InlineData("void M() { var x = new IntPtr(0); }")] // crash, found by Alexandre Mutel‏ (@xoofx)
        public void ThrowsGuardException_ForDeniedApi(string code)
        {
            var compiled = TestHelper.Compile(@"
                using System;
                class C {
                    " + code + @"
                }"
                                              );

            Assert.Throws <AssemblyGuardException>(
                () => AssemblyGuard.Rewrite(compiled, new MemoryStream())
                );
        }
Esempio n. 9
0
        public void ThrowsGuardException_ForFinalizers()
        {
            // found by George Pollard‏ (@porges)
            var compiled = TestHelper.Compile(@"
                class X {
                    ~X() {}
                }
            ");

            Assert.Throws <AssemblyGuardException>(
                () => AssemblyGuard.Rewrite(compiled, new MemoryStream())
                );
        }
Esempio n. 10
0
        public void Allows_AnonymousTypes()
        {
            var compiled = TestHelper.Compile(@"
                class C {
                    object M() {
                        return new { a = ""x"" };
                    }
                }
            ");

            // Assert.DoesNotThrow
            AssemblyGuard.Rewrite(compiled, new MemoryStream(), AssemblyGuardSettings.DefaultForCSharpAssembly());
        }
Esempio n. 11
0
        public void ThrowsGuardException_ForPInvoke()
        {
            // found by Igal Tabachnik (@hmemcpy)
            var compiled = TestHelper.Compile(@"
                using System.Runtime.InteropServices;
                static class X {
                    [DllImport(""kernel32.dll"")]
                    static extern void ExitProcess(int uExitCode);
                }
            ");

            Assert.Throws <AssemblyGuardException>(
                () => AssemblyGuard.Rewrite(compiled, new MemoryStream())
                );
        }
Esempio n. 12
0
        public void ThrowsAssemblyGuardException_IfTimeoutIsProvidedManually(string code)
        {
            var compiled = TestHelper.Compile(@"
                using System;
                using System.Text.RegularExpressions;

                class C {
                    public void M() => " + code + @";
                }
            ");
            var ex       = Record.Exception(() => AssemblyGuard.Rewrite(compiled, new MemoryStream()));

            Assert.IsType <AssemblyGuardException>(ex);
            Assert.Contains("Timeout", ex.Message, StringComparison.OrdinalIgnoreCase);
        }
Esempio n. 13
0
        [Fact] // https://github.com/ashmind/SharpLab/issues/323
        public void Allows_CallsToRefReadOnlyMethods()
        {
            var compiled = TestHelper.Compile(@"
                class C {
                    static ref readonly int MRef(ref int i) => ref i;
                    static void M() {
                        int x = 0;
                        ref readonly int r = ref MRef(ref x);
                    }
                }
            ");

            // Assert.DoesNotThrow
            AssemblyGuard.Rewrite(compiled, new MemoryStream(), AssemblyGuardSettings.DefaultForCSharpAssembly());
        }
Esempio n. 14
0
        public void ThrowsGuardException_ForDelegateBeginEndInvoke()
        {
            // found by Llewellyn Pritchard (@leppie)
            var compiled = TestHelper.Compile(@"
                using System;
                class C {
                    delegate void D();
                    void M() { D d = () => {}; d.BeginInvoke(null, null); }
                }"
                                              );

            Assert.Throws <AssemblyGuardException>(
                () => AssemblyGuard.Rewrite(compiled, new MemoryStream())
                );
        }
Esempio n. 15
0
        public static Invoke RewriteAndGetMethodWrappedInScope(string code, string typeName, string methodName, AssemblyGuardSettings guardSettings = null)
        {
            var assemblySourceStream = Compile(code);
            var assemblyTargetStream = new MemoryStream();

            var token = AssemblyGuard.Rewrite(assemblySourceStream, assemblyTargetStream, guardSettings);

            return(args => {
                using (token.Scope(new RuntimeGuardSettings {
                    TimeLimit = TimeSpan.FromMilliseconds(100)
                })) {
                    var method = GetInstanceMethod(assemblyTargetStream, typeName, methodName);
                    return method(args);
                }
            });
        }
Esempio n. 16
0
        public void Allows_ReasonableAmountOfNullableLocals()
        {
            var compiled = TestHelper.Compile(@"
                class C {
                    void M() {
                        int? a = 1;
                        int? b = 1;
                        int? c = a + b;
                        int? d = a + b;
                    }
                }
            ");

            // Assert.DoesNotThrow
            AssemblyGuard.Rewrite(compiled, new MemoryStream());
        }
Esempio n. 17
0
        public void Allows_ExternMethods()
        {
            // crash, found by Alexandre Mutel‏ (@xoofx)
            var compiled = TestHelper.Compile(@"
                class C {
                    static extern void Extern();
                    int M() {
                        Extern();
                        return 0;
                    }
                }
            ");

            // Assert.DoesNotThrow
            AssemblyGuard.Rewrite(compiled, new MemoryStream());
        }
Esempio n. 18
0
        public void ThrowsGuardException_ForExplicitStructLayout()
        {
            // found by Alexandre Mutel (@xoofx)
            var compiled = TestHelper.Compile(@"
                using System.Runtime.InteropServices;
                [StructLayout(LayoutKind.Explicit)]
                struct S {
                    [FieldOffset(0)]
                    int x;
                }
            ");

            Assert.Throws <AssemblyGuardException>(
                () => AssemblyGuard.Rewrite(compiled, new MemoryStream())
                );
        }
Esempio n. 19
0
        public void ThrowsGuardException_ForPointerTypes(string code)
        {
            // pointers, available in local functions due to a Roslyn bug, reported by Andy Gocke‏ (@andygocke)
            var policy = ApiPolicy.SafeDefault()
                         .Namespace("System.Security", ApiAccess.Neutral, n => n.Type(typeof(UnverifiableCodeAttribute), ApiAccess.Allowed));
            var compiled = TestHelper.Compile(@"
                class X {
                    unsafe void M(int a) { " + code + @" }
                }
            ", allowUnsafe: true);

            Assert.Throws <AssemblyGuardException>(
                () => AssemblyGuard.Rewrite(compiled, new MemoryStream(), new AssemblyGuardSettings {
                ApiPolicy = policy
            })
                );
        }
Esempio n. 20
0
        public void ThrowsGuardException_ForDelegatesCreatedFromMethodsWithRewriters(string code)
        {
            var compiled = TestHelper.Compile(@"
                using System;
                using System.Linq.Expressions;
                class C {
                    void M() { " + code + @" }
                }"
                                              );
            var policy = ApiPolicy.SafeDefault()
                         .Namespace("System.Linq.Expressions", ApiAccess.Allowed)
                         .Namespace("System.Reflection", ApiAccess.Allowed);

            Assert.Throws <AssemblyGuardException>(
                () => AssemblyGuard.Rewrite(compiled, new MemoryStream(), new AssemblyGuardSettings {
                ApiPolicy = policy
            })
                );
        }
Esempio n. 21
0
        public ExecutionResult Execute(CompilationStreamPair streams, IWorkSession session)
        {
            var readerParameters = new ReaderParameters {
                ReadSymbols          = streams.SymbolStream != null,
                SymbolStream         = streams.SymbolStream,
                AssemblyResolver     = _assemblyResolver,
                SymbolReaderProvider = streams.SymbolStream != null ? _symbolReaderProvider : null
            };

            using (streams)
                using (var definition = AssemblyDefinition.ReadAssembly(streams.AssemblyStream, readerParameters)) {
                    foreach (var rewriter in _rewriters)
                    {
                        rewriter.Rewrite(definition, session);
                    }
                    PerformanceLog.Checkpoint("Executor.Rewrite.Flow.End");

                    AssemblyLog.Log("2.WithFlow", definition);
                    if (definition.EntryPoint == null)
                    {
                        Output.Reset();
                        Flow.Reset();
                        Output.WriteWarning("Could not find any code to run (either a Main method or any top level code).");
                        return(new ExecutionResult(Output.Stream, Flow.Steps));
                    }

                    var guardToken = AssemblyGuard.Rewrite(definition, _guardSettings);
                    using (var rewrittenStream = _memoryStreamManager.GetStream()) {
                        definition.Write(rewrittenStream);

                        AssemblyLog.Log("3.Unbreakable", definition);

                        rewrittenStream.Seek(0, SeekOrigin.Begin);
                        PerformanceLog.Checkpoint("Executor.Rewrite.Unbreakable.End");
                        using (var context = new CustomAssemblyLoadContext(shouldShareAssembly: ShouldShareAssembly)) {
                            var assembly = context.LoadFromStream(rewrittenStream);
                            PerformanceLog.Checkpoint("Executor.AssemblyLoad.End");

                            return(Execute(assembly, guardToken, session));
                        }
                    }
                }
        }
Esempio n. 22
0
        public ExecutionResult Execute(CompilationStreamPair streams, IWorkSession session)
        {
            var readerParameters = new ReaderParameters {
                ReadSymbols          = streams.SymbolStream != null,
                SymbolStream         = streams.SymbolStream,
                AssemblyResolver     = _assemblyResolver,
                SymbolReaderProvider = streams.SymbolStream != null ? _symbolReaderProvider : null
            };

            using (streams)
                using (var definition = AssemblyDefinition.ReadAssembly(streams.AssemblyStream, readerParameters)) {
                    AssemblyLog.Log("1.Initial", definition);

                    foreach (var rewriter in _rewriters)
                    {
                        rewriter.Rewrite(definition, session);
                    }
                    PerformanceLog.Checkpoint("Executor.Rewrite.Flow.End");

                    AssemblyLog.Log("2.WithFlow", definition);
                    if (definition.EntryPoint == null)
                    {
                        throw new ArgumentException("Failed to find an entry point (Main?) in assembly.", nameof(streams));
                    }

                    var guardToken = AssemblyGuard.Rewrite(definition, _guardSettings);
                    using (var rewrittenStream = _memoryStreamManager.GetStream()) {
                        definition.Write(rewrittenStream);

                        AssemblyLog.Log("3.Unbreakable", definition);

                        rewrittenStream.Seek(0, SeekOrigin.Begin);
                        PerformanceLog.Checkpoint("Executor.Rewrite.Unbreakable.End");
                        using (var context = new CustomAssemblyLoadContext(shouldShareAssembly: ShouldShareAssembly)) {
                            var assembly = context.LoadFromStream(rewrittenStream);
                            PerformanceLog.Checkpoint("Executor.AssemblyLoad.End");

                            return(Execute(assembly, guardToken, session));
                        }
                    }
                }
        }
Esempio n. 23
0
        public void DoesNotEnforceApiPolicy_ForUserCode()
        {
            var compiled = TestHelper.Compile(@"
                namespace N {
                    class C1 {
                        void M(C2 c2) { c2.M(); }
                    }

                    class C2 {
                        public void M() {}
                    }
                }
            ");

            var exception = Record.Exception(() => AssemblyGuard.Rewrite(compiled, new MemoryStream(), new AssemblyGuardSettings {
                ApiPolicy = ApiPolicy.SafeDefault().Namespace("N", ApiAccess.Denied)
            }));

            Assert.Null(exception);
        }
Esempio n. 24
0
        public void ThrowsGuardException_ForFieldReadsThatExceedSizeLimit()
        {
            // found by Tereza Tomcova (@the-ress)
            var compiled = TestHelper.Compile(@"
                using System;
                using System.Collections.Generic;

                struct A_1 { public int A; public int B; }
                struct A_2 { public A_1 A; public A_1 B; }
                struct A_3 { public A_2 A; public A_2 B; }
                struct A_4 { public A_3 A; public A_3 B; }
                struct A_5 { public A_4 A; public A_4 B; }
                struct A_6 { public A_5 A; public A_5 B; }
                struct A_7 { public A_6 A; public A_6 B; }
                struct A_8 { public A_7 A; public A_7 B; }
                struct A_9 { public A_8 A; public A_8 B; }
                struct A_10 { public A_9 A; public A_9 B; }
                struct A_11 { public A_10 A; public A_10 B; }
                struct A_12 { public A_11 A; public A_11 B; }
                struct A_13 { public A_12 A; public A_12 B; }
                struct A_14 { public A_13 A; public A_13 B; }
                struct A_15 { public A_14 A; public A_14 B; }
                struct A_16 { public A_15 A; public A_15 B; }
                struct A_17 { public A_16 A; public A_16 B; }
                struct A_18 { public A_17 A; public A_17 B; }

                class C {
                    static readonly A_18 Value = default(A_18);

                    int M() {
                        var d = new Dictionary<int, A_18>();
                        d.Add(0, Value);
                        return 0;
                    }
                }
            ");

            Assert.Throws <AssemblyGuardException>(
                () => AssemblyGuard.Rewrite(compiled, new MemoryStream())
                );
        }
Esempio n. 25
0
        public ExecutionResult Execute(Stream assemblyStream, Stream symbolStream, IWorkSession session)
        {
            var readerParameters = new ReaderParameters {
                ReadSymbols          = symbolStream != null,
                SymbolStream         = symbolStream,
                AssemblyResolver     = _assemblyResolver,
                SymbolReaderProvider = symbolStream != null ? _symbolReaderProvider : null
            };

            using (assemblyStream)
                using (symbolStream)
                    using (var assembly = AssemblyDefinition.ReadAssembly(assemblyStream, readerParameters)) {
                        /*
                         #if DEBUG
                         * assembly.Write(@"d:\Temp\assembly\" + DateTime.Now.Ticks + "-before-rewrite.dll");
                         #endif
                         */
                        foreach (var rewriter in _rewriters)
                        {
                            rewriter.Rewrite(assembly, session);
                        }
                        if (assembly.EntryPoint == null)
                        {
                            throw new ArgumentException("Failed to find an entry point (Main?) in assembly.", nameof(assemblyStream));
                        }

                        var guardToken = AssemblyGuard.Rewrite(assembly, GuardSettings);
                        using (var rewrittenStream = _memoryStreamManager.GetStream()) {
                            assembly.Write(rewrittenStream);

                            /*
                             #if DEBUG
                             * assembly.Write(@"d:\Temp\assembly\" + DateTime.Now.Ticks + ".dll");
                             #endif
                             */
                            rewrittenStream.Seek(0, SeekOrigin.Begin);

                            return(ExecuteInAppDomain(rewrittenStream, guardToken, session));
                        }
                    }
        }
Esempio n. 26
0
        private static Assembly RewriteNewtonsoftJson()
        {
            var assemblyPath = typeof(JsonSerializer).Assembly.GetAssemblyFileFromCodeBase().FullName;
            var definition   = AssemblyDefinition.ReadAssembly(assemblyPath);

            definition.Name.HasPublicKey      = false;
            definition.Name.PublicKey         = new byte[0];
            definition.Name.HashAlgorithm     = AssemblyHashAlgorithm.None;
            definition.MainModule.Attributes &= ~ModuleAttributes.StrongNameSigned;
            AssemblyGuard.Rewrite(definition, new AssemblyGuardSettings {
                ApiPolicy                = ApiRules,
                MethodLocalsSizeLimit    = IntPtr.Size * 40,
                MethodStackPushSizeLimit = 120,
                AllowExplicitLayoutInTypesMatchingPattern = new Regex("<PrivateImplementationDetails>")
            });

            var assemblyStream = new MemoryStream();

            definition.Write(assemblyStream);
            definition.Write(Path.Combine(Path.GetDirectoryName(assemblyPath) !, "Newtonsoft.Json.Rewritten.dll"));
            return(Assembly.Load(assemblyStream.ToArray()));
        }
Esempio n. 27
0
        public ExecutionResult Execute(CompilationStreamPair streams, IWorkSession session)
        {
            var readerParameters = new ReaderParameters {
                ReadSymbols          = streams.SymbolStream != null,
                SymbolStream         = streams.SymbolStream,
                AssemblyResolver     = _assemblyResolver,
                SymbolReaderProvider = streams.SymbolStream != null ? _symbolReaderProvider : null
            };

            using (streams)
                using (var definition = AssemblyDefinition.ReadAssembly(streams.AssemblyStream, readerParameters)) {
                    AssemblyLog.Log("1.Initial", definition);

                    foreach (var rewriter in _rewriters)
                    {
                        rewriter.Rewrite(definition, session);
                    }
                    AssemblyLog.Log("2.WithFlow", definition);
                    if (definition.EntryPoint == null)
                    {
                        throw new ArgumentException("Failed to find an entry point (Main?) in assembly.", nameof(streams));
                    }

                    var guardToken = AssemblyGuard.Rewrite(definition, _guardSettings);
                    using (var rewrittenStream = _memoryStreamManager.GetStream()) {
                        definition.Write(rewrittenStream);
                        AssemblyLog.Log("3.Unbreakable", definition);

                        rewrittenStream.Seek(0, SeekOrigin.Begin);
                        var(result, exception) = ExecuteWithIsolation(rewrittenStream, guardToken, session);
                        if (ShouldMonitorException(exception))
                        {
                            _monitor.Exception(exception !, session);
                        }

                        return(result);
                    }
                }
        }
Esempio n. 28
0
 public static RuntimeGuardToken Rewrite(Stream source, Stream target)
 {
     return(AssemblyGuard.Rewrite(source, target, CreateGuardSettings()));
 }