VYPR
Moderate severityNVD Advisory· Published Mar 26, 2026· Updated Mar 27, 2026

Incus vulnerable to local privilege escalation through VM screenshot path

CVE-2026-33711

Description

Incus is a system container and virtual machine manager. Incus provides an API to retrieve VM screenshots. That API relies on the use of a temporary file for QEMU to write the screenshot to which is then picked up and sent to the user prior to deletion. As versions prior to 6.23.0 use predictable paths under /tmp for this, an attacker with local access to the system can abuse this mechanism by creating their own symlinks ahead of time. On the vast majority of Linux systems, this will result in a "Permission denied" error when requesting a screenshot. That's because the Linux kernel has a security feature designed to block such attacks, protected_symlinks. On the rare systems with this purposefully disabled, it's then possible to trick Incus intro truncating and altering the mode and permissions of arbitrary files on the filesystem, leading to a potential denial of service or possible local privilege escalation. Version 6.23.0 fixes the issue.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
github.com/lxc/incus/v6Go
< 6.23.06.23.0

Affected products

1

Patches

1
ef006240ac24

incusd/instance_console: Prevent symlink attacks

https://github.com/lxc/incusStéphane GraberMar 23, 2026via ghsa
1 file changed · +6 6
  • cmd/incusd/instance_console.go+6 6 modified
    @@ -726,14 +726,14 @@ func instanceConsoleLogGet(d *Daemon, r *http.Request) response.Response {
     
     		var headers map[string]string
     		if consoleLogType == "vga" {
    -			screenshotFile, err := os.Create(fmt.Sprintf("/tmp/incus_screenshot_%d", inst.ID()))
    -			if err != nil {
    -				return response.SmartError(fmt.Errorf("Couldn't create screenshot file: %w", err))
    -			}
    +			screenShotPath := fmt.Sprintf("/tmp/incus_screenshot_%d", inst.ID())
     
    -			err = screenshotFile.Chmod(0o600)
    +			// Delete then create the path with O_EXCL to ensure that we are the creator of the path.
    +			// Any attempt at racing with us will cause in a (already exists) failure.
    +			_ = os.Remove(screenShotPath)
    +			screenshotFile, err := os.OpenFile(screenShotPath, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0o600)
     			if err != nil {
    -				return response.SmartError(err)
    +				return response.SmartError(fmt.Errorf("Couldn't create screenshot file: %w", err))
     			}
     
     			ent.Cleanup = func() {
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.