See how pam_usb compares to other vendors in security performance
pamusb provides hardware authentication for Linux using removable media. From version 0.8.0 to before version 0.9.3, the denyremote feature in pamusb uses /usr/bin/w -i to detect whether the authenticating user has an active remote tmux session. In pusbtmuxhasremoteclients() (src/tmux.c), the IPv6 detection regex required exactly four explicit colon-separated groups of 1-4 hex digits (e.g. 2001:0db8:85a3:0000). Any IPv6 address in compressed notation — including loopback (::1), link-local (fe80::1), and global unicast addresses (2001:db8::1) — did not match this pattern. As a result the remote-client check silently returned "no remote clients" even when a remote tmux client was connected from such an address. This issue has been patched in version 0.9.3.
pamusb provides hardware authentication for Linux using removable media. Prior to version 0.9.3, src/local.c (pusbgetttyfromdisplayserver) allocates a 4096-byte cmdline buffer, reads up to 4096 bytes from /proc//cmdline, then replaces every NUL separator with a space. When read(2) returns exactly 4096 bytes for any process the function inspects, the buffer ends without a terminator and the subsequent strstr() calls scan past the allocation boundary. The function is invoked during normal PAM authentication when DISPLAY is set, so the read fires for every process at auth time. Consequences are bounded: strstr output is a Boolean substring match (limited info-disclosure surface) but a hostile heap layout can produce a SIGSEGV that terminates the host PAM process. This issue has been patched in version 0.9.3.
pamusb provides hardware authentication for Linux using removable media. Prior to version 0.9.3, src/local.c reads XRDPSESSION with plain getenv(3) at the head of pusblocallogin while every other env consumer in the same function uses securegetenv(3). When pamusb.so loads into a setuid PAM host, the calling user controls the environment passed in. Clearing XRDPSESSION before invoking the host bypasses the explicit XRDP-deny rule. Other remote-detection signals (rmsvc, evdev, loginctl, utmp) may still catch the session, but the env-based detection alone is defeated. This issue has been patched in version 0.9.3.
pamusb provides hardware authentication for Linux using removable media. From version 0.8.0 to before version 0.9.3, the denyremote feature in pamusb uses /usr/bin/w -i to detect whether the authenticating user has an active remote tmux session. In pusbtmuxhasremoteclients() (src/tmux.c), the IPv6 detection pattern matched the address group and then immediately expected whitespace. On Linux systems with multi-homed network interfaces, w -i appends a zone index (scope identifier) to link-local IPv6 addresses — e.g. fe80::1%eth0. The %eth0 suffix appeared between the address and the next whitespace field, causing the regex match to fail even for an otherwise-matching remote session. The function returned "no remote clients" and granted access. This issue has been patched in version 0.9.3.
pamusb provides hardware authentication for Linux using removable media. In versions prior to 0.9.2, getenv() environment variables XRDPSESSION, DISPLAY and TMUX allow environment variable injection into local-check logic. These environment variables influence whether a current session is local or remote, and a PAM module that runs in the context of setuid binaries (sudo, su), getenv() returns attacker-controlled values whenever the process environment has been manipulated by a local user. This issue has been fixed in version 0.9.2.
pamusb provides hardware authentication for Linux using ordinary removable media. In versions prior to 0.9.2, a symlink race condition exists in per-device and per-user pad directory creation. pamusb uses a check-then-act pattern: it calls lstat() to test for existence and then calls mkdir() separately to create the directory. A local attacker can win the race between these calls by replacing the target path with a symlink to a directory they control. If successful, one-time pad files may be written to an attacker-controlled location, potentially exposing future pad values before use or disrupting authentication. This issue has been fixed in version 0.9.2.
pamusb provides hardware authentication for Linux using ordinary removable media. In versions prior to 0.9.2, when updating a one-time pad file, a temporary file is created using open() without the OEXCL flag. Without OEXCL, the create operation is not atomic: two concurrent processes racing to update the same pad may both succeed in opening the file, with the second write silently overwriting the first. The one-time pad is the core replay-prevention mechanism of pamusb. A successful race could result in the stored pad value diverging from what either process expected, potentially causing authentication failures or, in a precisely timed attack, creating a window for pad reuse. This issue has been fixed in version 0.9.2.
pamusb provides hardware authentication for Linux using ordinary removable media. In versions prior to 0.9.2, pamusb calls xmlReadFile() with flags=0 when loading the configuration file, allowing libxml2 to process external entity references (XXE), potentially making outbound network connections or local file reads at XML parse time from the context of the authenticating process. The vulnerability requires the configuration file to contain crafted XML entity references. Since pamusb.conf is root-owned, direct exploitation requires prior write access to the config, but the defence-in-depth impact is significant given that pamusb.so runs in setuid contexts (sudo, su). This issue has been fixed in version 0.9.2.
pamusb provides hardware authentication for Linux using ordinary removable media. In versions 0.9.1 and below, pusbisloginctllocal() 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 strtokr(buf, "\n", &saveptr) returns NULL. A subsequent strcmp(isremote, "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.
pamusb provides hardware authentication for Linux using removable media. In pamusb 0.9.1 and earlier, usbgetprocessparentid() can cause an infinite loop DoS because it does not initialize ppid on failure. In pusblocallogin(), the same variable is reused as input and output in a process-tree while loop; if /proc/<pid>/stat cannot be read (for example, when an ancestor process exits during authentication), the PID is not updated and the loop does not terminate. This hangs the authenticating process (such as sudo, sshd, or login) until it is forcibly terminated. This issue has been fixed in version 0.9.2.
pamusb provides hardware authentication for Linux using ordinary removable media. Prior to 0.8.7, pamusb-pinentry reads the PINENTRYFALLBACKAPP environment variable and executes it directly without any validation. Any process that can set environment variables before pamusb-pinentry is invoked can point PINENTRYFALLBACKAPP at an arbitrary binary or script and have it executed with the privileges of the pamusb tool chain. This vulnerability is fixed in 0.8.7.
pamusb provides hardware authentication for Linux using ordinary removable media. Prior to 0.8.7, src/device.c passed the return values of udisksdrivegetserial(), udisksdrivegetvendor(), and udisksdrivegetmodel() directly to strcmp() without NULL checks. The GIO/UDisks API documentation states these accessors can return NULL for devices that do not expose the corresponding field. Passing NULL to strcmp() is undefined behaviour (typically a SIGSEGV). This vulnerability is fixed in 0.8.7.
pamusb provides hardware authentication for Linux using ordinary removable media. Prior to 0.8.7, symlink attacks on pad directory and pad files enable authentication bypass and root file corruption. This vulnerability is fixed in 0.8.7.
pamusb provides hardware authentication for Linux using ordinary removable media. Prior to 0.8.7, src/tmux.c reads the user's $TMUX environment variable, splits it on commas, and interpolates the socket-path component directly into a shell command passed to popen(). Because the value is placed inside double-quotes without sanitisation, any value containing " terminates the quoted string and injects arbitrary shell syntax. popen() runs as root inside the PAM stack. This vulnerability is fixed in 0.8.7.
pamusb provides hardware authentication for Linux using ordinary removable media. Prior to 0.9.0, pamusb 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 denyremote 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, pusbtmuxgetclienttty() 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 denyremote=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.
pamusb provides hardware authentication for Linux using ordinary removable media. Prior to 0.9.0, src/mem.c implemented out-of-memory guards for xmalloc(), xrealloc(), and xstrdup() using assert(data != NULL). The C standard specifies that all assert() expressions are compiled out when NDEBUG is defined at build time. NDEBUG is commonly defined in release and packaging builds (Debian, Fedora, Arch package flags all define it via -DNDEBUG in CFLAGS). With the guard removed, xmalloc/xrealloc/xstrdup silently return NULL on allocation failure. Every caller in the codebase dereferences the return value without a NULL check -- this is the intended design, as the guard was supposed to abort before the dereference. With the guard gone, any allocation failure causes a NULL pointer dereference, crashing the PAM module. A crash in a PAM module loaded by sudo or login causes authentication to fail for the duration of the crash, creating a local denial-of-service condition. An attacker who can induce memory pressure at authentication time can lock all users out of sudo and login. This vulnerability is fixed in 0.9.0.
pamusb provides hardware authentication for Linux using ordinary removable media. Prior to 0.9.0, the pusbpadcompare() function in src/pad.c only verified that the user-side pad (~/.pamusb/device.pad) could be read, but did not enforce that the system-side pad (the pad file on the USB device) was also present and readable. If the user-side pad was deleted or unreadable, the function returned a failure that was treated as non-fatal in certain code paths, allowing authentication to succeed without the USB device being verified. A local user can delete their own ~/.pamusb/device.pad to remove the USB device requirement and authenticate without the physical device. This vulnerability is fixed in 0.9.0.
pamusb provides hardware authentication for Linux using ordinary removable media. Prior to 0.9.0, pamusb builds XPath expressions from user-supplied identifiers (PAM username, service name) and device-supplied identifiers (USB device serial, model, vendor) to query /etc/pamusb.conf. These identifiers were not validated for XPath metacharacters, allowing injection of arbitrary XPath predicates. This vulnerability is fixed in 0.9.0.
pamusb provides hardware authentication for Linux using ordinary removable media. Prior to 0.9.0, multiple pamusb helper tools resolved external binaries through the PATH environment variable rather than using absolute paths. An attacker who can influence the process environment during PAM authentication or tool execution could substitute malicious binaries. The affected tools are pamusb-check (src/tmux.c), pamusb-conf (tools/pamusb-conf), and pamusb-keyring-unlock-gnome (tools/pamusb-keyring-unlock-gnome). This vulnerability is fixed in 0.9.0.
pamusb provides hardware authentication for Linux using ordinary removable media. Prior to 0.9.1, src/conf.c allocates heap memory proportional to ndevices, a count derived from libxml2 XPath evaluation of the config file, without first enforcing an upper bound. On 32-bit targets (armv7l, i686 -- both listed in the project Makefile), the multiplication ndevices sizeof(tpusbdevice) wraps around sizet, causing xmalloc() to receive a very small size. Because xmalloc() only calls abort() on NULL return, a small-but-non-NULL allocation is accepted, and subsequent array writes overflow the heap. This vulnerability is fixed in 0.9.1.
pamusb provides hardware authentication for Linux using ordinary removable media. Prior to 0.9.1, src/log.c contains a process-wide static pointer that is written on every PAM invocation with the address of a stack-local variable. This violates the PAM re-entrancy requirement and creates a data race when the PAM stack is invoked concurrently from multiple threads. This vulnerability is fixed in 0.9.1.