Garth Mollett discovered that a file descriptor overflow issue in the use of FD_SET() in nss-pam-ldapd can lead to a stack-based buffer overflow. An attacker could, under some circumstances, use this flaw to cause a process that has the NSS or PAM module loaded to crash or potentially execute arbitrary code.
This vulnerability was fixed in releases 0.7.18 and 0.8.11, though at the time, the security implications of the flaw were unknown. This flaw has been present since release 0.2 (of then nss-ldapd).
The I/O layer used for communicating between the NSS and PAM modules on the one end and nslcd on the other used select() and FD_SET() without checking FD_SETSIZE. This can lead to memory corruption if more than FD_SETSIZE (commonly 1024) file descriptors are open and an NSS lookup is performed using nss-pam-ldapd. This results in an overflow of the fd_set buffer wich is allocated on the stack which in turn can cause pointers on the stack to be corrupted resulting in heap corruption.
The issue can be triggered in a network daemon by opening a large number of connections and forcing a name lookup. This would result in a crash and possibly remote code execution. This issue may also allow local privilege escalation if a suid program does name lookups and doesn't close file descriptors inherited from the parent process.
While the crash condition has been witnessed in production environments in Apache, an exploit that triggers code execution for this issue is not (yet) available.
Release 0.7.18 contains a fix to avoid the overflow condition and return an error for NSS lookups if too many file descriptors are open. In 0.8.11 the use of FD_SET() and select() has been replaced by poll() allowing for full functionality even when more than FD_SETSIZE file descriptors are open.
This problem has been assigned CVE-2013-0288.
Using nscd (or unscd) or limiting the number of open file descriptors with rlimit (system wide) can reduce the exploitability of this issue (but probably not totally avoid it).
the bug report that led to the fix
the fix in the 0.7 series (abf03bc54032beeff95b1b8634cc005137e11f32 in Git)
the minimal fix in the 0.8 series (7867b93f9a7c76b96f1571cddc1de0811134bb81 in Git)
the switch to poll() in the 0.8 series (f266f05f20afe73e89c3946a7bd60bd7c5948e1b in Git)
the original advisory
the commit that introduced the bug (51f3f0903b3f32231f7e8780a5d7c4f9ae1f9203 in Git)
Thanks to Garth Mollett for reporting this issue and providing details. Also thanks to Jan iankko Lieskovsky, Nalin Dahyabhai and Jakub Hrozek from Red Hat for their help in coordinating this advisory.