- Reported
-
- Issued
-
- Package
-
pam-bindings
(crates.io)
- Type
-
Vulnerability
- Categories
-
- Keywords
-
#pam
#authentication
#ffi
#undefined-behavior
- References
-
- Patched
-
Description
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:
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 for pam_get_user(3).
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.
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 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.
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.
Advisory available under CC0-1.0
license.