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

build: %files from stage fails to copy relative symlinks #2607

Closed
dtrudg opened this issue Jan 31, 2024 · 1 comment · Fixed by #2924
Closed

build: %files from stage fails to copy relative symlinks #2607

dtrudg opened this issue Jan 31, 2024 · 1 comment · Fixed by #2924
Assignees
Labels
bug Something isn't working

Comments

@dtrudg
Copy link
Member

dtrudg commented Jan 31, 2024

Version of Singularity

main

Describe the bug

The following definition file fails to build:

09:38 am $ cat test.def 
BootStrap: docker
From: ubuntu:latest
Stage: devel

%post
mkdir -p /usr/mydir/mysubdir
ln -s ../bin/true /usr/mydir/true
ln -s ../../bin/true /usr/mydir/mysubdir/true

BootStrap: docker
From: ubuntu:latest
Stage: final

%files from devel
/usr/mydir
09:38 am $ sudo singularity build test.sif test.def
[sudo] password for dtrudg-sylabs: 
WARNING: 'nodev' mount option set on /tmp, it could be a source of failure during build process
INFO:    Starting build...
INFO:    Fetching OCI image...
28.2MiB / 28.2MiB [===================================================================================] 100 % 0.0 b/s 0s
INFO:    Extracting OCI image...
INFO:    Inserting Singularity configuration...
INFO:    Running post scriptlet
+ mkdir -p /usr/mydir/mysubdir
+ ln -s ../bin/true /usr/mydir/true
+ ln -s ../../bin/true /usr/mydir/mysubdir/true
INFO:    Fetching OCI image...
28.2MiB / 28.2MiB [===================================================================================] 100 % 0.0 b/s 0s
INFO:    Extracting OCI image...
INFO:    Inserting Singularity configuration...
INFO:    Copying /usr/mydir to 
FATAL:   While performing build: unable to copy files from stage to container fs: while copying [/tmp/build-temp-2697402686/rootfs/usr/mydir] to /tmp/build-temp-2218967937/rootfs/usr/mydir: invalid symlink "/tmp/build-temp-2218967937/rootfs/usr/mydir/mysubdir/true" -> "../../bin/true"
@dtrudg dtrudg added the bug Something isn't working label Jan 31, 2024
@dtrudg dtrudg self-assigned this Jan 31, 2024
@dtrudg
Copy link
Member Author

dtrudg commented Jan 31, 2024

The error invalid symlink is being raised from the docker/docker pkg/archive CopyWithTar code.

@dtrudg dtrudg added this to the SingularityCE 4.2.0 milestone Apr 26, 2024
dtrudg added a commit to dtrudg/singularity that referenced this issue May 15, 2024
In a build stage, a valid relative symlink can be created that points to a
location in the rootfs that is above the location of the symlink. E.g.:

  /usr/mydir/mysubdir/true -> ../../../bin/true

This symlink is valid in the rootfs. It resolves to `/bin/true`.

If we attempt to copy `/usr/mydir` into a new build stage, then prior to
this PR the symlink would cause the copy to fail.

We have been using `CopyFromTar` to copy from src `<stage1>/usr/mydir`,
to `<stage2>/usr/mydir`. The `CopyFromTar` routines enforce that the
target of a hard link or symlink must be under dst, or a fatal error is
raised to avoid a breakout attack.

When copying between stages our boundary is not dst, but the top level
of the destination stage's rootfs. We must allow links to be created
that are above dst, but withing the stage rootfs.

To resolve the issue, bring over enough code from
`docker/docker/pkg/archive` that we can implement a
`CopyFromTarWithRoot`, that performs the same as `CopyFromTar`, except
that we can specify a destination root directory. Any hard links and
symlink targets under this destination root directory are valid.

Fixes sylabs#2607
dtrudg added a commit to dtrudg/singularity that referenced this issue May 15, 2024
In a build stage, a valid relative symlink can be created that points to a
location in the rootfs that is above the location of the symlink. E.g.:

  /usr/mydir/mysubdir/true -> ../../../bin/true

This symlink is valid in the rootfs. It resolves to `/bin/true`.

If we attempt to copy `/usr/mydir` into a new build stage, then prior to
this PR the symlink would cause the copy to fail.

We have been using `CopyFromTar` to copy from src `<stage1>/usr/mydir`,
to `<stage2>/usr/mydir`. The `CopyFromTar` routines enforce that the
target of a hard link or symlink must be under dst, or a fatal error is
raised to avoid a breakout attack.

When copying between stages our boundary is not dst, but the top level
of the destination stage's rootfs. We must allow links to be created
that are above dst, but withing the stage rootfs.

To resolve the issue, bring over enough code from
`docker/docker/pkg/archive` that we can implement a
`CopyFromTarWithRoot`, that performs the same as `CopyFromTar`, except
that we can specify a destination root directory. Any hard links and
symlink targets under this destination root directory are valid.

Fixes sylabs#2607
dtrudg added a commit to dtrudg/singularity that referenced this issue May 15, 2024
In a build stage, a valid relative symlink can be created that points to a
location in the rootfs that is above the location of the symlink. E.g.:

  /usr/mydir/mysubdir/true -> ../../../bin/true

This symlink is valid in the rootfs. It resolves to `/bin/true`.

If we attempt to copy `/usr/mydir` into a new build stage, then prior to
this PR the symlink would cause the copy to fail.

We have been using `CopyFromTar` to copy from src `<stage1>/usr/mydir`,
to `<stage2>/usr/mydir`. The `CopyFromTar` routines enforce that the
target of a hard link or symlink must be under dst, or a fatal error is
raised to avoid a breakout attack.

When copying between stages our boundary is not dst, but the top level
of the destination stage's rootfs. We must allow links to be created
that are above dst, but withing the stage rootfs.

To resolve the issue, bring over enough code from
`docker/docker/pkg/archive` that we can implement a
`CopyFromTarWithRoot`, that performs the same as `CopyFromTar`, except
that we can specify a destination root directory. Any hard links and
symlink targets under this destination root directory are valid.

Fixes sylabs#2607
dtrudg added a commit to dtrudg/singularity that referenced this issue May 16, 2024
In a build stage, a valid relative symlink can be created that points to a
location in the rootfs that is above the location of the symlink. E.g.:

  /usr/mydir/mysubdir/true -> ../../../bin/true

This symlink is valid in the rootfs. It resolves to `/bin/true`.

If we attempt to copy `/usr/mydir` into a new build stage, then prior to
this PR the symlink would cause the copy to fail.

We have been using `CopyFromTar` to copy from src `<stage1>/usr/mydir`,
to `<stage2>/usr/mydir`. The `CopyFromTar` routines enforce that the
target of a hard link or symlink must be under dst, or a fatal error is
raised to avoid a breakout attack.

When copying between stages our boundary is not dst, but the top level
of the destination stage's rootfs. We must allow links to be created
that are above dst, but withing the stage rootfs.

To resolve the issue, bring over enough code from
`docker/docker/pkg/archive` that we can implement a
`CopyFromTarWithRoot`, that performs the same as `CopyFromTar`, except
that we can specify a destination root directory. Any hard links and
symlink targets under this destination root directory are valid.

Fixes sylabs#2607
dtrudg added a commit to dtrudg/singularity that referenced this issue May 16, 2024
In a build stage, a valid relative symlink can be created that points to a
location in the rootfs that is above the location of the symlink. E.g.:

  /usr/mydir/mysubdir/true -> ../../../bin/true

This symlink is valid in the rootfs. It resolves to `/bin/true`.

If we attempt to copy `/usr/mydir` into a new build stage, then prior to
this PR the symlink would cause the copy to fail.

