Bug#797952: libc6: getpwnam() returns a malformed /etc/passwd entry as valid
Package: libc6
Severity: normal
Tags: upstream
Dear Maintainer,
I'm not quite sure how/where to report this bug, but it certainly seems to apply to upstream as the same symptoms occur on REDHAT 5.x
(it also applies to Wheezy, but still exists in Jessie, so reporting here)
We had a malformed NIS passwd entry (NIS is not relevant in bug) where the field-separator (:) was missing between homedir and shell fields. E.g:
# grep sdowdy2 /etc/passwd
sdowdy2:x:8859:1500:Stephen Dowdy:/home/sdowdy/bin/bash
--------------------------------------------------^ (missing : delimiter between homedir and shell)
# simply C executable calling getpwnam(argv[1]) and printing struct values
jlab-core1:~# ./getpwnam sdowdy2
name = sdowdy2
password = x
uid = 8859
gid = 1500
real name = Stephen Dowdy
home directory = /home/sdowdy/bin/bash
shell program =
IMHO, from everything i see, (incl passwd(5)), ':' characters are NOT optional in /etc/passwd, but this record is missing one. I think the best response by getpwnam would be ENOENT, because there exists NO RECORD (no *valid* record) for that user, as the record is, again, malformed.
When coupled with 'pam_mkhomedir', this resulted in the user being able to login, with a /bin/sh shell (this is defined behaviour if the shell field is empty, which it technically is NOT, as the shell field does not exist at all), but by creating an incorrect homedir of /home/sdowdy/bin/bash (sigh).
It could be argued that coupling with the right set of PAM modules and the right (wrong) set of mistakes in a passwd entry, this could be a significant security issue. (i set status of the bug as normal, but feel free to elevate it)
By whittling away, it seems that any passwd file record that contains a minimum of:
username:password:uid:gid
(note the trailing : is not needed for GID field, but upto and including gid are necessary, or else a NULL pointer is returned with errno set SUCCESS!)
is parsed (improperly i might say) and returned with remaining fields blank, making it look as though all the remaining fields and their delimiters are optional. Again, the section 5 manpage for 'passwd' seems pretty clear that ':'s are not optional. (it only mentions that the shell field contents are optional)
>From my best guesses 'pwd/fgetpwent_r.c' is where the problem exists in not validating the record as having a required 6 ':'s separating the 7 fields, and not apparently scanning the whole record for each one and ensuring each was found.
fwiw, 'pwck' does detect an illegal entry, though it doesn't report a reason:
invalid password file entry
delete line 'sdowdy2:x:8859:1500:Stephen Dowdy:/home/sdowdy/bin/bash'? No
Also, 'passwd(1)' throws an exception on this malformed account:
passwd: User not known to underlying authentication module.
passwd: password unchanged.
thanks,
--stephen
-- System Information:
Debian Release: 8.1
APT prefers stable-updates
APT policy: (500, 'stable-updates'), (500, 'stable')
Architecture: amd64 (x86_64)
Foreign Architectures: i386
Kernel: Linux 3.16.0-4-amd64 (SMP w/8 CPU cores)
Locale: LANG=en_US, LC_CTYPE=en_US (charmap=ISO-8859-1)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
Reply to: