Skip to content

Commit 0f9c708

Browse files
committed
Add mitigation for CVE-2015-0235 (bug #68925)
1 parent 61ad5e2 commit 0f9c708

File tree

5 files changed

+44
-2
lines changed

5 files changed

+44
-2
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? 20?? PHP 5.4.38
44

5+
- Core:
6+
. Fixed bug #68925 (Mitigation for CVE-2015-0235 – GHOST: glibc gethostbyname
7+
buffer overflow). (Stas)
8+
59
22 Jan 2015 PHP 5.4.37
610
- Core:
711
. Fixed bug #68710 (Use After Free Vulnerability in PHP's unserialize()).

ext/standard/dns.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,11 @@ PHP_FUNCTION(gethostbyname)
222222
return;
223223
}
224224

225+
if(hostname_len > MAXHOSTNAMELEN) {
226+
/* name too long, protect from CVE-2015-0235 */
227+
php_error_docref(NULL, E_WARNING, "Host name is too long, the limit is %d characters", MAXHOSTNAMELEN);
228+
RETURN_STRINGL(hostname, hostname_len, 1);
229+
}
225230
addr = php_gethostbyname(hostname);
226231

227232
RETVAL_STRING(addr, 0);
@@ -242,6 +247,12 @@ PHP_FUNCTION(gethostbynamel)
242247
return;
243248
}
244249

250+
if(hostname_len > MAXHOSTNAMELEN) {
251+
/* name too long, protect from CVE-2015-0235 */
252+
php_error_docref(NULL, E_WARNING, "Host name is too long, the limit is %d characters", MAXHOSTNAMELEN);
253+
RETURN_FALSE;
254+
}
255+
245256
hp = gethostbyname(hostname);
246257
if (hp == NULL || hp->h_addr_list == NULL) {
247258
RETURN_FALSE;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
--TEST--
2+
Bug #68925 (CVE-2015-0235 – GHOST: glibc gethostbyname buffer overflow)
3+
--FILE--
4+
<?php
5+
var_dump(gethostbyname(str_repeat("0", 2501)));
6+
var_dump(gethostbynamel(str_repeat("0", 2501)));
7+
?>
8+
--EXPECTF--
9+
Warning: gethostbyname(): Host name is too long, the limit is 256 characters in %s/bug68925.php on line %d
10+
string(2501) "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
11+
12+
Warning: gethostbynamel(): Host name is too long, the limit is 256 characters in %s/bug68925.php on line %d
13+
bool(false)

main/network.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "php.h"
2525

2626
#include <stddef.h>
27+
#include <errno.h>
2728

2829
#ifdef PHP_WIN32
2930
# include "win32/inet.h"
@@ -102,6 +103,10 @@ const struct in6_addr in6addr_any = {0}; /* IN6ADDR_ANY_INIT; */
102103
# define PHP_TIMEOUT_ERROR_VALUE ETIMEDOUT
103104
#endif
104105

106+
#ifndef MAXHOSTNAMELEN
107+
#define MAXHOSTNAMELEN 255
108+
#endif
109+
105110
#if HAVE_GETADDRINFO
106111
#ifdef HAVE_GAI_STRERROR
107112
# define PHP_GAI_STRERROR(x) (gai_strerror(x))
@@ -243,7 +248,12 @@ PHPAPI int php_network_getaddresses(const char *host, int socktype, struct socka
243248
#else
244249
if (!inet_aton(host, &in)) {
245250
/* XXX NOT THREAD SAFE (is safe under win32) */
246-
host_info = gethostbyname(host);
251+
if(strlen(host) > MAXHOSTNAMELEN) {
252+
host_info = NULL;
253+
errno = E2BIG;
254+
} else {
255+
host_info = gethostbyname(host);
256+
}
247257
if (host_info == NULL) {
248258
if (error_string) {
249259
spprintf(error_string, 0, "php_network_getaddresses: gethostbyname failed. errno=%d", errno);

sapi/cgi/fastcgi.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,11 @@ int fcgi_listen(const char *path, int backlog)
611611
if (sa.sa_inet.sin_addr.s_addr == INADDR_NONE) {
612612
struct hostent *hep;
613613

614-
hep = gethostbyname(host);
614+
if(strlen(host) > MAXHOSTNAMELEN) {
615+
hep = NULL;
616+
} else {
617+
hep = gethostbyname(host);
618+
}
615619
if (!hep || hep->h_addrtype != AF_INET || !hep->h_addr_list[0]) {
616620
fprintf(stderr, "Cannot resolve host name '%s'!\n", host);
617621
return -1;

0 commit comments

Comments
 (0)