We have been using `CopyFromTar` to copy from src `<stage1>/usr/mydir`,
to `<stage2>/usr/mydir`. The `CopyFromTar` routines enforce that the
target of a hard link or symlink must be under dst, or a fatal error is
raised to avoid a breakout attack.

When copying between stages our boundary is not dst, but the top level
of the destination stage's rootfs. We must allow links to be created
that are above dst, but within the stage rootfs.

To resolve the issue, bring over enough code from
`docker/docker/pkg/archive` that we can implement a
`CopyFromTarWithRoot`, that performs the same as `CopyFromTar`, except
that we can specify a destination root directory. Any hard links and
symlink targets under this destination root directory are valid.

Fixes sylabs#2607
dtrudg added a commit to dtrudg/singularity that referenced this issue May 16, 2024
In a build stage, a valid relative symlink can be created that points to a
location in the rootfs that is above the location of the symlink. E.g.:

  /usr/mydir/mysubdir/true -> ../../../bin/true

This symlink is valid in the rootfs. It resolves to `/bin/true`.

If we attempt to copy `/usr/mydir` into a new build stage, then prior to
this PR the symlink would cause the copy to fail.

We have been using `CopyFromTar` to copy from src `<stage1>/usr/mydir`,
to `<stage2>/usr/mydir`. The `CopyFromTar` routines enforce that the
target of a hard link or symlink must be under dst, or a fatal error is
raised to avoid a breakout attack.

When copying between stages our boundary is not dst, but the top level
of the destination stage's rootfs. We must allow links to be created
that are above dst, but within the stage rootfs.

To resolve the issue, bring over enough code from
`docker/docker/pkg/archive` that we can implement a
`CopyFromTarWithRoot`, that performs the same as `CopyFromTar`, except
that we can specify a destination root directory. Any hard links and
symlink targets under this destination root directory are valid.

Fixes sylabs#2607
dtrudg added a commit to dtrudg/singularity that referenced this issue May 16, 2024
In a build stage, a valid relative symlink can be created that points to a
location in the rootfs that is above the location of the symlink. E.g.:

  /usr/mydir/mysubdir/true -> ../../../bin/true

This symlink is valid in the rootfs. It resolves to `/bin/true`.

If we attempt to copy `/usr/mydir` into a new build stage, then prior to
this PR the symlink would cause the copy to fail.

We have been using `CopyFromTar` to copy from src `<stage1>/usr/mydir`,
to `<stage2>/usr/mydir`. The `CopyFromTar` routines enforce that the
target of a hard link or symlink must be under dst, or a fatal error is
raised to avoid a breakout attack.

When copying between stages our boundary is not dst, but the top level
of the destination stage's rootfs. We must allow links to be created
that are above dst, but within the stage rootfs.

To resolve the issue, bring over enough code from
`docker/docker/pkg/archive` that we can implement a
`CopyFromTarWithRoot`, that performs the same as `CopyFromTar`, except
that we can specify a destination root directory. Any hard links and
symlink targets under this destination root directory are valid.

Fixes sylabs#2607
dtrudg added a commit to dtrudg/singularity that referenced this issue May 16, 2024
In a build stage, a valid relative symlink can be created that points to a
location in the rootfs that is above the location of the symlink. E.g.:

  /usr/mydir/mysubdir/true -> ../../../bin/true

This symlink is valid in the rootfs. It resolves to `/bin/true`.

If we attempt to copy `/usr/mydir` into a new build stage, then prior to
this PR the symlink would cause the copy to fail.

We have been using `CopyFromTar` to copy from src `<stage1>/usr/mydir`,
to `<stage2>/usr/mydir`. The `CopyFromTar` routines enforce that the
target of a hard link or symlink must be under dst, or a fatal error is
raised to avoid a breakout attack.

When copying between stages our boundary is not dst, but the top level
of the destination stage's rootfs. We must allow links to be created
that are above dst, but within the stage rootfs.

To resolve the issue, bring over enough code from
`docker/docker/pkg/archive` that we can implement a
`CopyFromTarWithRoot`, that performs the same as `CopyFromTar`, except
that we can specify a destination root directory. Any hard links and
symlink targets under this destination root directory are valid.

Fixes sylabs#2607
dtrudg added a commit to dtrudg/singularity that referenced this issue May 16, 2024
In a build stage, a valid relative symlink can be created that points to a
location in the rootfs that is above the location of the symlink. E.g.:

  /usr/mydir/mysubdir/true -> ../../../bin/true

This symlink is valid in the rootfs. It resolves to `/bin/true`.

If we attempt to copy `/usr/mydir` into a new build stage, then prior to
this PR the symlink would cause the copy to fail.

We have been using `CopyFromTar` to copy from src `<stage1>/usr/mydir`,
to `<stage2>/usr/mydir`. The `CopyFromTar` routines enforce that the
target of a hard link or symlink must be under dst, or a fatal error is
raised to avoid a breakout attack.

When copying between stages our boundary is not dst, but the top level
of the destination stage's rootfs. We must allow links to be created
that are above dst, but within the stage rootfs.

To resolve the issue, bring over enough code from
`docker/docker/pkg/archive` that we can implement a
`CopyFromTarWithRoot`, that performs the same as `CopyFromTar`, except
that we can specify a destination root directory. Any hard links and
symlink targets under this destination root directory are valid.

Fixes sylabs#2607
dtrudg added a commit to dtrudg/singularity that referenced this issue May 16, 2024
In a build stage, a valid relative symlink can be created that points to a
location in the rootfs that is above the location of the symlink. E.g.:

  /usr/mydir/mysubdir/true -> ../../../bin/true

This symlink is valid in the rootfs. It resolves to `/bin/true`.

If we attempt to copy `/usr/mydir` into a new build stage, then prior to
this PR the symlink would cause the copy to fail.

We have been using `CopyFromTar` to copy from src `<stage1>/usr/mydir`,
to `<stage2>/usr/mydir`. The `CopyFromTar` routines enforce that the
target of a hard link or symlink must be under dst, or a fatal error is
raised to avoid a breakout attack.

When copying between stages our boundary is not dst, but the top level
of the destination stage's rootfs. We must allow links to be created
that are above dst, but within the stage rootfs.

To resolve the issue, bring over enough code from
`docker/docker/pkg/archive` that we can implement a
`CopyFromTarWithRoot`, that performs the same as `CopyFromTar`, except
that we can specify a destination root directory. Any hard links and
symlink targets under this destination root directory are valid.

Fixes sylabs#2607
cyanezstange pushed a commit to cyanezstange/singularity that referenced this issue Jun 4, 2024
In a build stage, a valid relative symlink can be created that points to a
location in the rootfs that is above the location of the symlink. E.g.:

  /usr/mydir/mysubdir/true -> ../../../bin/true

This symlink is valid in the rootfs. It resolves to `/bin/true`.

If we attempt to copy `/usr/mydir` into a new build stage, then prior to
this PR the symlink would cause the copy to fail.

We have been using `CopyFromTar` to copy from src `<stage1>/usr/mydir`,
to `<stage2>/usr/mydir`. The `CopyFromTar` routines enforce that the
target of a hard link or symlink must be under dst, or a fatal error is
raised to avoid a breakout attack.

When copying between stages our boundary is not dst, but the top level
of the destination stage's rootfs. We must allow links to be created
that are above dst, but within the stage rootfs.

To resolve the issue, bring over enough code from
`docker/docker/pkg/archive` that we can implement a
`CopyFromTarWithRoot`, that performs the same as `CopyFromTar`, except
that we can specify a destination root directory. Any hard links and
symlink targets under this destination root directory are valid.

Fixes sylabs#2607
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant