Skip to content

Commit

Permalink
Fix underlay bind issue when the destination is a symlink
Browse files Browse the repository at this point in the history
pointing to a relative/absolute path.
  • Loading branch information
cclerget committed Nov 27, 2019
1 parent 92118c8 commit e619d05
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 9 deletions.
1 change: 1 addition & 0 deletions e2e/actions/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -1518,6 +1518,7 @@ func E2ETests(env e2e.TestEnv) func(*testing.T) {
"issue 4587": c.issue4587, // https://github.com/sylabs/singularity/issues/4587
"issue 4755": c.issue4755, // https://github.com/sylabs/singularity/issues/4755
"issue 4768": c.issue4768, // https://github.com/sylabs/singularity/issues/4768
"issue 4797": c.issue4797, // https://github.com/sylabs/singularity/issues/4797
"network": c.actionNetwork, // test basic networking
"binds": c.actionBinds, // test various binds
"exit and signals": c.exitSignals, // test exit and signals propagation
Expand Down
48 changes: 48 additions & 0 deletions e2e/actions/regressions.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,51 @@ func (c actionTests) issue4768(t *testing.T) {
),
)
}

// Check that underlay layer handle relative/absolute symlinks
// when those are bind mount points.
func (c actionTests) issue4797(t *testing.T) {
e2e.EnsureImage(t, c.env)

// /etc/relative-slink in the image point to ../usr/share/zoneinfo/Etc/UTC
// /etc/absolute-slink in the image point to /usr/share/zoneinfo/Etc/UTC
tests := []struct {
name string
args []string
exit int
}{
{
// check /usr/bin presence in the container
name: "RelativeUsrBin",
args: []string{"--bind", "/etc/passwd:/etc/relative-slink", c.env.ImagePath, "test", "-d", "/usr/bin"},
exit: 0,
},
{
// check /usr/share/zoneinfo/Etc/UTC presence in the container
name: "RelativeUTC",
args: []string{"--bind", "/etc/passwd:/etc/relative-slink", c.env.ImagePath, "test", "-f", "/usr/share/zoneinfo/Etc/UTC"},
exit: 0,
},
{
name: "AbsoluteUsrBin",
args: []string{"--bind", "/etc/passwd:/etc/absolute-slink", c.env.ImagePath, "test", "-d", "/usr/bin"},
exit: 0,
},
{
name: "AbsoluteUTC",
args: []string{"--bind", "/etc/passwd:/etc/absolute-slink", c.env.ImagePath, "test", "-f", "/usr/share/zoneinfo/Etc/UTC"},
exit: 0,
},
}

for _, tt := range tests {
c.env.RunSingularity(
t,
e2e.AsSubtest(tt.name),
e2e.WithProfile(e2e.UserNamespaceProfile),
e2e.WithCommand("exec"),
e2e.WithArgs(tt.args...),
e2e.ExpectExit(tt.exit),
)
}
}
4 changes: 4 additions & 0 deletions e2e/testdata/Singularity
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,9 @@ export HELLOTHISIS
mkdir /madness
ln -s /madness /var/etc/madness

# for underlay regression tests
ln -s ../usr/share/zoneinfo/Etc/UTC /etc/relative-slink
ln -s /usr/share/zoneinfo/Etc/UTC /etc/absolute-slink

%test
exec "$@"
17 changes: 8 additions & 9 deletions internal/pkg/util/fs/layout/layer/underlay/underlay_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,25 +96,25 @@ func (u *Underlay) createLayer(rootFsPath string, system *mount.System) error {
sylog.Warningf("skipping mount of %s: %s", point.Source, err)
continue
}
dst = filepath.Join(underlayDir, dst)
if _, err := u.session.GetPath(dst); err == nil {
underlayDst := filepath.Join(underlayDir, dst)
if _, err := u.session.GetPath(underlayDst); err == nil {
continue
}
switch st.Mode & syscall.S_IFMT {
case syscall.S_IFDIR:
if err := u.session.AddDir(dst); err != nil {
if err := u.session.AddDir(underlayDst); err != nil {
return err
}
default:
if err := u.session.AddFile(dst, nil); err != nil {
if err := u.session.AddFile(underlayDst, nil); err != nil {
return err
}
}
createdPath = append(
createdPath,
pathLen{
path: point.Destination,
len: uint16(strings.Count(point.Destination, "/")),
path: dst,
len: uint16(strings.Count(dst, "/")),
},
)
}
Expand All @@ -137,14 +137,13 @@ func (u *Underlay) createLayer(rootFsPath string, system *mount.System) error {
return err
}
}
dir := fs.EvalRelative(p, rootFsPath)
// if the directory is overrided by a bind mount we won't
// need to duplicate the container image directory
if _, ok := destinations[dir]; ok {
if _, ok := destinations[p]; ok {
continue
}
// directory not overrided, duplicate it
if err := u.duplicateDir(dir, system, pl.path); err != nil {
if err := u.duplicateDir(p, system, pl.path); err != nil {
return err
}
}
Expand Down

0 comments on commit e619d05

Please sign in to comment.