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

Creating tar file from a directory owned by an unknown group throws an exception on Linux #81658

Closed
chylex opened this issue Feb 5, 2023 · 2 comments

Comments

@chylex
Copy link

chylex commented Feb 5, 2023

Description

Calling TarFile.CreateFromDirectory on a directory that is owned by a group that does not exist in /etc/group, and is only identified by its GID, fails with an exception.

Creating an archive using the tar executable itself works as expected.

Reproduction Steps

I made an example Dockerfile, so that everything is isolated from the actual system, and it's similar to the scenario in which I found the issue (archiving a mounted folder owned by a group and user that exists on the host, but not in the container itself).

It creates a folder /app/example with a file, both of which are owned by a user and group that don't exist in the container. Then installs dotnet-script, and creates and runs a C# script file with the following line:

System.Formats.Tar.TarFile.CreateFromDirectory(Args[0], "out/test.tar", false);
FROM mcr.microsoft.com/dotnet/sdk:7.0

RUN mkdir -p /app/example          && \
    touch /app/example/example.txt && \
    chown -R 1234:1234 /app/example

RUN dotnet tool install --tool-path /app dotnet-script
RUN echo 'System.Formats.Tar.TarFile.CreateFromDirectory(Args[0], "out/test.tar", false);' > /app/Test.csx

# Uncomment to work around the issue:
# RUN groupadd test --gid 1234

WORKDIR /app

ENTRYPOINT ["/app/dotnet-script", "Test.csx", "--", "/app/example/"]

Put the Dockerfile in a directory, then create a directory named out, and run:

docker run --rm --mount type=bind,source="$(pwd)/out",target=/app/out -it "$(docker build -q .)"

This will build and launch the image. The out folder will contain the tar archive.

Expected behavior

Create a tar archive from the folder.

Actual behavior

The application crashes and leaves you with an empty tar archive.

System.IO.IOException: No such file or directory
   at Interop.Sys.GetGroupName(UInt32 gid)
   at System.Formats.Tar.TarWriter.ConstructEntryForWriting(String fullPath, String entryName, FileOptions fileOptions)
   at System.Formats.Tar.TarFile.CreateFromDirectoryInternal(String sourceDirectoryName, Stream destination, Boolean includeBaseDirectory, Boolean leaveOpen)
   at System.Formats.Tar.TarFile.CreateFromDirectory(String sourceDirectoryName, String destinationFileName, Boolean includeBaseDirectory)
   at Submission#0.<<Initialize>>d__0.MoveNext() in /app/Test.csx:line 1

Regression?

No response

Known Workarounds

  • Create the missing groups. It seems that there is no need to create the missing users, only the groups.
  • Use Process to call the tar program manually, since tar does not have the same issue.

Configuration

Same environment as the mcr.microsoft.com/dotnet/sdk:7.0 Docker image. The issue is specific to Linux (or perhaps more broadly Unix, but I have not verified that).

Other information

No response

@ghost ghost added the untriaged New issue has not been triaged by the area owner label Feb 5, 2023
@am11
Copy link
Member

am11 commented Feb 5, 2023

This was fixed in #81070 for .NET 8 and backport is in progress: #81139. You can test it with the preview build of .NET 8 (which dotnet-script doesn't support unfortunately):

FROM mcr.microsoft.com/dotnet/nightly/sdk:8.0-preview

RUN mkdir -p /app/example          && \
    touch /app/example/example.txt && \
    chown -R 1234:1234 /app/example

RUN dotnet new console -o /app
RUN echo 'System.Formats.Tar.TarFile.CreateFromDirectory(args[0], "out/test.tar", false);' > /app/Program.cs
RUN dotnet build /app

# Uncomment to work around the issue:
# RUN groupadd test --gid 1234

WORKDIR /app

RUN mkdir out

ENTRYPOINT ["dotnet", "run", "--", "/app/example/"]
$ docker build . -t gh-81658
$ docker run gh-81658
$ echo $?
0 # no error

Change the first line to FROM mcr.microsoft.com/dotnet/sdk:7.0 and it will currently throw the same exception (exit code 134), until the backport is completed and new release is out.

@smasher164
Copy link
Member

Duplicate of #81047.

@ghost ghost removed the untriaged New issue has not been triaged by the area owner label Feb 6, 2023
@ghost ghost locked as resolved and limited conversation to collaborators Mar 8, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants