Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[release/7.0] TAR: Trim file type bits from mode header #77612

Merged
merged 3 commits into from
Nov 11, 2022

Conversation

jeffhandley
Copy link
Member

@jeffhandley jeffhandley commented Oct 28, 2022

Backport of #77151 to release/7.0. Requested for inclusion in the December servicing release.

Customer Impact

Some tools, including docker, create TAR archives that include two pieces of data where the Unix file mode is stored, capturing both the Unix file mode and the file type. Our TAR extraction does not ignore the additional bits that represent the file type, and this leads to a crash because of an unexpected/invalid Unix file mode. A customer reported this issue when trying to extract a docker image as a TAR archive.

This was customer-reported by @WeihanLi using .NET 7.0 RC2. They reported the issue on CentOS but other Unix platforms are also affected, but Windows is not affected.

The fix is to align with the behavior of other tar tools and discard unrecognized bits in the file mode value to ensure the value is recognized and valid.

Testing

A unit test was added that extracts a TAR archive that includes entries with file mode values that previously caused the issue.

Risk

Low risk. The extraction now matches the spec for this specific value, ignoring the file type bits while recognizing the file mode bits. Extraction will still throw for invalid file modes.

* Trim file type bits from mode header

* Define and use ValidUnixFileModes

* Rev System.Formats.Tar.TestData version

* Move ValidUnixFileModes to shared helpers
@ghost
Copy link

ghost commented Oct 28, 2022

Tagging subscribers to this area: @dotnet/area-system-io
See info in area-owners.md if you want to be subscribed.

Issue Details

Backport of #77151 to release/7.0

Customer Impact

Some tools, including docker, create TAR archives that include two pieces of data where the Unix file mode is stored, capturing both the Unix file mode and the file type. Our TAR extraction does not ignore the additional bits that represent the file type, and this leads to a crash because of an unexpected/invalid Unix file mode. A customer reported this issue when trying to extract a docker image as a TAR archive.

This was customer-reported by @WeihanLi using .NET 7.0 RC2. They reported the issue on CentOS but other Unix platforms are also affected, but Windows is not affected.

The fix is to discard unrecognized bits in the file mode value to ensure the value is recognized and valid.

Testing

A unit test was added that extracts a TAR archive that includes entries with file mode values that previously caused the issue.

Risk

Low risk. The extraction now matches the spec for this specific value, ignoring the file type bits while recognizing the file mode bits. Extraction will still throw for invalid file modes.

Author: jeffhandley
Assignees: -
Labels:

area-System.IO

Milestone: -

@jeffhandley
Copy link
Member Author

@dotnet/area-system-io-compression Can you review the backport template for accuracy please to make sure I interpreted it all correctly?

Copy link
Member

@jozkee jozkee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Template also looks good. I would add that this change makes S.F.Tar align with the behavior of other tar tools.

@jozkee
Copy link
Member

jozkee commented Oct 31, 2022

CI issue is because the new test uses a newly version of System.Formats.Tar.TestData. My guess is that you need to bump the version on this PR.

<SystemFormatsTarTestDataVersion>7.0.0-beta.22503.1</SystemFormatsTarTestDataVersion>

cc @dotnet/area-infrastructure-libraries

@jeffhandley jeffhandley added the Servicing-consider Issue for next servicing release review label Nov 1, 2022
@leecow leecow added Servicing-approved Approved for servicing release and removed Servicing-consider Issue for next servicing release review labels Nov 1, 2022
@leecow leecow modified the milestones: 7.0.x, 7.0.1 Nov 1, 2022
@carlossanlop
Copy link
Member

carlossanlop commented Nov 3, 2022

I resolved the merge conflict. This PR introduced version 22524 of the System.Formats.Tar.TestData package, but the version we are already importing in Versions.props is newer: 22531. So I am keeping the newer one, and this should work. I'll monitor the CI.

