Skip to content

Commit

Permalink
Use the FileStream to sign the AppHost when first writing it.
Browse files Browse the repository at this point in the history
  • Loading branch information
jtschuster committed Oct 10, 2024
1 parent ea06637 commit 1c5121d
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ void RewriteAppHost(MemoryMappedFile mappedFile, MemoryMappedViewAccessor access
{
PEUtils.RemoveCetCompatBit(mappedFile, accessor);
}
if (appHostIsPEImage && enableMacOSCodeSign)
{
throw new InvalidDataException("Cannot sign a PE image with MacOS code signing.");
}
}

try
Expand All @@ -126,7 +130,6 @@ void RewriteAppHost(MemoryMappedFile mappedFile, MemoryMappedViewAccessor access
{
// Open the source host file.
appHostSourceStream = new FileStream(appHostSourceFilePath, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 1);
appHostSourceStream.SetLength(appHostSourceStream.Length + Signer.GetCodeSignatureSize(appHostSourceStream.Length));
memoryMappedFile = MemoryMappedFile.CreateFromFile(appHostSourceStream, null, 0, MemoryMappedFileAccess.Read, HandleInheritability.None, true);
memoryMappedViewAccessor = memoryMappedFile.CreateViewAccessor(0, 0, MemoryMappedFileAccess.CopyOnWrite);
Expand All @@ -138,22 +141,24 @@ void RewriteAppHost(MemoryMappedFile mappedFile, MemoryMappedViewAccessor access
RewriteAppHost(memoryMappedFile, memoryMappedViewAccessor);
// Save the transformed host.
using (FileStream fileStream = new FileStream(appHostDestinationFilePath, FileMode.Create))
using (FileStream fileStream = new FileStream(appHostDestinationFilePath, FileMode.Create, FileAccess.ReadWrite))
{
BinaryUtils.WriteToStream(memoryMappedViewAccessor, fileStream, sourceAppHostLength);
// Remove the signature from MachO hosts.
if (!appHostIsPEImage)
{
Signer.TryRemoveCodesign(fileStream, out _);
if (Signer.TryRemoveCodesign(fileStream, out long newLength))
{
fileStream.SetLength(newLength);
}
if (enableMacOSCodeSign)
{
Signer.AdHocSign(fileStream, Path.GetFileName(appHostDestinationFilePath));
newLength = Signer.AdHocSign(fileStream, Path.GetFileName(appHostDestinationFilePath));
fileStream.SetLength(newLength);
}
}
if (assemblyToCopyResourcesFrom != null && appHostIsPEImage)
else if (assemblyToCopyResourcesFrom != null)
{
using var updater = new ResourceUpdater(fileStream, true);
updater.AddResourcesFromPEImage(assemblyToCopyResourcesFrom);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,13 @@ public MachCodeSignature SetCodeSignatureSize(uint codeSignatureSize)

public void EnsureSpace()
{
if (objectFile.LoadCommands.OfType<MachCodeSignature>().Single() is { FileOffset: var offset, FileSize: var size}
&& offset + size <= objectFile.GetOriginalStream().Length)
var codeSignature = objectFile.LoadCommands.OfType<MachCodeSignature>().Single();
var requiredSize = codeSignature.FileOffset + codeSignature.FileSize;
if (requiredSize <= objectFile.GetOriginalStream().Length)
{
return;
}
throw new InvalidDataException("Code signature is not within the file bounds");
objectFile.SetStreamLength(requiredSize);
}

private MachCodeSignature UpdateCodeSignatureLayout(uint codeSignatureSize)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,5 +100,10 @@ internal Stream GetOriginalStream()

return stream.Slice(0, stream.Length);
}

internal void SetStreamLength(long length)
{
stream.SetLength(length);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -445,12 +445,12 @@ internal static bool IsMachOImage(string filePath)
internal static IList<MachObjectFile> Read(Stream stream)
{
var magic = ReadMagic(stream);
var magicBuffer = new byte[4];

List<MachObjectFile> values = new List<MachObjectFile>();

if (magic == MachMagic.FatMagicLittleEndian || magic == MachMagic.FatMagicBigEndian)
{
var magicBuffer = new byte[4];
var headerBuffer = new byte[Math.Max(FatHeader.BinarySize, FatArchHeader.BinarySize)];
stream.ReadFully(headerBuffer.AsSpan(0, FatHeader.BinarySize));
var fatHeader = FatHeader.Read(headerBuffer, isLittleEndian: magic == MachMagic.FatMagicLittleEndian, out var _);
Expand Down
10 changes: 2 additions & 8 deletions src/installer/managed/Microsoft.NET.HostModel/MachO/Signer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ private static void AdHocSignMachO(string executablePath)

using (FileStream inputFile = File.Open(executablePath, FileMode.Open, FileAccess.ReadWrite))
{
inputFile.SetLength(inputFile.Length + GetCodeSignatureSize(inputFile.Length));
long newSize = AdHocSignMachO(inputFile, bundleIdentifier);
inputFile.SetLength(newSize);
}
Expand Down Expand Up @@ -192,14 +191,14 @@ public static long AdHocSignMachO(Stream machStream, string bundleId)
return ((long)codeSignatureCommand.FileOffset) + codeSignatureSize;
}

public static void AdHocSign(Stream stream, string identifier)
public static long AdHocSign(Stream stream, string identifier)
{
if (!MachReader.IsMachOImage(stream))
{
throw new ArgumentException("Stream does not contain a Mach-O image");
}

AdHocSignMachO(stream, identifier);
return AdHocSignMachO(stream, identifier);
}

public static void AdHocSign(string path)
Expand Down Expand Up @@ -275,10 +274,5 @@ public static bool TryRemoveCodesign(string inputPath, string outputPath = null)
}
return removed;
}

internal static long GetCodeSignatureSize(long _)
{
return 1 << 15;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ public void UseMemoryMappedFile()
string tmpFileName = Path.GetFileName(tmpFilePath);
Console.WriteLine($"tmpFilePath: {tmpFilePath}");
long originalFileLength = objectFile.GetOriginalStream().Length;
long tmpFileSize = originalFileLength + Signer.GetCodeSignatureSize(originalFileLength);
// Add space for signature since memorymapped files can't be resized
long tmpFileSize = originalFileLength + 0x8000;

using (var fileStream = new FileStream(tmpFilePath, FileMode.Open, FileAccess.ReadWrite))
{
Expand Down

0 comments on commit 1c5121d

Please sign in to comment.