Summary
If a user has restricted access to a project that is configured with restricted=true, they can gain root access on the system by creating a disk device with shift=true and creating a setuid root executable. This is possible because the shift property is not restricted unless restricted.devices.disk.paths is set.
Details
The following patch shows the offending code with a possible fix:
--- a/lxd/device/disk.go
+++ b/lxd/device/disk.go
@@ -429,17 +429,19 @@ func (d *disk) validateEnvironmentSourcePath() error {
if instProject.Name != api.ProjectDefaultName {
// If restricted disk paths are in force, then check the disk's source is allowed, and record the
// allowed parent path for later user during device start up sequence.
- if shared.IsTrue(instProject.Config["restricted"]) && instProject.Config["restricted.devices.disk.paths"] != "" {
- allowed, restrictedParentSourcePath := project.CheckRestrictedDevicesDiskPaths(instProject.Config, d.config["source"])
- if !allowed {
- return fmt.Errorf("Disk source path %q not allowed by project for disk %q", d.config["source"], d.name)
+ if shared.IsTrue(instProject.Config["restricted"]) {
+ if instProject.Config["restricted.devices.disk.paths"] != "" {
+ allowed, restrictedParentSourcePath := project.CheckRestrictedDevicesDiskPaths(instProject.Config, d.config["source"])
+ if !allowed {
+ return fmt.Errorf("Disk source path %q not allowed by project for disk %q", d.config["source"], d.name)
+ }
+
+ d.restrictedParentSourcePath = shared.HostPath(restrictedParentSourcePath)
}
if shared.IsTrue(d.config["shift"]) {
return fmt.Errorf(`The "shift" property cannot be used with a restricted source path`)
}
-
- d.restrictedParentSourcePath = shared.HostPath(restrictedParentSourcePath)
}
}
PoC
$ lxc project create restricted -c restricted=true -c restricted.devices.disk=allow
$ lxc project switch restricted
$ lxc profile device add default root disk path=/ pool=default
$ lxc init ubuntu:22.04 c1
$ lxc config device add c1 d1 disk source=/ path=/mnt shift=true
$ lxc start c1 # no error
$ lxc project set restricted restricted.devices.disk.paths=/ # explicitly allow mounting /
$ lxc restart c1
Error: Failed to start device "d1": The "shift" property cannot be used with a restricted source path
Created https://github.com/canonical/lxd/issues/12606 to improve the documentation as per https://github.com/canonical/lxd/security/advisories/GHSA-x9qq-236j-gj97#advisory-comment-91918
Impact
Affected versions
Security releases
Kodem intelligence
Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.
Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.
Remediation advice
github.com/canonical/lxd to 5.20.0 or later; github.com/canonical/lxd to 0.0.0-20240118092008-ce1bd0dd37bb or later
Kodem Kai can prioritize this vulnerability in your dependency tree and generate a fix recommendation.
Frequently Asked Questions
- What is GHSA-X9QQ-236J-GJ97? GHSA-X9QQ-236J-GJ97 is a low-severity security vulnerability in github.com/canonical/lxd (go), affecting versions = 5.19.0. It is fixed in 5.20.0, 0.0.0-20240118092008-ce1bd0dd37bb.
- Which versions of github.com/canonical/lxd are affected by GHSA-X9QQ-236J-GJ97? github.com/canonical/lxd (go) versions = 5.19.0 is affected.
- Is there a fix for GHSA-X9QQ-236J-GJ97? Yes. GHSA-X9QQ-236J-GJ97 is fixed in 5.20.0, 0.0.0-20240118092008-ce1bd0dd37bb. Upgrade to this version or later.
- Is GHSA-X9QQ-236J-GJ97 exploitable, and should I be worried? Whether GHSA-X9QQ-236J-GJ97 is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
- What actually determines whether GHSA-X9QQ-236J-GJ97 is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
- How do I fix GHSA-X9QQ-236J-GJ97?
- Upgrade
github.com/canonical/lxdto 5.20.0 or later - Upgrade
github.com/canonical/lxdto 0.0.0-20240118092008-ce1bd0dd37bb or later
- Upgrade