update isolate integrity

This commit is contained in:
prixod
2025-11-04 23:22:11 +04:00
parent 44cb179cf5
commit ffd0de446d
7 changed files with 64 additions and 111 deletions

View File

@@ -22,48 +22,25 @@ builder.Services.AddSingleton(sp =>
// Register application services // Register application services
builder.Services.AddSingleton<PolygonProblemXmlParser>(); builder.Services.AddSingleton<PolygonProblemXmlParser>();
builder.Services.AddSingleton<AnswerGenerationService>(); builder.Services.AddSingleton<AnswerGenerationService>();
builder.Services.AddSingleton<CheckerService>();
builder.Services.AddSingleton<CheckerServiceIsolate>(); builder.Services.AddSingleton<CheckerServiceIsolate>();
builder.Services.AddSingleton<IPackageParserService, PackageParserService>(); builder.Services.AddSingleton<IPackageParserService, PackageParserService>();
builder.Services.AddSingleton<IOutputCheckerService, OutputCheckerService>(); builder.Services.AddSingleton<IOutputCheckerService, OutputCheckerService>();
builder.Services.AddSingleton<ICallbackService, CallbackService>(); builder.Services.AddSingleton<ICallbackService, CallbackService>();
// Register compilation services // Register Isolate compilation services
// Always register both standard and isolate versions
builder.Services.AddSingleton<CppCompilationService>();
builder.Services.AddSingleton<CppCompilationServiceIsolate>(); builder.Services.AddSingleton<CppCompilationServiceIsolate>();
builder.Services.AddSingleton<JavaCompilationService>();
builder.Services.AddSingleton<JavaCompilationServiceIsolate>(); builder.Services.AddSingleton<JavaCompilationServiceIsolate>();
builder.Services.AddSingleton<KotlinCompilationService>();
builder.Services.AddSingleton<KotlinCompilationServiceIsolate>(); builder.Services.AddSingleton<KotlinCompilationServiceIsolate>();
builder.Services.AddSingleton<CSharpCompilationService>();
builder.Services.AddSingleton<CSharpCompilationServiceIsolate>(); builder.Services.AddSingleton<CSharpCompilationServiceIsolate>();
builder.Services.AddSingleton<PythonCompilationService>();
builder.Services.AddSingleton<PythonCompilationServiceIsolate>(); builder.Services.AddSingleton<PythonCompilationServiceIsolate>();
builder.Services.AddSingleton<ICompilationServiceFactory, CompilationServiceFactory>(); builder.Services.AddSingleton<ICompilationServiceFactory, CompilationServiceFactory>();
// Register execution services // Register Isolate execution services
// Always register both standard and isolate versions
builder.Services.AddSingleton<CppExecutionService>();
builder.Services.AddSingleton<CppExecutionServiceIsolate>(); builder.Services.AddSingleton<CppExecutionServiceIsolate>();
builder.Services.AddSingleton<JavaExecutionService>();
builder.Services.AddSingleton<JavaExecutionServiceIsolate>(); builder.Services.AddSingleton<JavaExecutionServiceIsolate>();
builder.Services.AddSingleton<KotlinExecutionService>();
builder.Services.AddSingleton<KotlinExecutionServiceIsolate>(); builder.Services.AddSingleton<KotlinExecutionServiceIsolate>();
builder.Services.AddSingleton<CSharpExecutionService>();
builder.Services.AddSingleton<CSharpExecutionServiceIsolate>(); builder.Services.AddSingleton<CSharpExecutionServiceIsolate>();
builder.Services.AddSingleton<PythonExecutionService>();
builder.Services.AddSingleton<PythonExecutionServiceIsolate>(); builder.Services.AddSingleton<PythonExecutionServiceIsolate>();
builder.Services.AddSingleton<IExecutionServiceFactory, ExecutionServiceFactory>(); builder.Services.AddSingleton<IExecutionServiceFactory, ExecutionServiceFactory>();
// Register testing service // Register testing service

View File

@@ -1,56 +1,36 @@
namespace LiquidCode.Tester.Worker.Services; namespace LiquidCode.Tester.Worker.Services;
/// <summary>
/// Factory for compilation services - always uses Isolate sandbox for security
/// </summary>
public class CompilationServiceFactory : ICompilationServiceFactory public class CompilationServiceFactory : ICompilationServiceFactory
{ {
private readonly IServiceProvider _serviceProvider; private readonly IServiceProvider _serviceProvider;
private readonly IConfiguration _configuration;
private readonly ILogger<CompilationServiceFactory> _logger; private readonly ILogger<CompilationServiceFactory> _logger;
private readonly bool _useIsolate;
public CompilationServiceFactory( public CompilationServiceFactory(
IServiceProvider serviceProvider, IServiceProvider serviceProvider,
IConfiguration configuration,
ILogger<CompilationServiceFactory> logger) ILogger<CompilationServiceFactory> logger)
{ {
_serviceProvider = serviceProvider; _serviceProvider = serviceProvider;
_configuration = configuration;
_logger = logger; _logger = logger;
_useIsolate = configuration.GetValue<bool>("Isolate:Enabled", false);
if (_useIsolate) _logger.LogInformation("Compilation services configured to use Isolate sandbox");
{
_logger.LogInformation("Isolate sandbox is ENABLED for compilation");
}
else
{
_logger.LogWarning("Isolate sandbox is DISABLED for compilation - using standard compilation (NOT SECURE for production!)");
}
} }
public ICompilationService GetCompilationService(string language) public ICompilationService GetCompilationService(string language)
{ {
var normalizedLanguage = language.ToLowerInvariant().Replace(" ", ""); var normalizedLanguage = language.ToLowerInvariant().Replace(" ", "");
_logger.LogInformation("Getting compilation service for language: {Language} (Isolate: {UseIsolate})", _logger.LogDebug("Getting Isolate compilation service for language: {Language}", normalizedLanguage);
normalizedLanguage, _useIsolate);
return normalizedLanguage switch return normalizedLanguage switch
{ {
"c++" or "cpp" => _useIsolate "c++" or "cpp" => _serviceProvider.GetRequiredService<CppCompilationServiceIsolate>(),
? _serviceProvider.GetRequiredService<CppCompilationServiceIsolate>() "java" => _serviceProvider.GetRequiredService<JavaCompilationServiceIsolate>(),
: _serviceProvider.GetRequiredService<CppCompilationService>(), "kotlin" => _serviceProvider.GetRequiredService<KotlinCompilationServiceIsolate>(),
"java" => _useIsolate "c#" or "csharp" => _serviceProvider.GetRequiredService<CSharpCompilationServiceIsolate>(),
? _serviceProvider.GetRequiredService<JavaCompilationServiceIsolate>() "python" => _serviceProvider.GetRequiredService<PythonCompilationServiceIsolate>(),
: _serviceProvider.GetRequiredService<JavaCompilationService>(),
"kotlin" => _useIsolate
? _serviceProvider.GetRequiredService<KotlinCompilationServiceIsolate>()
: _serviceProvider.GetRequiredService<KotlinCompilationService>(),
"c#" or "csharp" => _useIsolate
? _serviceProvider.GetRequiredService<CSharpCompilationServiceIsolate>()
: _serviceProvider.GetRequiredService<CSharpCompilationService>(),
"python" => _useIsolate
? _serviceProvider.GetRequiredService<PythonCompilationServiceIsolate>()
: _serviceProvider.GetRequiredService<PythonCompilationService>(),
_ => throw new NotSupportedException($"Language '{language}' is not supported") _ => throw new NotSupportedException($"Language '{language}' is not supported")
}; };
} }

View File

@@ -42,7 +42,7 @@ public class CppCompilationServiceIsolate : ICompilationService
try try
{ {
await File.WriteAllTextAsync(sourceFilePath, sourceCode); await File.WriteAllTextAsync(sourceFilePath, sourceCode);
return await CompileFileInIsolateAsync(sourceFilePath, executablePath, version); return await CompileFileAsync(sourceFilePath, executablePath, version);
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -55,10 +55,15 @@ public class CppCompilationServiceIsolate : ICompilationService
} }
} }
private async Task<CompilationResult> CompileFileInIsolateAsync( /// <summary>
/// Compile a C++ source file to an executable using Isolate sandbox
/// </summary>
public async Task<CompilationResult> CompileFileAsync(
string sourceFilePath, string sourceFilePath,
string outputExecutablePath, string outputExecutablePath,
string? version = null) string? version = null,
IEnumerable<string>? includeDirectories = null,
IEnumerable<string>? additionalFlags = null)
{ {
int boxId = -1; int boxId = -1;
@@ -75,8 +80,8 @@ public class CppCompilationServiceIsolate : ICompilationService
var boxDir = $"/var/local/lib/isolate/{boxId}/box"; var boxDir = $"/var/local/lib/isolate/{boxId}/box";
var sourceFileName = Path.GetFileName(sourceFilePath); var sourceFileName = Path.GetFileName(sourceFilePath);
var boxSourcePath = Path.Combine(boxDir, sourceFileName); var boxSourcePath = Path.Combine(boxDir, sourceFileName);
var boxOutputName = "solution"; var outputFileName = Path.GetFileName(outputExecutablePath);
var boxOutputPath = Path.Combine(boxDir, boxOutputName); var boxOutputPath = Path.Combine(boxDir, outputFileName);
File.Copy(sourceFilePath, boxSourcePath, overwrite: true); File.Copy(sourceFilePath, boxSourcePath, overwrite: true);
@@ -86,9 +91,28 @@ public class CppCompilationServiceIsolate : ICompilationService
// Build compiler arguments // Build compiler arguments
var arguments = new List<string>(compilerFlags); var arguments = new List<string>(compilerFlags);
// Add include directories
if (includeDirectories != null)
{
foreach (var includeDir in includeDirectories.Where(d => !string.IsNullOrWhiteSpace(d)))
{
arguments.Add($"-I{includeDir}");
}
}
// Add additional flags
if (additionalFlags != null)
{
foreach (var flag in additionalFlags.Where(f => !string.IsNullOrWhiteSpace(f)))
{
arguments.Add(flag);
}
}
arguments.Add($"/box/{sourceFileName}"); arguments.Add($"/box/{sourceFileName}");
arguments.Add("-o"); arguments.Add("-o");
arguments.Add($"/box/{boxOutputName}"); arguments.Add($"/box/{outputFileName}");
// Prepare stderr output file for compiler messages // Prepare stderr output file for compiler messages
var stderrFilePath = Path.Combine(boxDir, "compile_stderr.txt"); var stderrFilePath = Path.Combine(boxDir, "compile_stderr.txt");

View File

@@ -1,56 +1,36 @@
namespace LiquidCode.Tester.Worker.Services; namespace LiquidCode.Tester.Worker.Services;
/// <summary>
/// Factory for execution services - always uses Isolate sandbox for security
/// </summary>
public class ExecutionServiceFactory : IExecutionServiceFactory public class ExecutionServiceFactory : IExecutionServiceFactory
{ {
private readonly IServiceProvider _serviceProvider; private readonly IServiceProvider _serviceProvider;
private readonly IConfiguration _configuration;
private readonly ILogger<ExecutionServiceFactory> _logger; private readonly ILogger<ExecutionServiceFactory> _logger;
private readonly bool _useIsolate;
public ExecutionServiceFactory( public ExecutionServiceFactory(
IServiceProvider serviceProvider, IServiceProvider serviceProvider,
IConfiguration configuration,
ILogger<ExecutionServiceFactory> logger) ILogger<ExecutionServiceFactory> logger)
{ {
_serviceProvider = serviceProvider; _serviceProvider = serviceProvider;
_configuration = configuration;
_logger = logger; _logger = logger;
_useIsolate = configuration.GetValue<bool>("Isolate:Enabled", false);
if (_useIsolate) _logger.LogInformation("Execution services configured to use Isolate sandbox");
{
_logger.LogInformation("Isolate sandbox is ENABLED for code execution");
}
else
{
_logger.LogWarning("Isolate sandbox is DISABLED - using standard execution (NOT SECURE for production!)");
}
} }
public IExecutionService GetExecutionService(string language) public IExecutionService GetExecutionService(string language)
{ {
var normalizedLanguage = language.ToLowerInvariant().Replace(" ", ""); var normalizedLanguage = language.ToLowerInvariant().Replace(" ", "");
_logger.LogInformation("Getting execution service for language: {Language} (Isolate: {UseIsolate})", _logger.LogDebug("Getting Isolate execution service for language: {Language}", normalizedLanguage);
normalizedLanguage, _useIsolate);
return normalizedLanguage switch return normalizedLanguage switch
{ {
"c++" or "cpp" => _useIsolate "c++" or "cpp" => _serviceProvider.GetRequiredService<CppExecutionServiceIsolate>(),
? _serviceProvider.GetRequiredService<CppExecutionServiceIsolate>() "java" => _serviceProvider.GetRequiredService<JavaExecutionServiceIsolate>(),
: _serviceProvider.GetRequiredService<CppExecutionService>(), "kotlin" => _serviceProvider.GetRequiredService<KotlinExecutionServiceIsolate>(),
"java" => _useIsolate "c#" or "csharp" => _serviceProvider.GetRequiredService<CSharpExecutionServiceIsolate>(),
? _serviceProvider.GetRequiredService<JavaExecutionServiceIsolate>() "python" => _serviceProvider.GetRequiredService<PythonExecutionServiceIsolate>(),
: _serviceProvider.GetRequiredService<JavaExecutionService>(),
"kotlin" => _useIsolate
? _serviceProvider.GetRequiredService<KotlinExecutionServiceIsolate>()
: _serviceProvider.GetRequiredService<KotlinExecutionService>(),
"c#" or "csharp" => _useIsolate
? _serviceProvider.GetRequiredService<CSharpExecutionServiceIsolate>()
: _serviceProvider.GetRequiredService<CSharpExecutionService>(),
"python" => _useIsolate
? _serviceProvider.GetRequiredService<PythonExecutionServiceIsolate>()
: _serviceProvider.GetRequiredService<PythonExecutionService>(),
_ => throw new NotSupportedException($"Language '{language}' is not supported") _ => throw new NotSupportedException($"Language '{language}' is not supported")
}; };
} }

View File

@@ -1,27 +1,21 @@
namespace LiquidCode.Tester.Worker.Services; namespace LiquidCode.Tester.Worker.Services;
/// <summary>
/// Output checker service - always uses Isolate sandbox for checker execution
/// </summary>
public class OutputCheckerService : IOutputCheckerService public class OutputCheckerService : IOutputCheckerService
{ {
private readonly ILogger<OutputCheckerService> _logger; private readonly ILogger<OutputCheckerService> _logger;
private readonly CheckerService _checkerService; private readonly CheckerServiceIsolate _checkerService;
private readonly CheckerServiceIsolate _checkerServiceIsolate;
private readonly bool _useIsolate;
public OutputCheckerService( public OutputCheckerService(
ILogger<OutputCheckerService> logger, ILogger<OutputCheckerService> logger,
CheckerService checkerService, CheckerServiceIsolate checkerService)
CheckerServiceIsolate checkerServiceIsolate,
IConfiguration configuration)
{ {
_logger = logger; _logger = logger;
_checkerService = checkerService; _checkerService = checkerService;
_checkerServiceIsolate = checkerServiceIsolate;
_useIsolate = configuration.GetValue<bool>("Isolate:Enabled", false);
if (_useIsolate) _logger.LogInformation("Checker service configured to use Isolate sandbox");
{
_logger.LogInformation("Using Isolate sandbox for checker execution");
}
} }
public async Task<bool> CheckOutputAsync(string actualOutput, string expectedOutputPath) public async Task<bool> CheckOutputAsync(string actualOutput, string expectedOutputPath)
@@ -82,12 +76,10 @@ public class OutputCheckerService : IOutputCheckerService
// If custom checker is available, use it // If custom checker is available, use it
if (!string.IsNullOrEmpty(checkerPath) && File.Exists(checkerPath)) if (!string.IsNullOrEmpty(checkerPath) && File.Exists(checkerPath))
{ {
_logger.LogDebug("Using custom checker: {CheckerPath} (Isolate: {UseIsolate})", _logger.LogDebug("Using custom checker in Isolate: {CheckerPath}", checkerPath);
checkerPath, _useIsolate);
var checkerResult = _useIsolate var checkerResult = await _checkerService.CheckAsync(
? await _checkerServiceIsolate.CheckAsync(checkerPath, inputFilePath, actualOutput, expectedOutputPath) checkerPath, inputFilePath, actualOutput, expectedOutputPath);
: await _checkerService.CheckAsync(checkerPath, inputFilePath, actualOutput, expectedOutputPath);
if (!checkerResult.Accepted) if (!checkerResult.Accepted)
{ {

View File

@@ -14,13 +14,13 @@ public class PackageParserService : IPackageParserService
private readonly ILogger<PackageParserService> _logger; private readonly ILogger<PackageParserService> _logger;
private readonly PolygonProblemXmlParser _polygonParser; private readonly PolygonProblemXmlParser _polygonParser;
private readonly AnswerGenerationService _answerGenerator; private readonly AnswerGenerationService _answerGenerator;
private readonly CppCompilationService _cppCompilation; private readonly CppCompilationServiceIsolate _cppCompilation;
public PackageParserService( public PackageParserService(
ILogger<PackageParserService> logger, ILogger<PackageParserService> logger,
PolygonProblemXmlParser polygonParser, PolygonProblemXmlParser polygonParser,
AnswerGenerationService answerGenerator, AnswerGenerationService answerGenerator,
CppCompilationService cppCompilation) CppCompilationServiceIsolate cppCompilation)
{ {
_logger = logger; _logger = logger;
_polygonParser = polygonParser; _polygonParser = polygonParser;

View File

@@ -7,7 +7,6 @@
}, },
"AllowedHosts": "*", "AllowedHosts": "*",
"Isolate": { "Isolate": {
"Enabled": true,
"MaxBoxes": 100 "MaxBoxes": 100
}, },
"Cpp": { "Cpp": {
@@ -76,6 +75,7 @@
}, },
"Python": { "Python": {
"Executable": "python3", "Executable": "python3",
"ValidateSyntax": true,
"Versions": { "Versions": {
"3.8": { "3.8": {
"Executable": "python3.8" "Executable": "python3.8"