GHSA-j93m-3j9p-m5m8: LXD has CreateCustomVolumeFromBackup nil-pointer dereference on volumes[0].snapshots[*].expires_at

  • Severity: MEDIUM
  • CVE: CVE-2026-9639
  • Ecosystems: go
  • Packages: github.com/canonical/lxd

## Summary

(sibling-field variant of CVE-2026-40197 fix 05bc272)

`(*lxdBackend).CreateCustomVolumeFromBackup` in [`lxd/storage/backend_lxd.go`](https://github.com/canonical/lxd/blob/05bc272/lxd/storage/backend_lxd.go) contains an unguarded `*time.Time` dereference on the `ExpiresAt` field of every volume-snapshot entry in an imported custom-volume backup. An authenticated user with `EntitlementCanCreateStorageVolumes` permission on any project can crash the `lxd` daemon by uploading a backup tarball whose `volumes[0].snapshots[*].expires_at` field is omitted.

This is a sibling-field variant of the CVE-2026-40197 fix (commit `05bc272`, “Validate snapshots from backup.yaml are non-nil”, cherry-picked from incus commit `985a1dedf` / GHSA-r7w7-mmxr-47r9). That fix added `if snap == nil` guards at several consumer sites, but did not guard the adjacent `*snapshot.ExpiresAt` deref at line 8216. Every other consumer of this field in the same file already gates the deref with `if … != nil` (e.g. lines 1010-1011, 1274-1275, 1856-1857, 2454-2455, 5070-5071, 5527-5528). Asymmetric guard is the bug.

## Vulnerable code

[`lxd/storage/backend_lxd.go`](https://github.com/canonical/lxd/blob/05bc272/lxd/storage/backend_lxd.go), `CreateCustomVolumeFromBackup`:

“`go
// Line 8141-8150 — earliest snapshot validation pass (caches s == nil)
for i, snap := range customVol.Snapshots {
if snap == nil {
return fmt.Errorf(“Nil custom volume snapshot definition found at index %d”, i)
}
err = dri…

Source: GitHub Security Advisories · 2026-11-06