Initial sandboxing implementation
This commit is contained in:
@@ -6,6 +6,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection.Metadata;
|
||||||
|
|
||||||
partial class NetScript
|
partial class NetScript
|
||||||
{
|
{
|
||||||
@@ -13,18 +14,34 @@ partial class NetScript
|
|||||||
{
|
{
|
||||||
private const bool useWhitelist = false;
|
private const bool useWhitelist = false;
|
||||||
|
|
||||||
private static string[] classesPermited = new string[] {};
|
private static string[] typesPermited = new string[] {
|
||||||
private static string[] classesProhibited = new string[] { };
|
// Basics
|
||||||
public static bool IsClassAllowed(string usingName)
|
"System.Runtime.CompilerServices.CompilationRelaxationsAttribute",
|
||||||
|
"System.Runtime.CompilerServices.RuntimeCompatibilityAttribute",
|
||||||
|
"System.Diagnostics.DebuggableAttribute",
|
||||||
|
"System.Object",
|
||||||
|
"System.String",
|
||||||
|
"System.Collections",
|
||||||
|
// Some roslyn magic
|
||||||
|
".DebuggingModes",
|
||||||
|
// Barotrauma
|
||||||
|
"Barotrauma",
|
||||||
|
};
|
||||||
|
private static string[] typessProhibited = new string[] {
|
||||||
|
//"System.Reflection",
|
||||||
|
"System.IO.File",
|
||||||
|
};
|
||||||
|
public static bool IsTypeAllowed(string usingName)
|
||||||
{
|
{
|
||||||
if (useWhitelist && !classesPermited.Any(u => u.Equals(usingName))) return false;
|
if (useWhitelist && !typesPermited.Any(u => u.StartsWith(usingName))) return false;
|
||||||
if (classesProhibited.Any(u => u.Equals(usingName))) return false;
|
if (typessProhibited.Any(u => u.StartsWith(usingName))) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string FilterSyntaxTree(CSharpSyntaxTree tree)
|
public static string FilterSyntaxTree(CSharpSyntaxTree tree)
|
||||||
{
|
{
|
||||||
if (tree == null) throw new ArgumentNullException("Syntax tree must not be null.");
|
if (tree == null) throw new ArgumentNullException("Syntax tree must not be null.");
|
||||||
|
|
||||||
{ // Disallow top-level statements
|
{ // Disallow top-level statements
|
||||||
var nodeCheck = tree.GetRoot().DescendantNodes();
|
var nodeCheck = tree.GetRoot().DescendantNodes();
|
||||||
|
|
||||||
@@ -32,64 +49,33 @@ partial class NetScript
|
|||||||
if (tlStatements.Count > 0)
|
if (tlStatements.Count > 0)
|
||||||
{
|
{
|
||||||
string errStr = "Cmopilation Error:";
|
string errStr = "Cmopilation Error:";
|
||||||
foreach (var tls in tlStatements) tls.GetDiagnostics().ToList().ForEach(d => errStr += "\n" + d.ToString());
|
foreach (var tls in tlStatements) tls.GetDiagnostics().ToList().ForEach(d => errStr += $"\n {d.ToString()}");
|
||||||
return errStr;
|
return errStr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var compRoot = tree.GetCompilationUnitRoot();
|
return null;
|
||||||
var refDirs = compRoot.GetReferenceDirectives().ToList();
|
}
|
||||||
Console.WriteLine($"Reference Directives [{refDirs.Count}]:");
|
|
||||||
refDirs.ForEach(d => Console.WriteLine(d.ToFullString()));
|
|
||||||
|
|
||||||
List<string> allUsedTypes = new List<string>();
|
public static string FilterMetadata(MetadataReader reader)
|
||||||
{ // Find all used types
|
{
|
||||||
}
|
if (reader == null) throw new ArgumentNullException("Metadata Reader must not be null.");
|
||||||
|
|
||||||
List<string> allResolvedTypes = new List<string>();
|
var conflictingTypes = new List<string>();
|
||||||
{ // Resolve all types
|
reader.TypeReferences.ToList().ForEach(t =>
|
||||||
}
|
|
||||||
|
|
||||||
{ // Check all used types
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Directory.Exists("./SyntaxTrees")) Directory.CreateDirectory("./SyntaxTrees");
|
|
||||||
string fileName = "./SyntaxTrees/" + tree.FilePath.Replace("/", "--") + ".txt";
|
|
||||||
if (File.Exists(fileName)) File.Delete(fileName);
|
|
||||||
var fileWriter = File.CreateText(fileName);
|
|
||||||
|
|
||||||
var nodes = new Queue<(SyntaxNode, int)>();
|
|
||||||
nodes.Enqueue((tree.GetRoot(), 0));
|
|
||||||
while (nodes.Count > 0)
|
|
||||||
{
|
{
|
||||||
var nodeElem = nodes.Dequeue();
|
var tRef = reader.GetTypeReference(t);
|
||||||
var node = nodeElem.Item1;
|
var typeName = $"{reader.GetString(tRef.Namespace)}.{reader.GetString(tRef.Name)}";
|
||||||
var indent = nodeElem.Item2;
|
if (!IsTypeAllowed(typeName)) conflictingTypes.Add(typeName);
|
||||||
|
});
|
||||||
|
|
||||||
node.ChildNodes().ToList().ForEach(n => {
|
if (conflictingTypes.Count > 0)
|
||||||
if (n.ChildNodes().Count() > 0) nodes.Enqueue((n, indent + 1));
|
{
|
||||||
if (!(
|
string errStr = "Metadata Error:";
|
||||||
n is MemberAccessExpressionSyntax ||
|
conflictingTypes.ForEach(t => errStr += $"\n Usage of type '{t}' in mods is prohibited.");
|
||||||
n is UsingDirectiveSyntax ||
|
return errStr;
|
||||||
n is BaseTypeSyntax ||
|
|
||||||
n is TypeSyntax
|
|
||||||
)) return;
|
|
||||||
//Console.WriteLine(new String(' ', indent * 2) + n.GetType().Name + " | " + n.GetText()?.ToString() ?? "null");
|
|
||||||
fileWriter.WriteLine(new String(' ', indent * 2) + n.GetType().Name + " | " + n.GetText()?.ToString() ?? "null");
|
|
||||||
});
|
|
||||||
node.DescendantNodes().ToList().ForEach(n => {
|
|
||||||
if (n.DescendantNodes().Count() > 0 && !nodes.Contains((n, indent + 1))) nodes.Enqueue((n, indent + 1));
|
|
||||||
if (!(
|
|
||||||
n is MemberAccessExpressionSyntax ||
|
|
||||||
n is UsingDirectiveSyntax ||
|
|
||||||
n is BaseTypeSyntax ||
|
|
||||||
n is TypeSyntax
|
|
||||||
)) return;
|
|
||||||
//Console.WriteLine(new String(' ', indent * 2) + n.GetType().Name + " | " + n.GetText()?.ToString() ?? "null");
|
|
||||||
fileWriter.WriteLine(new String(' ', indent * 2) + n.GetType().Name + " | " + n.GetText()?.ToString() ?? "null");
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
fileWriter.Close();
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,14 +5,11 @@ using Microsoft.CodeAnalysis.Scripting;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Microsoft.CodeAnalysis.CSharp;
|
using Microsoft.CodeAnalysis.CSharp;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using System.Collections.Immutable;
|
|
||||||
using System.Runtime.Loader;
|
using System.Runtime.Loader;
|
||||||
using static NetScript;
|
|
||||||
using Microsoft.CodeAnalysis.Emit;
|
|
||||||
using System.Reflection.PortableExecutable;
|
using System.Reflection.PortableExecutable;
|
||||||
using System.Reflection.Metadata;
|
using System.Reflection.Metadata;
|
||||||
|
using static NetScript;
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
@@ -113,29 +110,19 @@ namespace Barotrauma
|
|||||||
|
|
||||||
string errStr = "NET MODS NOT LOADED | Mod cmopilation errors:";
|
string errStr = "NET MODS NOT LOADED | Mod cmopilation errors:";
|
||||||
foreach (Diagnostic diagnostic in failures)
|
foreach (Diagnostic diagnostic in failures)
|
||||||
{
|
|
||||||
errStr = $"\n{diagnostic}";
|
errStr = $"\n{diagnostic}";
|
||||||
}
|
|
||||||
NetSetup.PrintMessage(errStr);
|
NetSetup.PrintMessage(errStr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mem.Seek(0, SeekOrigin.Begin);
|
mem.Seek(0, SeekOrigin.Begin);
|
||||||
var reader = new PEReader(mem);
|
var errStr = NetScriptFilter.FilterMetadata(new PEReader(mem).GetMetadataReader());
|
||||||
var mdReader = reader.GetMetadataReader();
|
if (errStr == null)
|
||||||
mdReader.AssemblyReferences.ToList().ForEach(a =>
|
{
|
||||||
{
|
mem.Seek(0, SeekOrigin.Begin);
|
||||||
var aRef = mdReader.GetAssemblyReference(a);
|
Assembly = LoadFromStream(mem);
|
||||||
Console.WriteLine(aRef.GetAssemblyName() + " " + aRef.Version);
|
}
|
||||||
});
|
else NetSetup.PrintMessage(errStr);
|
||||||
Console.WriteLine();
|
|
||||||
mdReader.TypeReferences.ToList().ForEach(t =>
|
|
||||||
{
|
|
||||||
var tRef = mdReader.GetTypeReference(t);
|
|
||||||
Console.WriteLine(mdReader.GetString(tRef.Namespace) + " - " + mdReader.GetString(tRef.Name));
|
|
||||||
});
|
|
||||||
mem.Seek(0, SeekOrigin.Begin);
|
|
||||||
Assembly = LoadFromStream(mem);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
syntaxTrees.Clear();
|
syntaxTrees.Clear();
|
||||||
|
|||||||
Reference in New Issue
Block a user