Skip to main content

pam_usb EUVDEUVD-2026-32655

| CVE-2026-47270 MEDIUM
Race Condition (CWE-362)
2026-05-27 security-advisories@github.com
6.3
CVSS 3.1 · GitHub Advisory
Share

Severity by source

GitHub Advisory PRIMARY
6.3 MEDIUM
AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:N

Primary rating from GitHub Advisory · only source for this CVE.

CVSS VectorGitHub Advisory

CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:N
Attack Vector
Local
Attack Complexity
High
Privileges Required
Low
User Interaction
None
Scope
Unchanged
Confidentiality
High
Integrity
High
Availability
None

Lifecycle Timeline

4
Source Code Evidence Fetched
May 27, 2026 - 22:26 vuln.today
Analysis Generated
May 27, 2026 - 22:26 vuln.today
Patch available
May 27, 2026 - 22:04 EUVD
CVE Published
May 27, 2026 - 21:16 nvd
MEDIUM 6.3

DescriptionGitHub Advisory

pam_usb provides hardware authentication for Linux using ordinary removable media. Prior to 0.9.0, pam_usb is a PAM module loaded into the host process (sudo, login, GDM, GNOME Shell). Display managers such as GDM run multiple concurrent authentication threads. Three functions used by the deny_remote feature called the non-reentrant strtok(), which stores state in a single global pointer. If two authentications race, one thread's strtok() call can overwrite the other's in-progress tokenisation pointer, causing incorrect parsing of the tmux session data or the /proc environ scan that backs the remote-session detection logic. Additionally, pusb_tmux_get_client_tty() passed the raw pointer returned by getenv(TMUX) directly to strtok(). getenv() returns a pointer into the live process environment block; strtok() inserts NUL bytes into that block, permanently corrupting the TMUX variable for subsequent code running in the same process. In long-lived display managers this affects all future authentications in that process. The combined effect can cause deny_remote=true to return an incorrect decision for a remote session, or an incorrect decision for a local session, depending on thread interleaving. This vulnerability is fixed in 0.9.0.

AnalysisAI

Thread-safety flaws in pam_usb's deny_remote feature allow incorrect remote-session authentication decisions in display managers like GDM that run concurrent authentication threads. Three functions use the non-reentrant strtok(), whose single global state pointer can be overwritten mid-parse by a racing thread, corrupting tmux session data or /proc environ analysis used to classify sessions as local or remote. Compounding this, strtok() is called directly on the raw pointer returned by getenv(TMUX), inserting NUL bytes directly into the live process environment block and permanently corrupting the TMUX variable for all subsequent authentications in that long-lived process. An attacker with local low-privileged access on an affected system running GDM could exploit thread interleaving to cause deny_remote=true to pass a remote session as local. No public exploit identified at time of analysis; CVSS 6.3 with local, high-complexity attack vector.

Technical ContextAI

pam_usb is a Linux PAM (Pluggable Authentication Module) that provides hardware-based authentication via removable USB media. PAM modules are loaded directly into the host process address space rather than running as separate daemons, meaning they share memory and environment with the parent - a critical architectural detail here. The deny_remote feature examines tmux session metadata and /proc/[pid]/environ to determine whether an authentication request originates from a remote session. The root cause (CWE-362: Concurrent Execution Using Shared Resource with Improper Synchronization) is the use of strtok() - a C standard library function that stores its parsing cursor in a static global pointer - across three functions invoked by this feature. In display managers such as GDM that spawn multiple concurrent PAM authentication threads, two threads calling strtok() simultaneously will overwrite each other's in-progress parse state, producing corrupted tokens. The second distinct flaw involves getenv(TMUX) returning a direct pointer into the process environment block (not a copy); passing this to strtok() causes in-place NUL byte insertion into the environment, permanently destroying the TMUX variable for the lifetime of the display manager process. Affected versions are all pam_usb releases prior to 0.9.0. No CPE strings were supplied in the input data.

RemediationAI

Upgrade to pam_usb 0.9.0, which resolves the race condition by replacing non-reentrant strtok() calls with thread-safe alternatives and eliminating the in-place mutation of the process environment block. The upstream fix is documented in commits https://github.com/mcdope/pam_usb/commit/94f1640a61d49dfaf38e782680a52f01d5bf8b51 and https://github.com/mcdope/pam_usb/commit/d003e551b794a9e3774ff4720830fb7aadaa48bd, and the full advisory is at https://github.com/mcdope/pam_usb/security/advisories/GHSA-j3xw-vc43-x7jg. If immediate patching is not possible, the most targeted compensating control is to set deny_remote=false in the pam_usb configuration, which disables the vulnerable code paths entirely - the trade-off is loss of remote-session rejection capability, meaning remote users would no longer be denied hardware authentication. A secondary option is restricting pam_usb to single-threaded PAM consumers (e.g., sudo, su) and removing it from GDM or other multi-threaded display managers until patching is complete; this eliminates the race condition by removing concurrency, at the cost of losing hardware authentication in graphical login sessions.

Share

EUVD-2026-32655 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy