Full_Name: Xin LI Version: 2.4.25 OS: FreeBSD/amd64 9.0-CURRENT URL: ftp://ftp.openldap.org/incoming/ Submission from: (NULL) (206.40.55.65)
slapd uses inet_ntoa in several places and some of them does not use inet_ntop when it's available. The inet_ntoa is not thread-safe on FreeBSD and thus could cause denial of service if it loses the race, when an IP based ACL is in effect.
diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c index aea3b39..65ce576 100644 --- a/servers/slapd/connection.c +++ b/servers/slapd/connection.c @@ -1500,12 +1500,21 @@ connection_input( Connection *conn , conn_readinfo *cri ) #ifdef LDAP_CONNECTIONLESS if ( conn->c_is_udp ) { char peername[sizeof("IP=255.255.255.255:65336")]; + const char *peeraddr = NULL;
len = ber_int_sb_read(conn->c_sb, &peeraddr, sizeof(struct sockaddr)); if (len != sizeof(struct sockaddr)) return 1;
+#if defined( HAVE_GETADDRINFO ) && defined( HAVE_INET_NTOP ) + char addr[INET_ADDRSTRLEN]; + inet_ntop( AF_INET, &peeraddr.sa_in_addr.sin_addr, + addr, sizeof(addr) ); + peeraddr = addr; +#else /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */ + peeraddr = inet_ntoa( peeraddr.sa_in_addr.sin_addr ); +#endif /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */ sprintf( peername, "IP=%s:%d", - inet_ntoa( peeraddr.sa_in_addr.sin_addr ), + peeraddr, (unsigned) ntohs( peeraddr.sa_in_addr.sin_port ) ); Statslog( LDAP_DEBUG_STATS, "conn=%lu UDP request from %s (%s) accepted.\n", diff --git a/servers/slapd/daemon.c b/servers/slapd/daemon.c index 8e8a69d..ccfa2ee 100644 --- a/servers/slapd/daemon.c +++ b/servers/slapd/daemon.c @@ -1971,8 +1971,16 @@ slap_listener( # ifdef LDAP_PF_INET6 case AF_INET6: if ( IN6_IS_ADDR_V4MAPPED(&from.sa_in6_addr.sin6_addr) ) { +#if defined( HAVE_GETADDRINFO ) && defined( HAVE_INET_NTOP ) + char addr[INET_ADDRSTRLEN]; + inet_ntop( AF_INET, + ((struct in_addr *)&from.sa_in6_addr.sin6_addr.s6_addr[12]), + addr, sizeof(addr) ); + peeraddr = addr; +#else /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */ peeraddr = inet_ntoa( *((struct in_addr *) &from.sa_in6_addr.sin6_addr.s6_addr[12]) ); +#endif /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */ sprintf( peername, "IP=%s:%d", peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN, (unsigned) ntohs( from.sa_in6_addr.sin6_port ) ); @@ -1989,12 +1997,19 @@ slap_listener( break; # endif /* LDAP_PF_INET6 */
- case AF_INET: + case AF_INET: { +#if defined( HAVE_GETADDRINFO ) && defined( HAVE_INET_NTOP ) + char addr[INET_ADDRSTRLEN]; + inet_ntop( AF_INET, &from.sa_in_addr.sin_addr, + addr, sizeof(addr) ); + peeraddr = addr; +#else /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */ peeraddr = inet_ntoa( from.sa_in_addr.sin_addr ); +#endif /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */ sprintf( peername, "IP=%s:%d", peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN, (unsigned) ntohs( from.sa_in_addr.sin_port ) ); - break; + } break;
default: slapd_close(sfd);