Skip to content

[Low] guestVolumeSource can map host paths containing ".." outside the microVM guest share #2920

Open

Description

@destijl

Summary

In internal/ocispec/microvm.go, guestVolumeSource translates host volume bind mount sources into in-guest paths under GuestSharedDir using strings.CutPrefix followed by path.Join. It does not validate that the prefix is non-empty or check whether the trimmed relative path contains .. traversal segments, allowing paths to escape GuestSharedDir.

Details

In internal/ocispec/microvm.go#L124-L136:

func guestVolumeSource(hostPath string, actorDirs *ateworkerpb.ActorDirs, containerName string) (string, error) {
	for _, staged := range []struct{ host, guest string }{
		{actorDirs.GetDurableDirVolumeMountsDir(), path.Join(GuestSharedDir, ShareDurable)},
		{actorDirs.GetExternalVolumeMountsDir(), path.Join(GuestSharedDir, ShareCSI)},
		{actorDirs.GetSystemInfoVolumeRootsDir(), path.Join(GuestSharedDir, ShareSystemInfo)},
		{imagecache.ImageVolumeMountPath(filepath.Join(actorDirs.GetOciBundleDir(), containerName), ""), path.Join(GuestSharedDir, GuestContainerID(containerName), ShareVolumes)},
	} {
		if rel, ok := strings.CutPrefix(hostPath, staged.host+"/"); ok {
			return path.Join(staged.guest, rel), nil
		}
	}
	return "", fmt.Errorf("host path %q is not staged into the guest share", hostPath)
}

Because path.Join performs lexical path resolution via path.Clean, passing a hostPath such as staged.host + "/../../../../../dev/vda" succeeds in strings.CutPrefix and cleans the joined path to /dev/vda, escaping GuestSharedDir (/run/kata-containers/shared/containers).

Impact

At the unit level, an unvalidated OCI spec passed to ShapeMicroVM can map host bind mounts to arbitrary guest device or filesystem nodes outside the virtio-fs shared directory. However, in production, ShapeMicroVM is only called by cmd/ateworker-microvm/run.go on specs generated by ocispec.Build. Volume and container names are validated as DNS-1123 labels (validate.ShortName), and host directory paths are validated as clean absolute paths (resources.ValidateActorDirs), preventing traversal sequences from reaching guestVolumeSource. The issue is therefore a defense-in-depth and hardening defect rather than an exploitable vulnerability.

Suggested fix

Validate that the relative path does not escape the target directory using filepath.Rel and filepath.IsLocal (or path.IsLocal), and verify that staged.host is non-empty before prefix matching.

Related

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area/securitySecurity related issue/prkind/bugSomething isn't working / bugfixes

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions