From: Stanislav Malyshev Date: Sun, 1 Feb 2015 02:59:18 +0000 (-0800) Subject: Add mitigation for CVE-2015-0235 (bug #68925) X-Git-Tag: php-5.4.38~14 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0f9c708229d7d4f4eff96c30cff7a2339f738511;p=php Add mitigation for CVE-2015-0235 (bug #68925) --- diff --git a/NEWS b/NEWS index 248211f15b..2e45ad877c 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,10 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 20?? PHP 5.4.38 +- Core: + . Fixed bug #68925 (Mitigation for CVE-2015-0235 – GHOST: glibc gethostbyname + buffer overflow). (Stas) + 22 Jan 2015 PHP 5.4.37 - Core: . Fixed bug #68710 (Use After Free Vulnerability in PHP's unserialize()). diff --git a/ext/standard/dns.c b/ext/standard/dns.c index 0b5e69ca58..e21aca4919 100644 --- a/ext/standard/dns.c +++ b/ext/standard/dns.c @@ -222,6 +222,11 @@ PHP_FUNCTION(gethostbyname) return; } + if(hostname_len > MAXHOSTNAMELEN) { + /* name too long, protect from CVE-2015-0235 */ + php_error_docref(NULL, E_WARNING, "Host name is too long, the limit is %d characters", MAXHOSTNAMELEN); + RETURN_STRINGL(hostname, hostname_len, 1); + } addr = php_gethostbyname(hostname); RETVAL_STRING(addr, 0); @@ -242,6 +247,12 @@ PHP_FUNCTION(gethostbynamel) return; } + if(hostname_len > MAXHOSTNAMELEN) { + /* name too long, protect from CVE-2015-0235 */ + php_error_docref(NULL, E_WARNING, "Host name is too long, the limit is %d characters", MAXHOSTNAMELEN); + RETURN_FALSE; + } + hp = gethostbyname(hostname); if (hp == NULL || hp->h_addr_list == NULL) { RETURN_FALSE; diff --git a/ext/standard/tests/network/bug68925.phpt b/ext/standard/tests/network/bug68925.phpt new file mode 100644 index 0000000000..e710d72bdf --- /dev/null +++ b/ext/standard/tests/network/bug68925.phpt @@ -0,0 +1,13 @@ +--TEST-- +Bug #68925 (CVE-2015-0235 – GHOST: glibc gethostbyname buffer overflow) +--FILE-- + +--EXPECTF-- +Warning: gethostbyname(): Host name is too long, the limit is 256 characters in %s/bug68925.php on line %d +string(2501) "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + +Warning: gethostbynamel(): Host name is too long, the limit is 256 characters in %s/bug68925.php on line %d +bool(false) diff --git a/main/network.c b/main/network.c index 5e44b0e6a8..41b2cfa0ba 100644 --- a/main/network.c +++ b/main/network.c @@ -24,6 +24,7 @@ #include "php.h" #include +#include #ifdef PHP_WIN32 # include "win32/inet.h" @@ -102,6 +103,10 @@ const struct in6_addr in6addr_any = {0}; /* IN6ADDR_ANY_INIT; */ # define PHP_TIMEOUT_ERROR_VALUE ETIMEDOUT #endif +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 255 +#endif + #if HAVE_GETADDRINFO #ifdef HAVE_GAI_STRERROR # define PHP_GAI_STRERROR(x) (gai_strerror(x)) @@ -243,7 +248,12 @@ PHPAPI int php_network_getaddresses(const char *host, int socktype, struct socka #else if (!inet_aton(host, &in)) { /* XXX NOT THREAD SAFE (is safe under win32) */ - host_info = gethostbyname(host); + if(strlen(host) > MAXHOSTNAMELEN) { + host_info = NULL; + errno = E2BIG; + } else { + host_info = gethostbyname(host); + } if (host_info == NULL) { if (error_string) { spprintf(error_string, 0, "php_network_getaddresses: gethostbyname failed. errno=%d", errno); diff --git a/sapi/cgi/fastcgi.c b/sapi/cgi/fastcgi.c index 8ddc2e4577..4c6ea4c0a3 100644 --- a/sapi/cgi/fastcgi.c +++ b/sapi/cgi/fastcgi.c @@ -611,7 +611,11 @@ int fcgi_listen(const char *path, int backlog) if (sa.sa_inet.sin_addr.s_addr == INADDR_NONE) { struct hostent *hep; - hep = gethostbyname(host); + if(strlen(host) > MAXHOSTNAMELEN) { + hep = NULL; + } else { + hep = gethostbyname(host); + } if (!hep || hep->h_addrtype != AF_INET || !hep->h_addr_list[0]) { fprintf(stderr, "Cannot resolve host name '%s'!\n", host); return -1;