Bug 998096 - (CVE-2014-8182) VUL-1: CVE-2014-8182: nss-pam-ldapd: crash in ldap_domain2hostlist when processing SRV records
(CVE-2014-8182)
VUL-1: CVE-2014-8182: nss-pam-ldapd: crash in ldap_domain2hostlist when proce...
Status: RESOLVED INVALID
Classification: Novell Products
Product: SUSE Security Incidents
Classification: Novell Products
Component: Incidents
unspecified
Other Other
: P4 - Low : Minor
: ---
Assigned To: Howard Guo
Security Team bot
https://smash.suse.de/issue/172463/
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2016-09-09 07:32 UTC by Victor Pereira
Modified: 2016-10-04 12:48 UTC (History)
4 users (show)

See Also:
Found By: Security Response Team
Services Priority:
Business Priority:
Blocker: ---
Marketing QA Status: ---
IT Deployment: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Victor Pereira 2016-09-09 07:32:13 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
Comment 1 Victor Pereira 2016-09-09 07:32:31 UTC
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;
Comment 2 Howard Guo 2016-09-09 09:08:23 UTC
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?
Comment 4 Howard Guo 2016-09-09 12:23:21 UTC
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.
Comment 5 Swamp Workflow Management 2016-09-09 22:00:13 UTC
bugbot adjusting priority
Comment 6 Johannes Segitz 2016-10-04 12:48:32 UTC
can't find it either, closing