Skip to content
This repository was archived by the owner on May 12, 2021. It is now read-only.

Commit 15305b8

Browse files
authored
Merge pull request #3011 from keloyang/bindmount-stable-1.11
runtime: Don' call bindUnmountContainerRootfs for devicemapper device
2 parents ddfeabe + 054c4fb commit 15305b8

4 files changed

Lines changed: 66 additions & 10 deletions

File tree

virtcontainers/container.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -850,7 +850,7 @@ func (c *Container) rollbackFailingContainerCreation() {
850850
if err := c.unmountHostMounts(); err != nil {
851851
c.Logger().WithError(err).Error("rollback failed unmountHostMounts()")
852852
}
853-
if err := bindUnmountContainerRootfs(c.ctx, getMountPath(c.sandbox.id), c.id); err != nil {
853+
if err := bindUnmountContainerRootfs(c.ctx, getMountPath(c.sandbox.id), c); err != nil {
854854
c.Logger().WithError(err).Error("rollback failed bindUnmountContainerRootfs()")
855855
}
856856
}
@@ -1120,7 +1120,7 @@ func (c *Container) stop(force bool) error {
11201120
return err
11211121
}
11221122

1123-
if err := bindUnmountContainerRootfs(c.ctx, getMountPath(c.sandbox.id), c.id); err != nil && !force {
1123+
if err := bindUnmountContainerRootfs(c.ctx, getMountPath(c.sandbox.id), c); err != nil && !force {
11241124
return err
11251125
}
11261126

virtcontainers/kata_agent.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1258,7 +1258,7 @@ func (k *kataAgent) rollbackFailingContainerCreation(c *Container) {
12581258
k.Logger().WithError(err2).Error("rollback failed unmountHostMounts()")
12591259
}
12601260

1261-
if err2 := bindUnmountContainerRootfs(k.ctx, getMountPath(c.sandbox.id), c.id); err2 != nil {
1261+
if err2 := bindUnmountContainerRootfs(k.ctx, getMountPath(c.sandbox.id), c); err2 != nil {
12621262
k.Logger().WithError(err2).Error("rollback failed bindUnmountContainerRootfs()")
12631263
}
12641264
}

virtcontainers/mount.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -315,13 +315,17 @@ func isSymlink(path string) bool {
315315
return stat.Mode()&os.ModeSymlink != 0
316316
}
317317

318-
func bindUnmountContainerRootfs(ctx context.Context, sharedDir, cID string) error {
318+
func bindUnmountContainerRootfs(ctx context.Context, sharedDir string, con *Container) error {
319319
span, _ := trace(ctx, "bindUnmountContainerRootfs")
320320
defer span.Finish()
321321

322-
rootfsDest := filepath.Join(sharedDir, cID, rootfsDir)
323-
if isSymlink(filepath.Join(sharedDir, cID)) || isSymlink(rootfsDest) {
324-
logrus.Warnf("container dir %s is a symlink, malicious guest?", cID)
322+
if con.state.Fstype != "" && con.state.BlockDeviceID != "" {
323+
return nil
324+
}
325+
326+
rootfsDest := filepath.Join(sharedDir, con.id, rootfsDir)
327+
if isSymlink(filepath.Join(sharedDir, con.id)) || isSymlink(rootfsDest) {
328+
logrus.Warnf("container dir %s is a symlink, malicious guest?", con.id)
325329
return nil
326330
}
327331

@@ -351,7 +355,7 @@ func bindUnmountAllRootfs(ctx context.Context, sharedDir string, sandbox *Sandbo
351355
if c.state.Fstype == "" {
352356
// even if error found, don't break out of loop until all mounts attempted
353357
// to be unmounted, and collect all errors
354-
errors = merr.Append(errors, bindUnmountContainerRootfs(c.ctx, sharedDir, c.id))
358+
errors = merr.Append(errors, bindUnmountContainerRootfs(c.ctx, sharedDir, c))
355359
}
356360
}
357361
return errors.ErrorOrNil()

virtcontainers/mount_test.go

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"testing"
2020

2121
ktu "github.com/kata-containers/runtime/pkg/katatestutils"
22+
"github.com/kata-containers/runtime/virtcontainers/types"
2223
"github.com/stretchr/testify/assert"
2324
)
2425

@@ -378,6 +379,10 @@ func TestBindUnmountContainerRootfsENOENTNotError(t *testing.T) {
378379
testMnt := "/tmp/test_mount"
379380
sID := "sandIDTest"
380381
cID := "contIDTest"
382+
container := &Container{
383+
id: cID,
384+
}
385+
381386
assert := assert.New(t)
382387

383388
// check to make sure the file doesn't exist
@@ -386,7 +391,7 @@ func TestBindUnmountContainerRootfsENOENTNotError(t *testing.T) {
386391
assert.NoError(os.Remove(testPath))
387392
}
388393

389-
err := bindUnmountContainerRootfs(context.Background(), filepath.Join(testMnt, sID), cID)
394+
err := bindUnmountContainerRootfs(context.Background(), filepath.Join(testMnt, sID), container)
390395
assert.NoError(err)
391396
}
392397

@@ -398,6 +403,9 @@ func TestBindUnmountContainerRootfsRemoveRootfsDest(t *testing.T) {
398403

399404
sID := "sandIDTestRemoveRootfsDest"
400405
cID := "contIDTestRemoveRootfsDest"
406+
container := &Container{
407+
id: cID,
408+
}
401409

402410
testPath := filepath.Join(testDir, sID, cID, rootfsDir)
403411
syscall.Unmount(testPath, 0)
@@ -407,11 +415,55 @@ func TestBindUnmountContainerRootfsRemoveRootfsDest(t *testing.T) {
407415
assert.NoError(err)
408416
defer os.RemoveAll(filepath.Join(testDir, sID))
409417

410-
bindUnmountContainerRootfs(context.Background(), filepath.Join(testDir, sID), cID)
418+
bindUnmountContainerRootfs(context.Background(), filepath.Join(testDir, sID), container)
411419

412420
if _, err := os.Stat(testPath); err == nil {
413421
t.Fatal("empty rootfs dest should be removed")
414422
} else if !os.IsNotExist(err) {
415423
t.Fatal(err)
416424
}
417425
}
426+
427+
func TestBindUnmountContainerRootfsDevicemapper(t *testing.T) {
428+
assert := assert.New(t)
429+
if tc.NotValid(ktu.NeedRoot()) {
430+
t.Skip(ktu.TestDisabledNeedRoot)
431+
}
432+
433+
sID := "sandIDDevicemapper"
434+
435+
cID1 := "contIDDevicemapper1"
436+
container := &Container{
437+
id: cID1,
438+
state: types.ContainerState{
439+
Fstype: "xfs",
440+
BlockDeviceID: "4b073a87f3c9242a",
441+
},
442+
}
443+
444+
testPath1 := filepath.Join(testDir, sID, cID1, rootfsDir)
445+
err := os.MkdirAll(testPath1, mountPerm)
446+
assert.NoError(err)
447+
448+
bindUnmountContainerRootfs(context.Background(), filepath.Join(testDir, sID), container)
449+
450+
// expect testPath1 exist, if not exist, it means this case failed.
451+
if _, err := os.Stat(testPath1); err != nil && !os.IsExist(err) {
452+
t.Fatal("testPath should not be removed")
453+
}
454+
455+
cID2 := "contIDDevicemapper2"
456+
container.state.Fstype = ""
457+
container.id = cID2
458+
testPath2 := filepath.Join(testDir, sID, cID2, rootfsDir)
459+
err = os.MkdirAll(testPath2, mountPerm)
460+
assert.NoError(err)
461+
462+
defer os.RemoveAll(filepath.Join(testDir, sID))
463+
464+
// expect testPath2 not exist, if exist, it means this case failed.
465+
bindUnmountContainerRootfs(context.Background(), filepath.Join(testDir, sID), container)
466+
if _, err := os.Stat(testPath2); err == nil || os.IsExist(err) {
467+
t.Fatal("testPath should be removed")
468+
}
469+
}

0 commit comments

Comments
 (0)