XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESystem

【Rust】XFE系统,基于Rust和汇编

公开
关注 0 Fork 0 Star 0
UTF-8
using System.Text;
using System.Text.Json;
using Mono.Cecil;

namespace XfeBootPlatformPatch;

/// <summary>Fail-closed patching of private compiler references, never the NuGet package cache.</summary>
public static class PrivatePlatformFiles
{
    public const string ReceiptName = "XfeBootPlatformV1.json";
    public const string PendingName = "XfeBootPlatformV1.Pending.json";
    private const string LockName = "XfeBootPlatformV1.lock";
    private const string Kind = "ProjectLocalBootProcessorPlatformV1";
    private static readonly JsonSerializerOptions Json = new() { WriteIndented = true };

    public static void Run(string directory)
    {
        directory = ValidateDirectory(directory);
        var corePath = Path.Combine(directory, PlatformPatch.CoreName + ".dll");
        var halPath = Path.Combine(directory, PlatformPatch.HalName + ".dll");
        var driversPath = Path.Combine(directory, LatencyPolicyPatch.DriversName + ".dll");
        var corelibPath = Path.Combine(directory, LatencyPolicyPatch.CoreLibName + ".dll");
        var receiptPath = Path.Combine(directory, ReceiptName);
        var pendingPath = Path.Combine(directory, PendingName);
        var lockPath = Path.Combine(directory, LockName);
        RejectReparse(corePath); RejectReparse(halPath); RejectReparse(driversPath); RejectReparse(corelibPath);
        RejectReparseIfPresent(receiptPath); RejectReparseIfPresent(pendingPath); RejectReparseIfPresent(lockPath);
        using var locked = new FileStream(lockPath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
        if (File.Exists(pendingPath))
            throw new InvalidOperationException("An interrupted platform write exists. Restore ALL FOUR private references through the pinned Cosmos patcher and inspect the pending receipt before retrying.");
        var coreBytes = File.ReadAllBytes(corePath);
        var halBytes = File.ReadAllBytes(halPath);
        var driversBytes = File.ReadAllBytes(driversPath);
        var corelibBytes = File.ReadAllBytes(corelibPath);
        var coreHash = PlatformPatch.Hash(coreBytes);
        var halHash = PlatformPatch.Hash(halBytes);
        var driversHash = PlatformPatch.Hash(driversBytes);
        var corelibHash = PlatformPatch.Hash(corelibBytes);
        VerifyOfficialInputs(directory);
        var toolHash = PlatformPatch.Hash(File.ReadAllBytes(typeof(PrivatePlatformFiles).Assembly.Location));
        using var core = Read(coreBytes);
        using var hal = Read(halBytes);
        using var drivers = Read(driversBytes);
        using var corelib = Read(corelibBytes);
        bool originalCore = coreHash == PlatformPatch.CoreOriginalSha256;
        bool originalHal = halHash == PlatformPatch.HalOriginalSha256;
        bool originalDrivers = driversHash == LatencyPolicyPatch.DriversOriginalSha256;
        bool originalCorelib = LatencyPolicyPatch.OriginalMonitorState(corelib);
        if (!originalCore || !originalHal || !originalDrivers || !originalCorelib)
        {
            if (originalCore || originalHal || originalDrivers || originalCorelib || !File.Exists(receiptPath))
                throw new InvalidOperationException("Unknown or partly patched platform references are not trusted.");
            var receipt = JsonSerializer.Deserialize<Receipt>(File.ReadAllText(receiptPath, Encoding.UTF8)) ?? throw new InvalidOperationException("Empty platform receipt.");
            if (receipt.Kind != Kind || receipt.PackageVersion != PlatformPatch.PackageVersion ||
                receipt.CoreOriginalSha256 != PlatformPatch.CoreOriginalSha256 || receipt.HalOriginalSha256 != PlatformPatch.HalOriginalSha256 ||
                receipt.CoreAfterSha256 != coreHash || receipt.HalAfterSha256 != halHash || receipt.ToolSha256 != toolHash ||
                receipt.DriversOriginalSha256 != LatencyPolicyPatch.DriversOriginalSha256 || receipt.DriversAfterSha256 != driversHash || receipt.CoreLibAfterSha256 != corelibHash ||
                receipt.OfficialPlugsSha256 != LatencyPolicyPatch.OfficialPlugsSha256 || receipt.OfficialCoreLibSha256 != LatencyPolicyPatch.OfficialCoreLibSha256 ||
                receipt.SchedulerTimerIntervalMs != 1 || receipt.XhciPolledDrainIntervalMs != 1 || receipt.SuppressedMonitorLogCalls != LatencyPolicyPatch.SuppressedMonitorLogCalls ||
                !receipt.MonitorWaitAlgorithmsPreserved || !receipt.XhciMsiPathPreserved || !receipt.SchedulerAccountingQuantumPreserved ||
                !string.Equals(receipt.PrivateDirectory, directory, StringComparison.OrdinalIgnoreCase) || receipt.SchedulerCpuCount != 1 ||
                !receipt.NormalTimerLogRemoved || !receipt.HardwareApicRoutingPreserved ||
                !receipt.DeviceIrqSchedulerUsesLogicalCpuZero || receipt.SchedulerCpuIndex != 0 || receipt.SchedulerCpuIndexSitesPatched != 2)
                throw new InvalidOperationException("Private platform references do not match their pinned-origin verification receipt.");
            PlatformPatch.Verify(core, hal);
            LatencyPolicyPatch.VerifyIo(drivers, corelib);
            Console.WriteLine("XFE boot processor platform patch verified; no files changed.");
            return;
        }

        // All input and IL guards finish before any destination or receipt is modified.
        PlatformPatch.Apply(core, hal);
        LatencyPolicyPatch.ApplyIo(drivers, corelib);
        var afterCore = Write(core);
        var afterHal = Write(hal);
        var afterDrivers = Write(drivers);
        var afterCorelib = Write(corelib);
        using (var roundCore = Read(afterCore))
        using (var roundHal = Read(afterHal)) PlatformPatch.Verify(roundCore, roundHal);
        using (var roundDrivers = Read(afterDrivers))
        using (var roundCorelib = Read(afterCorelib)) LatencyPolicyPatch.VerifyIo(roundDrivers, roundCorelib);
        var next = new Receipt
        {
            Kind = Kind, PackageVersion = PlatformPatch.PackageVersion, PrivateDirectory = directory,
            CoreOriginalSha256 = PlatformPatch.CoreOriginalSha256, HalOriginalSha256 = PlatformPatch.HalOriginalSha256,
            CoreAfterSha256 = PlatformPatch.Hash(afterCore), HalAfterSha256 = PlatformPatch.Hash(afterHal),
            DriversOriginalSha256 = LatencyPolicyPatch.DriversOriginalSha256, DriversAfterSha256 = PlatformPatch.Hash(afterDrivers),
            CoreLibGeneratedInputSha256 = corelibHash, CoreLibAfterSha256 = PlatformPatch.Hash(afterCorelib),
            OfficialPlugsSha256 = LatencyPolicyPatch.OfficialPlugsSha256, OfficialCoreLibSha256 = LatencyPolicyPatch.OfficialCoreLibSha256,
            SchedulerTimerIntervalMs = 1, XhciPolledDrainIntervalMs = 1, SuppressedMonitorLogCalls = LatencyPolicyPatch.SuppressedMonitorLogCalls,
            MonitorWaitAlgorithmsPreserved = true, XhciMsiPathPreserved = true, SchedulerAccountingQuantumPreserved = true,
            ToolSha256 = toolHash, SchedulerCpuCount = 1, NormalTimerLogRemoved = true,
            HardwareApicRoutingPreserved = true, DeviceIrqSchedulerUsesLogicalCpuZero = true,
            SchedulerCpuIndex = 0, SchedulerCpuIndexSitesPatched = 2
        };
        byte[] receiptBytes = Encoding.UTF8.GetBytes(JsonSerializer.Serialize(next, Json));
        if (PlatformPatch.Hash(File.ReadAllBytes(corePath)) != coreHash || PlatformPatch.Hash(File.ReadAllBytes(halPath)) != halHash ||
            PlatformPatch.Hash(File.ReadAllBytes(driversPath)) != driversHash || PlatformPatch.Hash(File.ReadAllBytes(corelibPath)) != corelibHash)
            throw new IOException("Platform input changed during verification.");
        // Four renames cannot form one filesystem transaction. The durable pending marker is
        // written first and remains on ANY failure; later builds then reject the partial pair.
        using (var pending = new FileStream(pendingPath, FileMode.CreateNew, FileAccess.Write, FileShare.None, 4096, FileOptions.WriteThrough))
        { pending.Write(receiptBytes); pending.Flush(true); }
        Replace(corePath, afterCore);
        Replace(halPath, afterHal);
        Replace(driversPath, afterDrivers);
        Replace(corelibPath, afterCorelib);
        if (PlatformPatch.Hash(File.ReadAllBytes(corePath)) != next.CoreAfterSha256 || PlatformPatch.Hash(File.ReadAllBytes(halPath)) != next.HalAfterSha256 ||
            PlatformPatch.Hash(File.ReadAllBytes(driversPath)) != next.DriversAfterSha256 || PlatformPatch.Hash(File.ReadAllBytes(corelibPath)) != next.CoreLibAfterSha256)
            throw new IOException("Platform output readback differs from the verified pair.");
        Replace(receiptPath, receiptBytes);
        File.Delete(pendingPath);
        Console.WriteLine("XFE boot processor platform ready: one executing BSP, logical CPU 0; physical ACPI topology and APIC routing unchanged.");
        Console.WriteLine("XFE normal timer ISR logging removed; tick counter, invalid-stack diagnostics and scheduler dispatch preserved. Native acceptance still required.");
        Console.WriteLine("XFE latency policy ready: LAPIC 1 ms, no-MSI xHCI drain 1 ms; monitor logging suppressed, original waits/IRQ/GC/queue algorithms preserved.");
    }

    private static void VerifyOfficialInputs(string directory)
    {
        string? project = directory;
        while (project is not null && !File.Exists(Path.Combine(project, "XFESystem.Kernel.csproj"))) project = Path.GetDirectoryName(project);
        string packages = Path.GetFullPath(Path.Combine(project!, "..", "..", ".tools", "CSharpBoot", "NuGetPackages"));
        string plugs = Path.Combine(packages, "cosmos.kernel.plugs", "3.0.94", "runtimes", "linux-x64", "lib", "net10.0", "Cosmos.Kernel.Plugs.dll");
        string corelib = Path.Combine(packages, "microsoft.netcore.app.runtime.nativeaot.linux-x64", "10.0.12", "runtimes", "linux-x64", "native", "System.Private.CoreLib.dll");
        if (PlatformPatch.Hash(File.ReadAllBytes(plugs)) != LatencyPolicyPatch.OfficialPlugsSha256 ||
            PlatformPatch.Hash(File.ReadAllBytes(corelib)) != LatencyPolicyPatch.OfficialCoreLibSha256)
            throw new InvalidOperationException("The fixed Cosmos plugs/.NET 10 NativeAOT source packages differ; no private runtime is written.");
    }

    public static string ValidateDirectory(string path)
    {
        var directory = Path.TrimEndingDirectorySeparator(Path.GetFullPath(path));
        if (!Directory.Exists(directory) || !directory.EndsWith(Path.Combine("cosmos", "ref"), StringComparison.OrdinalIgnoreCase))
            throw new ArgumentException("Only a private Kernel obj/.../cosmos/ref directory is accepted.");
        string? projectRoot = directory;
        while (projectRoot is not null && !File.Exists(Path.Combine(projectRoot, "XFESystem.Kernel.csproj")))
            projectRoot = Path.GetDirectoryName(projectRoot);
        if (projectRoot is null || !directory.StartsWith(Path.Combine(projectRoot, "obj") + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase))
            throw new ArgumentException("Platform patches must remain under the kernel project's private obj directory.");
        // Check the entire resolved textual ancestor chain, including the project and drive,
        // rather than stopping just below the project and accepting a junction above it.
        for (string? current = directory; current is not null; current = Path.GetDirectoryName(current)) RejectReparse(current);
        return directory;
    }

    private static void RejectReparseIfPresent(string path)
    {
        // File.Exists is false for a dangling symlink. GetAttributes still sees
        // the link itself, so it cannot redirect an OpenOrCreate lock outside obj.
        try { RejectReparse(path); }
        catch (FileNotFoundException) { }
        catch (DirectoryNotFoundException) { }
    }

    private static void RejectReparse(string path)
    {
        if ((File.GetAttributes(path) & FileAttributes.ReparsePoint) != 0)
            throw new ArgumentException("A private platform path cannot traverse a symbolic link or junction.");
    }

    private static AssemblyDefinition Read(byte[] bytes) => AssemblyDefinition.ReadAssembly(new MemoryStream(bytes, false), new ReaderParameters { InMemory = true });
    private static byte[] Write(AssemblyDefinition assembly)
    {
        using var stream = new MemoryStream();
        assembly.Write(stream);
        return stream.ToArray();
    }
    private static void Replace(string path, byte[] bytes)
    {
        // CreateNew and a fresh name ensure cleanup can only remove our own temporary file.
        var temporary = path + "." + Guid.NewGuid().ToString("N") + ".tmp";
        try
        {
            using (var output = new FileStream(temporary, FileMode.CreateNew, FileAccess.Write, FileShare.None, 4096, FileOptions.WriteThrough))
            { output.Write(bytes); output.Flush(true); }
            File.Move(temporary, path, true);
        }
        finally { if (File.Exists(temporary)) File.Delete(temporary); }
    }
    public sealed class Receipt
    {
        public string Kind { get; set; } = "";
        public string PackageVersion { get; set; } = "";
        public string PrivateDirectory { get; set; } = "";
        public string CoreOriginalSha256 { get; set; } = "";
        public string HalOriginalSha256 { get; set; } = "";
        public string CoreAfterSha256 { get; set; } = "";
        public string HalAfterSha256 { get; set; } = "";
        public string DriversOriginalSha256 { get; set; } = "";
        public string DriversAfterSha256 { get; set; } = "";
        public string CoreLibGeneratedInputSha256 { get; set; } = "";
        public string CoreLibAfterSha256 { get; set; } = "";
        public string OfficialPlugsSha256 { get; set; } = "";
        public string OfficialCoreLibSha256 { get; set; } = "";
        public uint SchedulerTimerIntervalMs { get; set; }
        public uint XhciPolledDrainIntervalMs { get; set; }
        public int SuppressedMonitorLogCalls { get; set; }
        public bool MonitorWaitAlgorithmsPreserved { get; set; }
        public bool XhciMsiPathPreserved { get; set; }
        public bool SchedulerAccountingQuantumPreserved { get; set; }
        public string ToolSha256 { get; set; } = "";
        public uint SchedulerCpuCount { get; set; }
        public bool NormalTimerLogRemoved { get; set; }
        public bool HardwareApicRoutingPreserved { get; set; }
        public bool DeviceIrqSchedulerUsesLogicalCpuZero { get; set; }
        public uint SchedulerCpuIndex { get; set; }
        public int SchedulerCpuIndexSitesPatched { get; set; }
        public bool NativeGuestTested { get; set; }
    }
}