diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2019-07-16 13:27:41 +0200 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-07-16 15:47:10 +0200 |
commit | 5161cebe28cca36fa7f7989b5a799290a3f1eb6a (patch) | |
tree | 75cb905c499a7b673445394b3af858116d2e5c31 /main | |
parent | 292354f73ae7b55c062d0a0fc9cc34a8d761cd21 (diff) | |
download | php-git-5161cebe28cca36fa7f7989b5a799290a3f1eb6a.tar.gz |
Fix bug #52752 by not using mmap() to lex files
Using mmap() is unsafe under concurrent modification. If the file
is truncated, access past the end of the file may occur, which will
generate a SIGBUS error. Even if the length does not change, the
contents may, which is a situation that the lexer certainly is not
prepared to deal with either.
Reproduce with test.php:
<?php
file_put_contents(__DIR__ . '/test.tpl',
'AAA<?php $string = "' .
str_repeat('A', mt_rand(1, 256 * 1024)) .
'"; ?>BBB' . "\r\n");
require_once __DIR__ . '/test.tpl';
And:
for ((n=0;n<100;n++)); do sapi/cli/php test.php & done
Diffstat (limited to 'main')
-rw-r--r-- | main/main.c | 52 |
1 files changed, 2 insertions, 50 deletions
diff --git a/main/main.c b/main/main.c index 66cf8df419..c9d37ac2e0 100644 --- a/main/main.c +++ b/main/main.c @@ -84,27 +84,6 @@ #include "rfc1867.h" #include "ext/standard/html_tables.h" - -#if HAVE_MMAP || defined(PHP_WIN32) -# if HAVE_UNISTD_H -# include <unistd.h> -# if defined(_SC_PAGESIZE) -# define REAL_PAGE_SIZE sysconf(_SC_PAGESIZE); -# elif defined(_SC_PAGE_SIZE) -# define REAL_PAGE_SIZE sysconf(_SC_PAGE_SIZE); -# endif -# endif -# if HAVE_SYS_MMAN_H -# include <sys/mman.h> -# endif -# ifndef REAL_PAGE_SIZE -# ifdef PAGE_SIZE -# define REAL_PAGE_SIZE PAGE_SIZE -# else -# define REAL_PAGE_SIZE 4096 -# endif -# endif -#endif /* }}} */ PHPAPI int (*php_register_internal_extensions_func)(void) = php_register_internal_extensions; @@ -1583,13 +1562,6 @@ static void php_zend_stream_closer(void *handle) /* {{{ */ } /* }}} */ -static void php_zend_stream_mmap_closer(void *handle) /* {{{ */ -{ - php_stream_mmap_unmap((php_stream*)handle); - php_zend_stream_closer(handle); -} -/* }}} */ - static size_t php_zend_stream_fsizer(void *handle) /* {{{ */ { php_stream_statbuf ssb; @@ -1608,38 +1580,18 @@ static int php_stream_open_for_zend(const char *filename, zend_file_handle *hand PHPAPI int php_stream_open_for_zend_ex(const char *filename, zend_file_handle *handle, int mode) /* {{{ */ { - char *p; - size_t len, mapped_len; php_stream *stream = php_stream_open_wrapper((char *)filename, "rb", mode, &handle->opened_path); if (stream) { -#if HAVE_MMAP || defined(PHP_WIN32) - size_t page_size = REAL_PAGE_SIZE; -#endif - + handle->type = ZEND_HANDLE_STREAM; handle->filename = (char*)filename; handle->free_filename = 0; handle->handle.stream.handle = stream; handle->handle.stream.reader = (zend_stream_reader_t)_php_stream_read; handle->handle.stream.fsizer = php_zend_stream_fsizer; handle->handle.stream.isatty = 0; - /* can we mmap immediately? */ memset(&handle->handle.stream.mmap, 0, sizeof(handle->handle.stream.mmap)); - len = php_zend_stream_fsizer(stream); - if (len != 0 -#if HAVE_MMAP || defined(PHP_WIN32) - && ((len - 1) % page_size) <= page_size - ZEND_MMAP_AHEAD -#endif - && php_stream_mmap_possible(stream) - && (p = php_stream_mmap_range(stream, 0, len, PHP_STREAM_MAP_MODE_SHARED_READONLY, &mapped_len)) != NULL) { - handle->handle.stream.closer = php_zend_stream_mmap_closer; - handle->handle.stream.mmap.buf = p; - handle->handle.stream.mmap.len = mapped_len; - handle->type = ZEND_HANDLE_MAPPED; - } else { - handle->handle.stream.closer = php_zend_stream_closer; - handle->type = ZEND_HANDLE_STREAM; - } + handle->handle.stream.closer = php_zend_stream_closer; /* suppress warning if this stream is not explicitly closed */ php_stream_auto_cleanup(stream); |