|
Description
|
When running the pam_ldap test suite, a few test cases failed
due to the message "Connection to localhost closed" from the
login command. Core files were found and showed the stack
trace as:
# pstack core.login.27298.1125529674
core 'core.login.27298.1125529674' of 27298: login -d /dev/pts/3 -r localhost
ff2897d0 memset (ffbff775, ffbff774, 14a08, fefdbdc0, 33b80, 2f290) + 90
ff01b704 _nss_ldap_lookup (2f290, ffbf9e28, ff02f254, ffbf9b58, 0, ff01beb4) + 7c
ff019a34 getbyname (2f290, ffbf9e28, ffbf9a58, 14664, 1, ff02e000) + a8
ff1dae24 nss_search (ff01998c, ff26b844, ff270790, ffbf9e28, 1, ff2682b8) + 1d4
ff1c97c8 _uncached_getpwnam_r (29c10, ffbffb74, ffbff774, 1000, ff1c9a94, 9eb30) + 50
ff1c9578 getpwnam_r (29c10, ffbffb74, ffbff774, 1000, 29c10, 2fb98) + 88
feb411c4 pam_sm_setcred (296a0, 1, 0, 0, 29c10, feb40ed8) + 2ec
ff3230c8 run_stack (0, 0, 0, 0, 0, 0) + 378
It seems at first the code in nss_ldap.so.1 passed bad pointer or
length to memset(), but further investigation revealed that the
problem was due to pam_sm_setcred's passing incorrect length to
getpwnam_r(). The pam_sm_setcred function is in pam_unix_cred.so.1.
Looking at the source file, src/lib/pam_modules/unix_cred/unix_cred.c,
I found 'getpwnam_r' in the following lines:
224 if (getpwnam_r(user, &pwd, pwbuf, sizeof (buf)) == NULL) {
and
252 (getpwnam_r(ruser, &rpwd, rpwbuf, sizeof (buf)) != NULL)) {
All seems to use an incorrect buffer length (the 4th argument).
The size of pwbuf or rpwbuf is actually NSS_BUFLEN_PASSWD (1024)
but buf is of size PROJECT_BUFSZ (4096, defined in usr/src/head/project.h,
line 41), so nss_ldap.so.1 would have problem zeroing out way too
many bytes (because the memset call is to clear the input buffer).
Please note that this problem is only seen when the nscd daemon is
not running. The nscd uses an internal buffer to interface with
nss_ldap.so.1, so it is not affect by this error.
The pam.debug and core files are attached.
|