From c3cb4044c2000d840bd8b0a6082932c116f98b2e Mon Sep 17 00:00:00 2001 From: Irem Yuksel Date: Wed, 8 Apr 2026 17:37:52 +0000 Subject: [PATCH 1/3] Merged PR 59736: [internal/release/8.0] Add check for negative ExtentedAttributes size in TarHeader Adds check for the "size" attribute in the ExdendedAttributes section of a tar file to prevent infinite loop with negative size. Follows the same throw logic for TarHeader's size. The negative sized tar file cannot be reproduced using .NET, hence the lack of tests. --- .../src/System/Formats/Tar/TarHeader.Read.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHeader.Read.cs b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHeader.Read.cs index 5036a59334d85b..52df8a8c52ffb7 100644 --- a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHeader.Read.cs +++ b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHeader.Read.cs @@ -133,6 +133,11 @@ internal void ReplaceNormalAttributesWithExtended(Dictionary? di // The 'size' header field only fits 12 bytes, so the data section length that surpases that limit needs to be retrieved if (TarHelpers.TryGetStringAsBaseTenLong(ExtendedAttributes, PaxEaSize, out long size)) { + if (size < 0) + { + throw new InvalidDataException(SR.Format(SR.TarSizeFieldNegative)); + } + _size = size; } From feca9d8c930b177e349cfe3074d0a3f9b8342982 Mon Sep 17 00:00:00 2001 From: Alin Pahontu Date: Mon, 13 Apr 2026 08:52:20 +0000 Subject: [PATCH 2/3] Merged PR 59616: Fix Windows tar symlink checks - .NET 8.0 Fix Windows tar vulnerability that allows creating a symlink to a file (and only a file, not a directory) to anywhere on the same drive where the tar is extracted. ---- #### AI description (iteration 1) #### PR Classification Bug fix to correct Windows tar symlink validation when extracting archives with rooted paths outside the destination directory. #### PR Summary Fixes a security issue in tar extraction on Windows where symlinks with rooted paths (like `\Temp\file.txt`) were incorrectly validated, allowing extraction outside the intended destination directory. The fix replaces `Path.IsPathFullyQualified()` with `Path.IsPathRooted()` and ensures proper path resolution. - `TarEntry.cs`: Changed symlink validation logic from `Path.IsPathFullyQualified()` to `Path.IsPathRooted()` with `Path.GetFullPath()` for both file destination paths and link targets to properly detect and reject rooted paths pointing outside the destination - `TarFile.ExtractToDirectory.File.Tests.Windows.cs`: Added test `ExtractToDirectory_RejectsSymlinkWithRootedTargetOutsideDestination()` to verify that symlinks with rooted targets outside the destination directory throw `IOException` and are not created --- .../src/System/Formats/Tar/TarEntry.cs | 15 +++++++++---- ...e.ExtractToDirectory.File.Tests.Windows.cs | 21 +++++++++++++++++++ 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarEntry.cs b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarEntry.cs index 83f915875d266e..4ae74325894d59 100644 --- a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarEntry.cs +++ b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarEntry.cs @@ -347,6 +347,13 @@ internal Task ExtractRelativeToDirectoryAsync(string destinationDirectoryPath, b // LinkName is an absolute path, or path relative to the fileDestinationPath directory. // We don't check if the LinkName is empty. In that case, creation of the link will fail because link targets can't be empty. string linkName = ArchivingUtils.SanitizeEntryFilePath(LinkName, preserveDriveRoot: true); + // On Windows, reject rooted but not fully qualified paths ("\Windows\win.ini", "C:foo"). + // They resolve ambiguously based on the current drive or working directory. + // Symlinks are resolved at access time, so Path.GetFullPath cannot reliably determine which drive will be used. + if (OperatingSystem.IsWindows() && Path.IsPathRooted(linkName) && !Path.IsPathFullyQualified(linkName)) + { + throw new IOException(SR.Format(SR.TarExtractingResultsLinkOutside, linkName, destinationDirectoryPath)); + } string? linkDestination = GetFullDestinationPath( destinationDirectoryPath, Path.IsPathFullyQualified(linkName) ? linkName : Path.Join(Path.GetDirectoryName(fileDestinationPath), linkName)); @@ -576,10 +583,10 @@ private FileStreamOptions CreateFileStreamOptions(bool isAsync) if (!OperatingSystem.IsWindows()) { - const UnixFileMode OwnershipPermissions = - UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute | - UnixFileMode.GroupRead | UnixFileMode.GroupWrite | UnixFileMode.GroupExecute | - UnixFileMode.OtherRead | UnixFileMode.OtherWrite | UnixFileMode.OtherExecute; + const UnixFileMode OwnershipPermissions = + UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute | + UnixFileMode.GroupRead | UnixFileMode.GroupWrite | UnixFileMode.GroupExecute | + UnixFileMode.OtherRead | UnixFileMode.OtherWrite | UnixFileMode.OtherExecute; // Restore permissions. // For security, limit to ownership permissions, and respect umask (through UnixCreateMode). diff --git a/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.ExtractToDirectory.File.Tests.Windows.cs b/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.ExtractToDirectory.File.Tests.Windows.cs index 19d5dc19627db2..a05d4c2de245a4 100644 --- a/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.ExtractToDirectory.File.Tests.Windows.cs +++ b/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.ExtractToDirectory.File.Tests.Windows.cs @@ -27,5 +27,26 @@ public void Extract_SpecialFiles_Windows_ThrowsInvalidOperation() Assert.Equal(0, Directory.GetFileSystemEntries(destination).Count()); } + + [ConditionalFact(typeof(MountHelper), nameof(MountHelper.CanCreateSymbolicLinks))] + public void ExtractToDirectory_RejectsSymlinkWithRootedTargetOutsideDestination() + { + using TempDirectory root = new TempDirectory(); + string destDir = Path.Combine(root.Path, "dest"); + Directory.CreateDirectory(destDir); + + // A rooted path that points outside destDir (the target doesn't need to exist). + string rootedLinkTarget = @"\Temp\temp.ini"; + + string tarPath = Path.Combine(root.Path, "windows_symlink.tar"); + using (FileStream stream = new FileStream(tarPath, FileMode.Create, FileAccess.Write)) + using (TarWriter writer = new TarWriter(stream, leaveOpen: false)) + { + writer.WriteEntry(new PaxTarEntry(TarEntryType.SymbolicLink, "outside.txt") { LinkName = rootedLinkTarget }); + } + + Assert.Throws(() => TarFile.ExtractToDirectory(tarPath, destDir, overwriteFiles: true)); + Assert.Empty(Directory.EnumerateFileSystemEntries(destDir)); + } } } From a6bde67c455f2ac219988c7a66171631090b6f65 Mon Sep 17 00:00:00 2001 From: "Sean Reeser (CSI Interfusion Inc)" Date: Wed, 29 Apr 2026 22:59:23 +0000 Subject: [PATCH 3/3] Merged PR 60606: Updated Versions.props - MicrosoftNativeQuicMsQuicSchannelVersion 2.4.18 Updated Versions.props - MicrosoftNativeQuicMsQuicSchannelVersion 2.4.18 ---- #### AI description (iteration 1) #### PR Classification Dependency version update to upgrade the MsQuic Schannel package from version 2.4.17 to 2.4.18. #### PR Summary This pull request updates the MsQuic Schannel dependency version in the project's version management file. - `eng/Versions.props`: Updated `MicrosoftNativeQuicMsQuicSchannelVersion` from 2.4.17 to 2.4.18 --- eng/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Versions.props b/eng/Versions.props index 564eb4eed4c7e3..bf21de4c16379e 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -233,7 +233,7 @@ 8.0.0-rtm.25625.2 - 2.4.17 + 2.4.18 16.0.5-alpha.1.25311.1 16.0.5-alpha.1.25311.1