mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-09-13 04:49:36 +00:00
Merge pull request #2475 from bergwolf/umount
vc: do not follow symlink when umounting contanier host path
This commit is contained in:
@@ -590,7 +590,7 @@ func (c *Container) unmountHostMounts() error {
|
|||||||
span, _ := c.trace("unmount")
|
span, _ := c.trace("unmount")
|
||||||
span.SetTag("host-path", m.HostPath)
|
span.SetTag("host-path", m.HostPath)
|
||||||
|
|
||||||
if err := syscall.Unmount(m.HostPath, syscall.MNT_DETACH); err != nil {
|
if err := syscall.Unmount(m.HostPath, syscall.MNT_DETACH|UmountNoFollow); err != nil {
|
||||||
c.Logger().WithFields(logrus.Fields{
|
c.Logger().WithFields(logrus.Fields{
|
||||||
"host-path": m.HostPath,
|
"host-path": m.HostPath,
|
||||||
"error": err,
|
"error": err,
|
||||||
|
@@ -24,6 +24,9 @@ import (
|
|||||||
// IPC is used.
|
// IPC is used.
|
||||||
const DefaultShmSize = 65536 * 1024
|
const DefaultShmSize = 65536 * 1024
|
||||||
|
|
||||||
|
// Sadly golang/sys doesn't have UmountNoFollow although it's there since Linux 2.6.34
|
||||||
|
const UmountNoFollow = 0x8
|
||||||
|
|
||||||
var rootfsDir = "rootfs"
|
var rootfsDir = "rootfs"
|
||||||
|
|
||||||
var systemMountPrefixes = []string{"/proc", "/sys"}
|
var systemMountPrefixes = []string{"/proc", "/sys"}
|
||||||
@@ -328,12 +331,25 @@ type Mount struct {
|
|||||||
BlockDeviceID string
|
BlockDeviceID string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isSymlink(path string) bool {
|
||||||
|
stat, err := os.Stat(path)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return stat.Mode()&os.ModeSymlink != 0
|
||||||
|
}
|
||||||
|
|
||||||
func bindUnmountContainerRootfs(ctx context.Context, sharedDir, sandboxID, cID string) error {
|
func bindUnmountContainerRootfs(ctx context.Context, sharedDir, sandboxID, cID string) error {
|
||||||
span, _ := trace(ctx, "bindUnmountContainerRootfs")
|
span, _ := trace(ctx, "bindUnmountContainerRootfs")
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
|
|
||||||
rootfsDest := filepath.Join(sharedDir, sandboxID, cID, rootfsDir)
|
rootfsDest := filepath.Join(sharedDir, sandboxID, cID, rootfsDir)
|
||||||
err := syscall.Unmount(rootfsDest, syscall.MNT_DETACH)
|
if isSymlink(filepath.Join(sharedDir, sandboxID, cID)) || isSymlink(rootfsDest) {
|
||||||
|
logrus.Warnf("container dir %s is a symlink, malicious guest?", cID)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
err := syscall.Unmount(rootfsDest, syscall.MNT_DETACH|UmountNoFollow)
|
||||||
if err == syscall.ENOENT {
|
if err == syscall.ENOENT {
|
||||||
logrus.Warnf("%s: %s", err, rootfsDest)
|
logrus.Warnf("%s: %s", err, rootfsDest)
|
||||||
return nil
|
return nil
|
||||||
@@ -347,6 +363,10 @@ func bindUnmountAllRootfs(ctx context.Context, sharedDir string, sandbox *Sandbo
|
|||||||
|
|
||||||
var errors *merr.Error
|
var errors *merr.Error
|
||||||
for _, c := range sandbox.containers {
|
for _, c := range sandbox.containers {
|
||||||
|
if isSymlink(filepath.Join(sharedDir, sandbox.id, c.id)) {
|
||||||
|
logrus.Warnf("container dir %s is a symlink, malicious guest?", c.id)
|
||||||
|
continue
|
||||||
|
}
|
||||||
c.unmountHostMounts()
|
c.unmountHostMounts()
|
||||||
if c.state.Fstype == "" {
|
if c.state.Fstype == "" {
|
||||||
// even if error found, don't break out of loop until all mounts attempted
|
// even if error found, don't break out of loop until all mounts attempted
|
||||||
|
Reference in New Issue
Block a user