set
{
if ((int)value is < 0 or > 4095) // 4095 in decimal is 7777 in octal
if ((value & ~TarHelpers.ValidUnixFileModes) != 0) // throw on invalid UnixFileModes
Copy link
Member

@stephentoub stephentoub Nov 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We discussed and agreed upon throwing here rather than just masking? What does that mean for roundtripping an existing archive that has the invalid bits in it... will that no longer be roundtrippable because it will throw, or is there a separate code path that handles just masking off the invalid bits? And if the latter, which is what the comment added on the getter suggests, shouldn't this be consistent with that?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Roundtripping works fine. I tested with the archive with invalid bits attached to the original issue.

Looking at the references of _mode, there might be a way in where we end up with invalid bits, perhaps with a Pax Extended Attribute. Regardless of that, we would be fine still, because of the mask in the getter.

shouldn't this be consistent with that?

Probably yes, but not for this PR.

@carlossanlop
Copy link
Member

Some unrelated infra failures that were affecting many PRs 8 days ago. I'll restart the CI with a rebase by closing and reopening.

@carlossanlop
Copy link
Member

CI is still having trouble with the docker images. One of the legs had no coverage for the tar tests.

Console log: 'System.Formats.Tar.Tests' from job c7cb00e3-fcca-42c7-aaaf-c9197d4a9dc0 (windows.10.amd64.serverrs5.open.svc) using docker image mcr.microsoft.com/dotnet-buildtools/prereqs:nanoserver-1809-helix-amd64-08e8e40-20200107182504 on a000OEL
running %HELIX_CORRELATION_PAYLOAD%\scripts\fdb85036f9c64dbcaf28ab9c526aec1c\execute.cmd in C:\h\w\C4870A88\w\B44D0974\e max 900 seconds

The issue is being tracked by dotnet/arcade#11554 which may already have a fix. I'll restart the failed legs.

@carlossanlop
Copy link
Member

This is ready to merge. The infra docker problem has been fixed. The new CI failures in the re-run are unrelated:

LibraryImportGenerator.UnitTests.Compiles.ValidateNoGeneratedOuptutForNoImport(id: "Compiles.cs:650", source: "\r\nusing System.Runtime.InteropServices;\r\npubli"..., framework: Standard) [FAIL]
      NuGet.Protocol.Core.Types.FatalProtocolException : Unable to load the service index for source https://pkgs.dev.azure.com/dnceng/public/_packaging/darc-pub-dotnet-emsdk-6b7d1f47/nuget/v3/index.json.
      ---- System.Net.Http.HttpRequestException : Response status code does not indicate success: 500 (Internal Server Error - Request was blocked due to exceeding usage of resource 'Concurrency' in namespace 'IPAddress'. For more information on why your request was blocked, see the topic "Rate limits" on the Microsoft Web site (https://go.microsoft.com/fwlink/?LinkId=823950). (DevOps Activity ID: FB02FBD9-D617-4C3F-9B9F-FAC092FB0153)).
===========================================================================================================

C:\h\w\A73C09B2\w\B77D0945\e>xunit.console.exe Microsoft.Extensions.Logging.Console.Tests.dll -xml testResults.xml -nologo -nocolor -notrait category=IgnoreForCI -notrait category=OuterLoop -notrait category=failing  
  Discovering: Microsoft.Extensions.Logging.Console.Tests (app domain = on [no shadow copy], method display = ClassAndMethod, method display options = None)
  Discovered:  Microsoft.Extensions.Logging.Console.Tests (found 110 of 112 test cases)
  Starting:    Microsoft.Extensions.Logging.Console.Tests (parallel test collections = on, max threads = 2)

Unhandled Exception: System.IO.FileLoadException: Could not load file or assembly 'System.Text.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
   at Microsoft.Extensions.Logging.ConsoleLoggerExtensions.AddConsole(ILoggingBuilder builder)
   at Microsoft.Extensions.DependencyInjection.LoggingServiceCollectionExtensions.AddLogging(IServiceCollection services, Action`1 configure)
   at Microsoft.Extensions.Logging.Console.Test.ConsoleLoggerTest.<>c.<AddConsole_IsOutputRedirected_ColorDisabled>b__21_0()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.DotNet.RemoteExecutor.Program.Main(String[] args)
    Microsoft.Extensions.Logging.Console.Test.ConsoleLoggerTest.AddConsole_IsOutputRedirected_ColorDisabled [FAIL]
      Microsoft.DotNet.RemoteExecutor.RemoteExecutionException : Remote process failed with an unhandled exception.
      Stack Trace:
        
        Child exception:
          System.IO.FileLoadException: Could not load file or assembly 'System.Text.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
        File name: 'System.Text.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'
           at Microsoft.Extensions.Logging.ConsoleLoggerExtensions.AddConsole(ILoggingBuilder builder)
           at Microsoft.Extensions.DependencyInjection.LoggingServiceCollectionExtensions.AddLogging(IServiceCollection services, Action`1 configure)
           at Microsoft.Extensions.Logging.Console.Test.ConsoleLoggerTest.<>c.<AddConsole_IsOutputRedirected_ColorDisabled>b__21_0()
        
        WRN: Assembly binding logging is turned OFF.
        To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1.
        Note: There is some performance penalty associated with assembly bind failure logging.
        To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fusion!EnableLog].
        
        
        Child process:
          Microsoft.Extensions.Logging.Console.Tests, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60 Microsoft.Extensions.Logging.Console.Test.ConsoleLoggerTest+<>c Void <AddConsole_IsOutputRedirected_ColorDisabled>b__21_0()
        
        
  Finished:    Microsoft.Extensions.Logging.Console.Tests
=== TEST EXECUTION SUMMARY ===
   Microsoft.Extensions.Logging.Console.Tests  Total: 621, Errors: 0, Failed: 1, Skipped: 0, Time: 5.809s
----- end Thu 11/10/2022 21:34:42.57 ----- exit code 1 ----------------------------------------------------------
    MonoTests.System.Runtime.Caching.CountersTest.Basic_Counters [FAIL]
      System.InvalidOperationException : Category does not exist.

@carlossanlop carlossanlop merged commit 3853aa0 into release/7.0 Nov 11, 2022
@carlossanlop carlossanlop deleted the backport/pr-77151-to-release/7.0 branch November 11, 2022 01:41
@ghost ghost locked as resolved and limited conversation to collaborators Dec 22, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Formats.Tar Servicing-approved Approved for servicing release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants