Merge branch 'PHP-5.6'

* PHP-5.6:
  fix format
  update NEWS
  Add test for bug #69522
  Update tests
  Fix bug #69522 - do not allow int overflow
  Forgot test file
  Fix bug #69403 and other int overflows
  Fixed bug #69418 - more s->p fixes for filenames
  Fixed bug #69364 - use smart_str to assemble strings
  Fix bug #69453 - don't try to cut empty string
  Fix bug #69545 - avoid overflow when reading list

Conflicts:
	Zend/zend_alloc.c
	Zend/zend_operators.c
	ext/ftp/ftp.c
	ext/pcntl/pcntl.c
	ext/standard/basic_functions.c
	ext/standard/dir.c
	ext/standard/file.c
	ext/standard/pack.c
	ext/standard/string.c
	main/rfc1867.c
This commit is contained in:
Stanislav Malyshev 2015-05-12 14:31:52 -07:00
commit 5a1bef8eef
18 changed files with 122 additions and 77 deletions

View File

@ -2293,13 +2293,13 @@ ZEND_API char* ZEND_FASTCALL _estrdup(const char *s ZEND_FILE_LINE_DC ZEND_FILE_
HANDLE_BLOCK_INTERRUPTIONS();
length = strlen(s)+1;
p = (char *) _emalloc(length ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
length = strlen(s);
p = (char *) _emalloc(safe_address(length, 1, 1) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
if (UNEXPECTED(p == NULL)) {
HANDLE_UNBLOCK_INTERRUPTIONS();
return p;
}
memcpy(p, s, length);
memcpy(p, s, length+1);
HANDLE_UNBLOCK_INTERRUPTIONS();
return p;
}
@ -2310,7 +2310,7 @@ ZEND_API char* ZEND_FASTCALL _estrndup(const char *s, size_t length ZEND_FILE_LI
HANDLE_BLOCK_INTERRUPTIONS();
p = (char *) _emalloc(length+1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
p = (char *) _emalloc(safe_address(length, 1, 1) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
if (UNEXPECTED(p == NULL)) {
HANDLE_UNBLOCK_INTERRUPTIONS();
return p;
@ -2328,7 +2328,7 @@ ZEND_API char* ZEND_FASTCALL zend_strndup(const char *s, size_t length)
HANDLE_BLOCK_INTERRUPTIONS();
p = (char *) malloc(length+1);
p = (char *) malloc(safe_address(length, 1, 1));
if (UNEXPECTED(p == NULL)) {
HANDLE_UNBLOCK_INTERRUPTIONS();
return p;

View File

@ -1784,8 +1784,8 @@ ftp_genlist(ftpbuf_t *ftp, const char *cmd, const char *path)
databuf_t *data = NULL;
char *ptr;
int ch, lastch;
int size, rcvd;
int lines;
size_t size, rcvd;
size_t lines;
char **ret = NULL;
char **entry;
char *text;
@ -1827,7 +1827,7 @@ ftp_genlist(ftpbuf_t *ftp, const char *cmd, const char *path)
lines = 0;
lastch = 0;
while ((rcvd = my_recv(ftp, data->fd, data->buf, FTP_BUFSIZE))) {
if (rcvd == -1) {
if (rcvd == -1 || rcvd > ((size_t)(-1))-size) {
goto bail;
}

View File

@ -783,7 +783,7 @@ PHP_FUNCTION(pcntl_exec)
size_t path_len;
zend_ulong key_num;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|aa", &path, &path_len, &args, &envs) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|aa", &path, &path_len, &args, &envs) == FAILURE) {
return;
}

View File

@ -434,7 +434,7 @@ bail:
entry.filename_len = i;
entry.filename = pestrndup(hdr->name, i, myphar->is_persistent);
if (entry.filename[entry.filename_len - 1] == '/') {
if (i > 0 && entry.filename[entry.filename_len - 1] == '/') {
/* some tar programs store directories with trailing slash */
entry.filename[entry.filename_len - 1] = '\0';
entry.filename_len--;

View File

@ -0,0 +1,21 @@
--TEST--
Phar: bug #69453: Memory Corruption in phar_parse_tarfile when entry filename starts with null
--SKIPIF--
<?php if (!extension_loaded("phar")) die("skip"); ?>
--FILE--
<?php
$fname = dirname(__FILE__) . '/bug69453.tar.phar';
try {
$r = new Phar($fname, 0);
} catch(UnexpectedValueException $e) {
echo $e;
}
?>
==DONE==
--EXPECTF--
exception 'UnexpectedValueException' with message 'phar error: "%s/bug69453.tar.phar" is a corrupted tar file (checksum mismatch of file "")' in %s:%d
Stack trace:
#0 %s/bug69453.php(%d): Phar->__construct('%s', 0)
#1 {main}
==DONE==

Binary file not shown.

View File

@ -5409,7 +5409,7 @@ PHP_FUNCTION(set_include_path)
char *old_value;
zend_string *key;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &new_value) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "P", &new_value) == FAILURE) {
return;
}

View File

@ -224,7 +224,7 @@ static void _php_do_opendir(INTERNAL_FUNCTION_PARAMETERS, int createobject)
php_stream_context *context = NULL;
php_stream *dirp;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|r", &dirname, &dir_len, &zcontext) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|r", &dirname, &dir_len, &zcontext) == FAILURE) {
RETURN_NULL();
}
@ -300,7 +300,7 @@ PHP_FUNCTION(chroot)
int ret;
size_t str_len;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &str, &str_len) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &str, &str_len) == FAILURE) {
RETURN_FALSE;
}

View File

@ -806,7 +806,7 @@ PHP_FUNCTION(tempnam)
int fd;
zend_string *p;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ps", &dir, &dir_len, &prefix, &prefix_len) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "pp", &dir, &dir_len, &prefix, &prefix_len) == FAILURE) {
return;
}
@ -1353,7 +1353,7 @@ PHP_FUNCTION(rmdir)
zval *zcontext = NULL;
php_stream_context *context;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|r", &dir, &dir_len, &zcontext) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|r", &dir, &dir_len, &zcontext) == FAILURE) {
RETURN_FALSE;
}

View File

@ -699,6 +699,12 @@ PHP_FUNCTION(unpack)
break;
}
if (size != 0 && size != -1 && size < 0) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type %c: integer overflow", type);
zval_dtor(return_value);
RETURN_FALSE;
}
/* Do actual unpacking */
for (i = 0; i != arg; i++ ) {
/* Space for name + number, safe as namelen is ensured <= 200 */
@ -714,7 +720,8 @@ PHP_FUNCTION(unpack)
if (size != 0 && size != -1 && INT_MAX - size + 1 < inputpos) {
php_error_docref(NULL, E_WARNING, "Type %c: integer overflow", type);
inputpos = 0;
zval_dtor(return_value);
RETURN_FALSE;
}
if ((inputpos + size) <= inputlen) {
@ -798,7 +805,7 @@ PHP_FUNCTION(unpack)
len = size * 2;
}
if (argb > 0) {
if (len > 0 && argb > 0) {
len -= argb % 2;
}

View File

@ -92,27 +92,27 @@ echo "Done";
-- Iteration 1 --
Warning: dir() expects parameter 1 to be string, array given in %s on line %d
Warning: dir() expects parameter 1 to be a valid path, array given in %s on line %d
NULL
-- Iteration 2 --
Warning: dir() expects parameter 1 to be string, array given in %s on line %d
Warning: dir() expects parameter 1 to be a valid path, array given in %s on line %d
NULL
-- Iteration 3 --
Warning: dir() expects parameter 1 to be string, array given in %s on line %d
Warning: dir() expects parameter 1 to be a valid path, array given in %s on line %d
NULL
-- Iteration 4 --
Warning: dir() expects parameter 1 to be string, array given in %s on line %d
Warning: dir() expects parameter 1 to be a valid path, array given in %s on line %d
NULL
-- Iteration 5 --
Warning: dir() expects parameter 1 to be string, array given in %s on line %d
Warning: dir() expects parameter 1 to be a valid path, array given in %s on line %d
NULL
-- Iteration 6 --
@ -151,16 +151,16 @@ bool(false)
-- Iteration 16 --
Warning: dir() expects parameter 1 to be string, resource given in %s on line %d
Warning: dir() expects parameter 1 to be a valid path, resource given in %s on line %d
NULL
-- Iteration 17 --
Warning: dir() expects parameter 1 to be string, resource given in %s on line %d
Warning: dir() expects parameter 1 to be a valid path, resource given in %s on line %d
NULL
-- Iteration 18 --
Warning: dir() expects parameter 1 to be string, object given in %s on line %d
Warning: dir() expects parameter 1 to be a valid path, object given in %s on line %d
NULL
Done

View File

@ -194,7 +194,7 @@ bool(false)
-- Iteration 18 --
Warning: opendir() expects parameter 1 to be string, array given in %s on line %d
Warning: opendir() expects parameter 1 to be a valid path, array given in %s on line %d
NULL
-- Iteration 19 --
@ -219,6 +219,6 @@ bool(false)
-- Iteration 25 --
Warning: opendir() expects parameter 1 to be string, resource given in %s on line %d
Warning: opendir() expects parameter 1 to be a valid path, resource given in %s on line %d
NULL
===DONE===

View File

@ -68,7 +68,7 @@ bool(false)
Warning: mkdir() expects parameter 1 to be a valid path, string given in %s on line %d
bool(false)
Warning: rmdir(%s): No such file or directory in %s on line %d
Warning: rmdir() expects parameter 1 to be a valid path, string given in %s on line %d
bool(false)
*** Testing mkdir() with miscelleneous input ***

View File

@ -105,7 +105,7 @@ Failed, not created in the correct directory %s vs %s
OK
-- Iteration 7 --
Warning: tempnam() expects parameter 2 to be string, array given in %s\ext\standard\tests\file\tempnam_variation3-win32.php on line %d
Warning: tempnam() expects parameter 2 to be a valid path, array given in %s\ext\standard\tests\file\tempnam_variation3-win32.php on line %d
OK
-- Iteration 8 --
OK

View File

@ -100,12 +100,14 @@ File name is => %s/%s
File permissions are => 100600
File created in => directory specified
-- Iteration 6 --
File name is => %s/%s
File permissions are => 100600
File created in => directory specified
Warning: tempnam() expects parameter 2 to be a valid path, string given in %s on line %d
-- File is not created --
Warning: unlink(): %s in %s on line %d
-- Iteration 7 --
Warning: tempnam() expects parameter 2 to be string, array given in %s on line %d
Warning: tempnam() expects parameter 2 to be a valid path, array given in %s on line %d
-- File is not created --
Warning: unlink(): %s in %s on line %d

View File

@ -67,7 +67,7 @@ string(1) "."
NULL
string(1) "."
Warning: set_include_path() expects parameter 1 to be string, array given in %s on line %d
Warning: set_include_path() expects parameter 1 to be a valid path, array given in %s on line %d
NULL
string(1) "."
NULL

View File

@ -0,0 +1,11 @@
--TEST--
Bug #69522 (heap buffer overflow in unpack())
--FILE--
<?php
$a = pack("AAAAAAAAAAAA", 1,2,3,4,5,6,7,8,9,10,11,12);
$b = unpack('h2147483648', $a);
?>
===DONE===
--EXPECTF--
Warning: unpack(): Type h: integer overflow in %s on line %d
===DONE===

View File

@ -33,6 +33,7 @@
#include "php_variables.h"
#include "rfc1867.h"
#include "ext/standard/php_string.h"
#include "ext/standard/php_smart_string.h"
#if defined(PHP_WIN32) && !defined(HAVE_ATOLL)
# define atoll(s) _atoi64(s)
@ -408,8 +409,9 @@ static int find_boundary(multipart_buffer *self, char *boundary)
static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header)
{
char *line;
mime_header_entry prev_entry = {0}, entry;
int prev_len, cur_len;
mime_header_entry entry = {0};
smart_string buf_value = {0};
char *key = NULL;
/* didn't find boundary, abort */
if (!find_boundary(self, self->boundary)) {
@ -421,7 +423,6 @@ static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header)
while( (line = get_line(self)) && line[0] != '\0' )
{
/* add header to table */
char *key = line;
char *value = NULL;
if (php_rfc1867_encoding_translation()) {
@ -434,31 +435,34 @@ static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header)
}
if (value) {
*value = 0;
if(buf_value.c && key) {
/* new entry, add the old one to the list */
smart_string_0(&buf_value);
entry.key = key;
entry.value = buf_value.c;
zend_llist_add_element(header, &entry);
buf_value.c = NULL;
key = NULL;
}
*value = '\0';
do { value++; } while(isspace(*value));
entry.value = estrdup(value);
entry.key = estrdup(key);
} else if (zend_llist_count(header)) { /* If no ':' on the line, add to previous line */
prev_len = (int)strlen(prev_entry.value);
cur_len = (int)strlen(line);
entry.value = emalloc(prev_len + cur_len + 1);
memcpy(entry.value, prev_entry.value, prev_len);
memcpy(entry.value + prev_len, line, cur_len);
entry.value[cur_len + prev_len] = '\0';
entry.key = estrdup(prev_entry.key);
zend_llist_remove_tail(header);
key = estrdup(line);
smart_string_appends(&buf_value, value);
} else if (buf_value.c) { /* If no ':' on the line, add to previous line */
smart_string_appends(&buf_value, line);
} else {
continue;
}
}
if(buf_value.c && key) {
/* add the last one to the list */
smart_string_0(&buf_value);
entry.key = key;
entry.value = buf_value.c;
zend_llist_add_element(header, &entry);
prev_entry = entry;
}
return 1;