Skip to content

Canonical LXD documentation improvement to make clear restricted.devices.disk=allow without restricted.devices.disk.paths also allows shift=true

Low severity GitHub Reviewed Published Dec 5, 2023 in canonical/lxd • Updated Mar 5, 2024

Package

gomod github.com/canonical/lxd (Go)

Affected versions

= 5.19

Patched versions

5.20

Description

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 canonical/lxd#12606 to improve the documentation as per https://github.com/canonical/lxd/security/advisories/GHSA-x9qq-236j-gj97#advisory-comment-91918

References

@tomponline tomponline published to canonical/lxd Dec 5, 2023
Published to the GitHub Advisory Database Dec 5, 2023
Reviewed Dec 5, 2023
Last updated Mar 5, 2024

Severity

Low

Weaknesses

No CWEs

CVE ID

No known CVE

GHSA ID

GHSA-x9qq-236j-gj97

Source code

Credits

Loading Checking history
See something to contribute? Suggest improvements for this vulnerability.