Miggo Logo

CVE-2025-54288: Canonical LXD Source Container Identification Vulnerability via cmdline Spoofing in devLXD Server

4.1

CVSS Score
3.1

Basic Information

EPSS Score
0.09466%
Published
10/2/2025
Updated
10/2/2025
KEV Status
No
Technology
TechnologyGo

Technical Details

CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:L/I:N/A:N
Package NameEcosystemVulnerable VersionsFirst Patched Version
github.com/canonical/lxdgo>= 4.0, < 5.21.45.21.4
github.com/canonical/lxdgo>= 6.0, < 6.56.5
github.com/canonical/lxdgo>= 0.0.0-20200331193331-03aab09f5b5c, < 0.0.0-20250827065555-0494f5d47e410.0.0-20250827065555-0494f5d47e41

Vulnerability Intelligence
Miggo AIMiggo AI

Miggo AIRoot Cause Analysis

The vulnerability, as described, is a container identification spoofing issue in Canonical's LXD. The root cause is the reliance on process command-line information (cmdline) to identify a container, without sufficient verification of the process's actual origin. An attacker with root in one container could launch a process with a spoofed name, making it appear to be the monitor process for a different container.

The analysis of the provided patches confirms this. The key change is the replacement of the loadContainerFromLXCMonitorPID function, which only parsed the command line, with a new function getLXCMonitorContainer. This new function adds a critical security check: it verifies the PID namespace of the process by reading the NSpid field from /proc/<pid>/status. If a process is running in a different PID namespace, it cannot be the legitimate monitor process, even if its name is spoofed.

Two primary vulnerable functions were identified that used this flawed logic:

  1. devlxdFindContainerForPID in lxd/api_devlxd.go: This was the main function responsible for mapping a process ID to a container for devLXD API requests. The patch shows the removal of the loop that walked the process tree and called the insecure loadContainerFromLXCMonitorPID.

  2. An anonymous function within (*Daemon).init() in lxd/daemon.go: This function serves as a seccomp handler and also used loadContainerFromLXCMonitorPID to identify containers from PIDs. This provided a second vector for the same attack.

By exploiting these functions, an attacker could bypass container isolation and access sensitive information from other containers on the same host, including metadata, configuration, and device information. The fix, applied in both locations, mitigates this by ensuring the process's PID namespace is validated, preventing the spoofing attack. Security teams should ensure they have patched to LXD 5.21.4 or 6.5 to remediate this vulnerability.

Vulnerable functions

devlxdFindContainerForPID
lxd/api_devlxd.go
This function was the primary entry point for the vulnerability. It attempted to find the container for a given process ID by walking up the process tree and inspecting the command line of parent processes. It used the `loadContainerFromLXCMonitorPID` function, which was insecure because it trusted the process name (`cmdline`) to identify the container. An attacker with root privileges in one container could spoof the process name to impersonate another container and gain access to its metadata, configuration, and devices via the devLXD API. The fix involves using `getLXCMonitorContainer` which adds a crucial check of the PID namespace to prevent this spoofing.
(*Daemon).init.func1
lxd/daemon.go
This anonymous function, used as a seccomp handler, was another entry point for the vulnerability. It directly called the insecure `loadContainerFromLXCMonitorPID` function to identify a container based on a PID from the seccomp listener. This made it vulnerable to the same command line spoofing attack as `devlxdFindContainerForPID`. The patch replaces the call with `getLXCMonitorContainer` to ensure the PID namespace is verified.

WAF Protection Rules

WAF Rule

### Imp**t In LX*'s **vLX* s*rv*r, t** sour** *ont*in*r i**nti*i**tion pro**ss us*s pro**ss *m*lin* (*omm*n* lin*) in*orm*tion, *llowin* *tt**k*rs to imp*rson*t* ot**r *ont*in*rs *y spoo*in* pro**ss n*m*s. T** *or* issu* li*s in t** *in**ont*in*r*or

Reasoning

T** vuln*r**ility, *s **s*ri***, is * *ont*in*r i**nti*i**tion spoo*in* issu* in **noni**l's LX*. T** root **us* is t** r*li*n** on pro**ss *omm*n*-lin* in*orm*tion (`*m*lin*`) to i**nti*y * *ont*in*r, wit*out su**i*i*nt v*ri*i**tion o* t** pro**ss's