PT-2025-63032
Published
2025-06-02
·
Updated
2025-06-02
Description by
Score
N/A
Not availableNo severity ratings or metrics are available. When they are, we'll update the corresponding info on the page.
In affected versions,
PamHandle::get user can return Err(PAM SUCCESS) after it gets the username successfully.
PAM modules that return this "error" code from sm authenticate or sm acct mgmt early-return a success code to PAM without doing any further verification.
This means a user could log in when they shouldn't be able to (e.g., if the module is sufficient).The
pam try! macro of this crate early-returns the code in this exact way:rust
fn sm authenticate(pamh: &mut PamHandle, args: Vec<&CStr>, flags: PamFlag) -> PamResultCode {
let user = pam try!(pamh.get user(None)); // Can return PAM SUCCESS here.
// If it does, the module does not get to this line.
}The root cause is an [incorrect FFI declaration][ffi-decl] for [
pam get user(3)][pam-get-user].
This C function writes a pointer to the username through its user argument (of type const char **user).
This crate's binding declared this argument as a shared reference (&*mut c char).
Writing through a shared reference is [undefined behavior][ub-immutable].Thus, the compiler can assume that the local pointer, whose address is passed as
user, is still null after the call.
After the call, the affected code [returns Ok][null-check] only if the return code is PAM SUCCESS and this pointer is not null.
Otherwise, it returns the return code as an error.
If the compiler assumes that the pointer is null, get user returns an error even when the return code is PAM SUCCESS.
Release builds have been [observed to do this][observed-irl].
Debug builds usually work correctly, so tests in debug mode can miss the problem.Version 0.1.2 changes the declaration to
&mut *const c char.
The fix is in commit 401c961.If a module cannot upgrade, do not return the error code from
get user.
Return a failure code instead, for example pam try!(pamh.get user(None), PamResultCode::PAM AUTH ERR).
This makes the module deny access instead of allowing it, but the undefined behavior remains.[pam-get-user]: https://github.com/linux-pam/linux-pam/blob/28fce1fd55b003fec90f34e5bc785e9439b216f2/libpam/include/security/pam modules.h#L30-L31
[ffi-decl]: https://github.com/lvkv/pam-rs/blob/3d9318b5b812d9142595928deec23e5843a60995/pam/src/module.rs#L49-L53
[ub-immutable]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html#r-undefined.immutable
[null-check]: https://github.com/lvkv/pam-rs/blob/3d9318b5b812d9142595928deec23e5843a60995/pam/src/module.rs#L196-L202
[observed-irl]: https://github.com/lvkv/pam-rs/issues/16#issuecomment-3693665220
Vendors
Affected products
Related identifiers
Found an issue in the description? Have something to add? Feel free to write us 👾