Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

[Low] setupImageVolumes builds host mount paths from vol.Name without a containment check

Open Beginner friendly
#2,919 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

@abhisheksharma2411 is already working on this.

Since Oct 20, 2026.

  • #3024 by @abhisheksharma2411 — open

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
73/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
go
Domain
security

Research direction

Read internal/imagecache/bundle_linux.go at setupImageVolumes and internal/imagecache/spec.go for ImageVolumeMountPath and the createExtraDirs validation pattern. Check how volume names reach this function, then add a containment check before building mount paths. Done when non-local names are rejected and valid volume names still work; the payload names no test file.

Written by the indexing model from the issue text.

Description

area/security kind/bug

Summary

In internal/imagecache/bundle_linux.go, setupImageVolumes constructs mount points using ImageVolumeMountPath(bundlePath, vol.Name) without verifying that vol.Name is a clean, local relative path. If a crafted rootfs-overlay.json containing path traversal sequences (such as ../) is processed, setupImageVolumes can create directories, unmount existing mounts, and mount image layers at arbitrary locations on the host within the privileged ateworker context.

Details

In internal/imagecache/bundle_linux.go#L114-L122:

		mountpoint := ImageVolumeMountPath(bundlePath, vol.Name)
		if err := os.MkdirAll(mountpoint, 0o700); err != nil {
			return fmt.Errorf("while creating image volume mount point %q: %w", mountpoint, err)
		}
		_ = unix.Unmount(mountpoint, unix.MNT_DETACH)

		if err := mountImageVolume(mountpoint, vol.Layers); err != nil {
			return fmt.Errorf("while mounting image volume %q: %w", vol.Name, err)
		}

And internal/imagecache/spec.go#L30-L32:

func ImageVolumeMountPath(bundlePath, volumeName string) string {
	return filepath.Join(bundlePath, "volumes", volumeName)
}

In contrast to createExtraDirs (internal/imagecache/spec.go#L182-L184), which uses os.OpenRoot and enforces filepath.IsLocal, setupImageVolumes performs no checks on vol.Name.

Impact

Exploitability is constrained by upstream controls:

  1. Both ateapi (cmd/ateapi/internal/apivalidation/zz_generated.validation.go#L9511) and atelet (cmd/atelet/internal/apivalidation/zz_generated.validation.go#L4448) enforce validate.ShortName (content.IsDNS1123Label), rejecting slashes and .. traversal sequences in volume names at API ingress.
  2. rootfs-overlay.json is generated by atelet on the host; untrusted sandboxed containers cannot modify it directly.
    An attacker would require a pre-existing host-level compromise or a bypass of the API server validation to write a malicious rootfs-overlay.json.

Suggested fix

Validate vol.Name in setupImageVolumes before joining paths, rejecting non-local paths or path separators:

if !filepath.IsLocal(vol.Name) || filepath.Base(vol.Name) != vol.Name {
    return fmt.Errorf("invalid volume name %q: must be a local filename", vol.Name)
}

Related

  • Related: #1436 (SystemInfoVolumeSource path traversal validation)
  • Related: PR #923 (Added image volumes to ActorTemplate)
  • Related: PR #2826 (Micro-VM image volumes refactor)
Dominant language
Go
Stars
5.7k
Forks
612
Avg merge
2d 14h
Merged PRs (30d)
533

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from agent-substrate/substrate

All issues in agent-substrate/substrate

Similar issues

More Go issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.