summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStanislav Malyshev <stas@php.net>2015-01-31 19:12:00 -0800
committerStanislav Malyshev <stas@php.net>2015-01-31 19:12:20 -0800
commit41bdd6e7cc7671b1c000261a3ccb73411732ce2b (patch)
tree1de213b59180b4a7d5029b4731bff6e1785bbc72
parentd9a9afa4990ede4be6dd4084b8ab550779be4f15 (diff)
parent882a375dbad4ecb1fddd9dd80f1a1350299629c1 (diff)
downloadphp-git-41bdd6e7cc7671b1c000261a3ccb73411732ce2b.tar.gz
Merge branch 'PHP-5.5' into PHP-5.6
* PHP-5.5: Add mitigation for CVE-2015-0235 (bug #68925) Add mitigation for CVE-2015-0235 (bug #68925)
-rw-r--r--NEWS4
-rw-r--r--ext/sockets/sockaddr_conv.c6
-rw-r--r--ext/standard/dns.c11
-rw-r--r--ext/standard/string.c2
-rw-r--r--ext/standard/tests/network/bug68925.phpt13
-rw-r--r--main/network.c13
-rw-r--r--sapi/cgi/fastcgi.c6
7 files changed, 50 insertions, 5 deletions
diff --git a/NEWS b/NEWS
index 3533fb00ad..6b9e21525c 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,10 @@
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? Feb 2015, PHP 5.6.6
+- Core:
+ . Fixed bug #68925 (Mitigation for CVE-2015-0235 – GHOST: glibc gethostbyname
+ buffer overflow). (Stas)
+
- Dba:
. Fixed bug #68711 (useless comparisons). (bugreports at internot dot info)
diff --git a/ext/sockets/sockaddr_conv.c b/ext/sockets/sockaddr_conv.c
index 1c1a90d58f..80807dd243 100644
--- a/ext/sockets/sockaddr_conv.c
+++ b/ext/sockets/sockaddr_conv.c
@@ -9,6 +9,10 @@
#include <arpa/inet.h>
#endif
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 255
+#endif
+
extern int php_string_to_if_index(const char *val, unsigned *out TSRMLS_DC);
#if HAVE_IPV6
@@ -90,7 +94,7 @@ int php_set_inet_addr(struct sockaddr_in *sin, char *string, php_socket *php_soc
if (inet_aton(string, &tmp)) {
sin->sin_addr.s_addr = tmp.s_addr;
} else {
- if (! (host_entry = gethostbyname(string))) {
+ if (strlen(string) > MAXHOSTNAMELEN || ! (host_entry = gethostbyname(string))) {
/* Note: < -10000 indicates a host lookup error */
#ifdef PHP_WIN32
PHP_SOCKET_ERROR(php_sock, "Host lookup failed", WSAGetLastError());
diff --git a/ext/standard/dns.c b/ext/standard/dns.c
index 7d95a22abf..bb5f9109ed 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/string.c b/ext/standard/string.c
index fe7ba24f20..48614dbf74 100644
--- a/ext/standard/string.c
+++ b/ext/standard/string.c
@@ -3935,7 +3935,7 @@ static void php_str_replace_in_subject(zval *search, zval *replace, zval **subje
replace_value, replace_len, &Z_STRLEN(temp_result), case_sensitivity, replace_count);
}
- str_efree(Z_STRVAL_P(result));
+ str_efree(Z_STRVAL_P(result));
Z_STRVAL_P(result) = Z_STRVAL(temp_result);
Z_STRLEN_P(result) = Z_STRLEN(temp_result);
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--
+<?php
+var_dump(gethostbyname(str_repeat("0", 2501)));
+var_dump(gethostbynamel(str_repeat("0", 2501)));
+?>
+--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 6072e76e72..c93e366cc6 100644
--- a/main/network.c
+++ b/main/network.c
@@ -24,7 +24,7 @@
#include "php.h"
#include <stddef.h>
-
+#include <errno.h>
#ifdef PHP_WIN32
@@ -105,6 +105,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))
@@ -246,7 +250,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 5e9e4c89c4..7d39d6139b 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;