Bugzilla – Bug 998096
VUL-1: CVE-2014-8182: nss-pam-ldapd: crash in ldap_domain2hostlist when processing SRV records
Last modified: 2016-10-04 12:48:32 UTC
rh#1095976 Description of problem: The nss-pam-ldapd daemon nslcd can be configured to find ldap servers via SRV lookups on a domain. With this configuration, a crash seen when starting nslcd can be caused by a number of specific SRV records presented to ldap_domain2hostlist(). The records are a set of 5+ SRV records for _ldap._tcp, all with a 5-digit port number, i.e. 12345. [root@auto1 ~]# dig SRV _ldap._tcp.rodan.local | grep ldap ; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.23.rc1.el6_5.1 <<>> SRV _ldap._tcp.rodan.local ;_ldap._tcp.rodan.local. IN SRV _ldap._tcp.rodan.local. 3600 IN SRV 1 5 15001 activedirectory2.rodan.local. _ldap._tcp.rodan.local. 3600 IN SRV 1 5 15001 activedirectory3.rodan.local. _ldap._tcp.rodan.local. 3600 IN SRV 1 5 15001 activedirectory4.rodan.local. _ldap._tcp.rodan.local. 3600 IN SRV 0 5 15001 ads.rodan.local. _ldap._tcp.rodan.local. 3600 IN SRV 0 5 15001 ads2.rodan.local. _ldap._tcp.rodan.local. 3600 IN SRV 0 5 15001 ads3.rodan.local. _ldap._tcp.rodan.local. 3600 IN SRV 1 5 15001 activedirectory.rodan.local. On startup this crash happens most of the time, and can appear differently: [root@auto1 ~]# nslcd -d nslcd: DEBUG: query rodan.local for SRV records *** glibc detected *** nslcd: realloc(): invalid next size: 0x0000000001e29480 *** ======= Backtrace: ========= /lib64/libc.so.6(+0x76166)[0x7fda91c7a166] /lib64/libc.so.6(+0x7bc17)[0x7fda91c7fc17] /lib64/libc.so.6(realloc+0xe5)[0x7fda91c7fdd5] /lib64/liblber-2.4.so.2(ber_memrealloc_x+0x2a)[0x7fda919fd87a] /lib64/libldap_r-2.4.so.2(ldap_domain2hostlist+0x423)[0x7fda92400f33] nslcd[0x407fb1] nslcd[0x408c0e] nslcd[0x40a21d] nslcd[0x403a75] /lib64/libc.so.6(__libc_start_main+0xfd)[0x7fda91c22d1d] nslcd[0x402d39] ======= Memory map: ======== 00400000-0041d000 r-xp 00000000 fd:00 405486 /usr/sbin/nslcd 0061d000-0061e000 rw-p 0001d000 fd:00 405486 /usr/sbin/nslcd 01e28000-01e49000 rw-p 00000000 00:00 0 [heap] 7fda8ed94000-7fda8ee05000 r-xp 00000000 fd:00 261638 /lib64/libfreebl3.so ... [root@auto1 ~]# nslcd -d nslcd: DEBUG: query rodan.local for SRV records *** glibc detected *** nslcd: realloc(): invalid next size: 0x00000000023b3480 *** *** glibc detected *** nslcd: malloc(): memory corruption: 0x00000000023b34f0 *** ^C [root@auto1 ~]# nslcd -d nslcd: DEBUG: query rodan.local for SRV records *** glibc detected *** nslcd: realloc(): invalid next size: 0x00000000020bd480 *** *** glibc detected *** nslcd: malloc(): memory corruption: 0x00000000020bd4f0 *** ^C [root@auto1 ~]# nslcd -d nslcd: DEBUG: query rodan.local for SRV records nslcd: DEBUG: add_uris_from_dns(): found uri: ldap://activedirectory4.rodan.local:15001 nslcd: DEBUG: add_uri(ldap://activedirectory4.rodan.local:15001) nslcd: DEBUG: add_uris_from_dns(): found uri: ldap://activedirectory.rodan.local:15001 nslcd: DEBUG: add_uri(ldap://activedirectory.rodan.local:15001) nslcd: DEBUG: add_uris_from_dns(): found uri: ldap://activedirectory3.rodan.local:15001 nslcd: DEBUG: add_uri(ldap://activedirectory3.rodan.local:15001) nslcd: DEBUG: add_uris_from_dns(): found uri: ldap://activedirectory2.rodan.local:15001 nslcd: DEBUG: add_uri(ldap://activedirectory2.rodan.local:15001) nslcd: DEBUG: add_uris_from_dns(): found uri: ldap://ads.rodan.local:15001 nslcd: DEBUG: add_uri(ldap://ads.rodan.local:15001) nslcd: DEBUG: add_uris_from_dns(): found uri: ldap://ads2.rodan.local:15001 nslcd: DEBUG: add_uri(ldap://ads2.rodan.local:15001) nslcd: DEBUG: add_uris_from_dns(): found uri: ldap://ads3.rodan.local:15001 The crash is related to the maximum length of a port specified in the SRV record. Any 4 digit or less ports did not crash with the same entries, so I suspected that in ldap_domain2hostlist(), doing STRLENOF(":65355") with the 5 digit port ends up missing a byte. It also only starts to show up when there are 5 or more entries in the host list, as it appears that the sprintf at the end of the hostent_count loop needs to be called enough times for this to corrupt the hostlist array. With a larger number of entries the crash would probably have a greater chance of happening. I'm attaching a patch that changes STRLENOF to sizeof, to account for the proper length needed in the buffer for a max length port. With the patch I tested multiple restarts of nslcd against the records and I wasn't able to reproduce the crash. I think this bug should be evaluated as a possible CVE. In the event of DNS hijacking/spoofing, a malicious nameserver presenting these specific SRV records may be able to cause a DoS to ldap services that utilize ldap_domain2hostlist(). Version-Release number of selected component (if applicable): openldap-2.4.23-34.el6_5.1 How reproducible: 1. Create SRV records in DNS as specified above 2. Configure nslcd to do SRV lookups to locate an ldap server (in /etc/nslcd.conf, set 'uri:DNS:domain') 3. Start nslcd in foreground debug mode (nslcd -d) References: https://bugzilla.redhat.com/show_bug.cgi?id=1095976 http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-8182 http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-8182
Looking at upstream git, this looks to have been fixed by d13285fd which would have the same effect as my patch: commit d13285fdd81eeec010dd273090d45e55f4b400fe Author: Kurt Zeilenga <kurt@openldap.org> Date: Mon Jul 8 18:45:53 2002 +0000 Fix possible under allocation of buffer diff --git a/libraries/libldap/dnssrv.c b/libraries/libldap/dnssrv.c index cc193e9..0f7c863 100644 --- a/libraries/libldap/dnssrv.c +++ b/libraries/libldap/dnssrv.c @@ -261,7 +261,7 @@ int ldap_domain2hostlist( /* weight = (p[2] << 8) | p[3]; */ port = (p[4] << 8) | p[5]; - buflen = strlen(host) + sizeof(":65355"); + buflen = strlen(host) + sizeof(":65355 "); hostlist = (char *) LDAP_REALLOC(hostlist, cur + buflen); if (hostlist == NULL) { rc = LDAP_NO_MEMORY;
I checked the source code and patches among SLE and openSUSE distributions and cannot find the offending code, Victor would you please double check again in case I missed anything?
Hi Victor. The offending code doesn't exist in nslcd either, I have just set up the case on this computer and nslcd doesn't crash. So I think we are safe for now.
bugbot adjusting priority
can't find it either, closing