pam_usb: NULL Dereference Crash in pusb_is_loginctl_local when loginctl Returns Empty Remote Field
Description
pam_usb provides hardware authentication for Linux using ordinary removable media. In versions 0.9.1 and below, pusb_is_loginctl_local() can cause a NULL dereference crash when parsing loginctl output. The function calls popen() and reads the result; if the Remote field is only a newline, fgets() succeeds but strtok_r(buf, "\n", &saveptr) returns NULL. A subsequent strcmp(is_remote, "no") then dereferences NULL, causing undefined behavior (typically SIGSEGV) and crashing the PAM module. This can crash the authenticating process (e.g., sudo, login) and, depending on PAM stack configuration, deny access for all users of the affected service. This issue has been fixed in version 0.9.2.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Affected products
1Patches
Vulnerability mechanics
Root cause
"Missing NULL check on the return value of strtok_r() before passing it to strcmp() in pusb_is_loginctl_local()."
Attack vector
An attacker who can influence the output of `loginctl` (e.g., by having a session where the `Remote` field is empty or only a newline) triggers a NULL pointer dereference in `pusb_is_loginctl_local()`. The crash occurs when `strtok_r()` returns NULL and `strcmp()` dereferences it [CWE-476]. This crashes the PAM module, which can terminate the authenticating process (e.g., `sudo`, `login`) and, depending on PAM stack configuration, deny access for all users of the affected service [ref_id=1].
Affected code
The vulnerability is in `pusb_is_loginctl_local()` in `src/local.c:306-314`. The function calls `popen()` to run `loginctl`, reads the output with `fgets()`, and then uses `strtok_r()` to parse the `Remote` field. When that field is only a newline, `strtok_r()` returns NULL, and the subsequent `strcmp(is_remote, "no")` dereferences the NULL pointer, causing a crash.
What the fix does
The fix adds a guard before the `strcmp()` call: after `strtok_r()` returns, the code checks `if (!is_remote || *is_remote == '\0')` and, if true, calls `pclose(fp)` and returns 0 [ref_id=1]. This prevents the NULL pointer from being passed to `strcmp()`, avoiding the crash. The patch does not show the exact diff, but the advisory describes the proposed guard.
Preconditions
- inputThe `loginctl` command must output a `Remote` field that is empty or contains only a newline.
- configThe attacker must have a session or be able to influence the loginctl output such that the Remote field is empty.
Generated on Jun 19, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
2- github.com/mcdope/pam_usb/releases/tag/0.9.2mitrex_refsource_MISC
- github.com/mcdope/pam_usb/security/advisories/GHSA-7j6h-wfc2-mg5qmitrex_refsource_CONFIRM
News mentions
0No linked articles in our index yet.