Every CVE Search/ Get API key

CVE-2026-12411

Broken Access Control in Canonical LXD DevLXD API

8.4 HighFix available

Broken Access Control in the devLXDInstancePatchHandler component of Canonical LXD allows an untrusted guest to mount, read, and overwrite another guest's custom storage volume via a crafted device PATCH request over /dev/lxd when security.devlxd.management.volumes is enabled.

Attack profile

How easy it is to exploit

Attack vector
Local
Complexity
Low
Privileges needed
Low
User interaction
None

What an attacker can affect

Confidentiality
High
Integrity
High
Availability
None

Exploit likelihood

0.24%Up 0.1 points since Jun 27, 2026
90%50%10%1%

What each source reports

CVE List Score used 8.4

Broken Access Control in Canonical LXD DevLXD API

Broken Access Control in the devLXDInstancePatchHandler component of Canonical LXD allows an untrusted guest to mount, read, and overwrite another guest's custom storage volume via a crafted device PATCH request over /dev/lxd when security.devlxd.management.volumes is enabled.

Record
CVE-2026-12411
CVSS 3.1
8.4 HighCVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N
Weakness
CWE-639, CWE-862
Updated
2026-11-02
EUVDEUVD-2026-39788 8.4

lxd allows Cross-guest volume hijack via DevLXD device patch

Record
EUVD-2026-39788
CVSS 3.1
8.4 HighCVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N
Updated
2026-11-05
GitHub AdvisoriesGHSA-hhf9-qw4v-72xp 8.4

lxd allows Cross-guest volume hijack via DevLXD device patch

Summary

A guest can mount another guest's custom storage volume over /dev/lxd and read or write its contents without owning it. The DevLXD storage API blocks access to volumes you don't own, but the instance device-update path that attaches a volume to a container without checks ownership. Any guest in a project with security.devlxd.management.volumes enabled can attach a volume belonging to a different guest by naming it in a device PATCH, giving one tenant full read and write access to another tenant's volume data.

Details

Volumes created over DevLXD get volatile.devlxd.owner set to the calling identity. The storage handlers enforce it on GET/PUT/DELETE (isDevLXDVolumeOwner, lxd/devlxd_storage.go:359) and on volume-copy sources (devlxd_storage.go:286). The device-attach path does not.

devLXDInstancePatchHandler (lxd/devlxd_instances.go:88) passes the guest's device map to generateDevLXDInstanceDevices (devlxd_instances.go:178). For a device that isn't already on the instance, the only check is isDeviceAccessible(device):

if (exists && !isOwned) || (!isDeviceAccessible(device)) 

exists is false for a newly added device, so isDeviceAccessible is the whole gate. It resolves to newDevLXDDeviceAccessValidator (devlxd_instances.go:250), which is diskDeviceAllowed && filters.IsCustomVolumeDisk(device). IsCustomVolumeDisk (lxd/device/filters/disk.go:28) checks the device shape only: type=disk, non-empty source, non-empty pool. It never loads the (pool, source) volume or compares its owner to the caller.

The handler then sets volatile.<dev>.devlxd.owner to the caller and issues an in-process PATCH to instancePatch (lxd/instance_patch.go:55). That call skips the HTTP access handler and runs only project quota checks (limits.AllowInstanceUpdate, instance_patch.go:215) before c.Update. The disk device's validateConfig confirms the volume exists but does no ownership or RBAC check. A guest can therefore point a new disk device at any custom volume in its project and LXD mounts it. The recorded device owner becomes the attacker while the volume's volatile.devlxd.owner still names the victim.

PoC

Built from source at HEAD d29ece6284 (reports as 6.8, API extension devlxd_volume_management); single host, dir pool, default project.

Host setup, two guests with separate DevLXD identities, each scoped to edit only its own instance:

lxc launch images:alpine/edge guesta -c security.devlxd=true -c security.devlxd.management.volumes=true
lxc launch images:alpine/edge guestb -c security.devlxd=true -c security.devlxd.management.volumes=true
lxc exec guesta -- apk add --no-cache curl ; lxc exec guestb -- apk add --no-cache curl

for g in a b; do
  lxc auth identity create devlxd/id$g
  lxc auth group create g$g
  lxc auth group permission add g$g project default can_view
  lxc auth group permission add g$g project default can_view_storage_volumes
  lxc auth group permission add g$g project default can_create_storage_volumes
  lxc auth group permission add g$g instance guest$g can_view…
Record
GHSA-hhf9-qw4v-72xp
CVSS 3.1
8.4 HighCVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N
Weakness
CWE-639, CWE-862
Updated
2026-11-05
NVD 8.4

Broken Access Control in the devLXDInstancePatchHandler component of Canonical LXD allows an untrusted guest to mount, read, and overwrite another guest's custom storage volume via a crafted device PATCH request over /dev/lxd when security.devlxd.management.volumes is enabled.

Record
CVE-2026-12411
CVSS 3.1
8.4 HighCVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N
CVSS 3.1
9.6 CriticalCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N
Weakness
CWE-639, CWE-862
Updated
2026-11-02
OSV 8.4

Broken Access Control in Canonical LXD DevLXD API

Broken Access Control in the devLXDInstancePatchHandler component of Canonical LXD allows an untrusted guest to mount, read, and overwrite another guest's custom storage volume via a crafted device PATCH request over /dev/lxd when security.devlxd.management.volumes is enabled.

Record
CVE-2026-12411
CVSS 3.1
8.4 HighCVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N
Weakness
CWE-639, CWE-862
Updated
2026-11-06
OSVGHSA-hhf9-qw4v-72xp 8.4

lxd allows Cross-guest volume hijack via DevLXD device patch

Summary

A guest can mount another guest's custom storage volume over /dev/lxd and read or write its contents without owning it. The DevLXD storage API blocks access to volumes you don't own, but the instance device-update path that attaches a volume to a container without checks ownership. Any guest in a project with security.devlxd.management.volumes enabled can attach a volume belonging to a different guest by naming it in a device PATCH, giving one tenant full read and write access to another tenant's volume data.

Details

Volumes created over DevLXD get volatile.devlxd.owner set to the calling identity. The storage handlers enforce it on GET/PUT/DELETE (isDevLXDVolumeOwner, lxd/devlxd_storage.go:359) and on volume-copy sources (devlxd_storage.go:286). The device-attach path does not.

devLXDInstancePatchHandler (lxd/devlxd_instances.go:88) passes the guest's device map to generateDevLXDInstanceDevices (devlxd_instances.go:178). For a device that isn't already on the instance, the only check is isDeviceAccessible(device):

if (exists && !isOwned) || (!isDeviceAccessible(device)) 

exists is false for a newly added device, so isDeviceAccessible is the whole gate. It resolves to newDevLXDDeviceAccessValidator (devlxd_instances.go:250), which is diskDeviceAllowed && filters.IsCustomVolumeDisk(device). IsCustomVolumeDisk (lxd/device/filters/disk.go:28) checks the device shape only: type=disk, non-empty source, non-empty pool. It never loads the (pool, source) volume or compares its owner to the caller.

The handler then sets volatile.<dev>.devlxd.owner to the caller and issues an in-process PATCH to instancePatch (lxd/instance_patch.go:55). That call skips the HTTP access handler and runs only project quota checks (limits.AllowInstanceUpdate, instance_patch.go:215) before c.Update. The disk device's validateConfig confirms the volume exists but does no ownership or RBAC check. A guest can therefore point a new disk device at any custom volume in its project and LXD mounts it. The recorded device owner becomes the attacker while the volume's volatile.devlxd.owner still names the victim.

PoC

Built from source at HEAD d29ece6284 (reports as 6.8, API extension devlxd_volume_management); single host, dir pool, default project.

Host setup, two guests with separate DevLXD identities, each scoped to edit only its own instance:

lxc launch images:alpine/edge guesta -c security.devlxd=true -c security.devlxd.management.volumes=true
lxc launch images:alpine/edge guestb -c security.devlxd=true -c security.devlxd.management.volumes=true
lxc exec guesta -- apk add --no-cache curl ; lxc exec guestb -- apk add --no-cache curl

for g in a b; do
  lxc auth identity create devlxd/id$g
  lxc auth group create g$g
  lxc auth group permission add g$g project default can_view
  lxc auth group permission add g$g project default can_view_storage_volumes
  lxc auth group permission add g$g project default can_create_storage_volumes
  lxc auth group permission add g$g instance guest$g can_view…
Record
GHSA-hhf9-qw4v-72xp
CVSS 3.1
8.4 HighCVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N
Weakness
CWE-639, CWE-862
Updated
2026-11-06
OSVGO-2026-6917 No score

LXD allows cross-guest volume hijack via DevLXD device patch in github.com/canonical/lxd

LXD allows cross-guest volume hijack via DevLXD device patch in github.com/canonical/lxd

Record
GO-2026-6917
Updated
2026-11-06

Affected products

Affected packages

Affected packages
PackageAffectedFixed
github.com/canonical/lxd
Go
0.0.0-20250721152936-fe86ceb2c3fa up to 0.0.0-20260626085133-7cb96ac80a6d
0.0.0-20260626085133-7cb96ac80a6d

History

History
RecordedChangedSources
affected, aliases, referencesOSV
publishedEUVD
affected, facts, referencesGitHub Advisories, OSV
first indexedCVE List, EUVD, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-12411 is a high vulnerability (CVSS 8.4) in Canonical Lxd, published June 26, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.24%, the 14th percentile. Fixed in github.com/canonical/lxd 0.0.0-20260626085133-7cb96ac80a6d.

References

This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open