Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix php://input stream to use upload_tmp_dir #705

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 4 additions & 2 deletions NEWS
Expand Up @@ -5,14 +5,16 @@ PHP NEWS
03 Jul 2014, PHP 5.6.0 Release Candidate 2

- Core:
. Fixed bug #67091 (make install fails to install libphp5.so on FreeBSD 10.0).
(Ferenc)
. Fixed bug #67368 (Memory leak with immediately dereferenced array in class
constant). (Laruence)
. Fixed bug #67468 (Segfault in highlight_file()/highlight_string()).
(Andreas Ferber)
. Fixed bug #67091 (make install fails to install libphp5.so on FreeBSD 10.0).
(Ferenc)
. Fixed bug #67498 (phpinfo() Type Confusion Information Leak Vulnerability).
(Stefan Esser)
. Fixed bug #67551 (php://input temp file will be located in sys_temp_dir
instead of upload_tmp_dir). (Mike)

- FPM:
. Fix bug #67531 (syslog cannot be set in pool configuration). (Remi)
Expand Down
2 changes: 1 addition & 1 deletion ext/standard/php_fopen_wrapper.c
Expand Up @@ -231,7 +231,7 @@ php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, const char *pa
if ((input->body = SG(request_info).request_body)) {
php_stream_rewind(input->body);
} else {
input->body = php_stream_temp_create(TEMP_STREAM_DEFAULT, SAPI_POST_BLOCK_SIZE);
input->body = php_stream_temp_create_ex(TEMP_STREAM_DEFAULT, SAPI_POST_BLOCK_SIZE, PG(upload_tmp_dir));
SG(request_info).request_body = input->body;
}

Expand Down
2 changes: 1 addition & 1 deletion main/SAPI.c
Expand Up @@ -279,7 +279,7 @@ SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data)
}


SG(request_info).request_body = php_stream_temp_create(TEMP_STREAM_DEFAULT, SAPI_POST_BLOCK_SIZE);
SG(request_info).request_body = php_stream_temp_create_ex(TEMP_STREAM_DEFAULT, SAPI_POST_BLOCK_SIZE, PG(upload_tmp_dir));

if (sapi_module.read_post) {
int read_bytes;
Expand Down
6 changes: 6 additions & 0 deletions main/php_content_types.c
Expand Up @@ -64,6 +64,12 @@ SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader)
length = php_stream_copy_to_mem(SG(request_info).request_body, &data, PHP_STREAM_COPY_ALL, 0);
php_stream_rewind(SG(request_info).request_body);

if (length > INT_MAX) {
sapi_module.sapi_error(E_WARNING,
"HTTP_RAW_POST_DATA truncated from %lu to %d bytes",
(unsigned long) length, INT_MAX);
length = INT_MAX;
}
SET_VAR_STRINGL("HTTP_RAW_POST_DATA", data, length);

sapi_module.sapi_error(E_DEPRECATED,
Expand Down
2 changes: 2 additions & 0 deletions main/php_memory_streams.h
Expand Up @@ -36,6 +36,7 @@

#define php_stream_temp_new() php_stream_temp_create(TEMP_STREAM_DEFAULT, PHP_STREAM_MAX_MEM)
#define php_stream_temp_create(mode, max_memory_usage) _php_stream_temp_create((mode), (max_memory_usage) STREAMS_CC TSRMLS_CC)
#define php_stream_temp_create_ex(mode, max_memory_usage, tmpdir) _php_stream_temp_create_ex((mode), (max_memory_usage), (tmpdir) STREAMS_CC TSRMLS_CC)
#define php_stream_temp_create_rel(mode, max_memory_usage) _php_stream_temp_create((mode), (max_memory_usage) STREAMS_REL_CC TSRMLS_CC)
#define php_stream_temp_open(mode, max_memory_usage, buf, length) _php_stream_temp_open((mode), (max_memory_usage), (buf), (length) STREAMS_CC TSRMLS_CC)

Expand All @@ -45,6 +46,7 @@ PHPAPI php_stream *_php_stream_memory_open(int mode, char *buf, size_t length ST
PHPAPI char *_php_stream_memory_get_buffer(php_stream *stream, size_t *length STREAMS_DC TSRMLS_DC);

PHPAPI php_stream *_php_stream_temp_create(int mode, size_t max_memory_usage STREAMS_DC TSRMLS_DC);
PHPAPI php_stream *_php_stream_temp_create_ex(int mode, size_t max_memory_usage, const char *tmpdir STREAMS_DC TSRMLS_DC);
PHPAPI php_stream *_php_stream_temp_open(int mode, size_t max_memory_usage, char *buf, size_t length STREAMS_DC TSRMLS_DC);
END_EXTERN_C()

Expand Down
21 changes: 17 additions & 4 deletions main/streams/memory.c
Expand Up @@ -352,6 +352,7 @@ typedef struct {
size_t smax;
int mode;
zval* meta;
char* tmpdir;
} php_stream_temp_data;


Expand All @@ -369,7 +370,7 @@ static size_t php_stream_temp_write(php_stream *stream, const char *buf, size_t
char *membuf = php_stream_memory_get_buffer(ts->innerstream, &memsize);

if (memsize + count >= ts->smax) {
php_stream *file = php_stream_fopen_tmpfile();
php_stream *file = php_stream_fopen_temporary_file(ts->tmpdir, "php", NULL);
php_stream_write(file, membuf, memsize);
php_stream_free_enclosed(ts->innerstream, PHP_STREAM_FREE_CLOSE);
ts->innerstream = file;
Expand Down Expand Up @@ -420,6 +421,10 @@ static int php_stream_temp_close(php_stream *stream, int close_handle TSRMLS_DC)
zval_ptr_dtor(&ts->meta);
}

if (ts->tmpdir) {
efree(ts->tmpdir);
}

efree(ts);

return ret;
Expand Down Expand Up @@ -547,16 +552,18 @@ PHPAPI php_stream_ops php_stream_temp_ops = {

/* }}} */

/* {{{ _php_stream_temp_create */
PHPAPI php_stream *_php_stream_temp_create(int mode, size_t max_memory_usage STREAMS_DC TSRMLS_DC)
/* {{{ _php_stream_temp_create_ex */
PHPAPI php_stream *_php_stream_temp_create_ex(int mode, size_t max_memory_usage, const char *tmpdir STREAMS_DC TSRMLS_DC)
{
php_stream_temp_data *self;
php_stream *stream;

self = ecalloc(1, sizeof(*self));
self->smax = max_memory_usage;
self->mode = mode;
self->meta = NULL;
if (tmpdir) {
self->tmpdir = estrdup(tmpdir);
}
stream = php_stream_alloc_rel(&php_stream_temp_ops, self, 0, mode & TEMP_STREAM_READONLY ? "rb" : "w+b");
stream->flags |= PHP_STREAM_FLAG_NO_BUFFER;
self->innerstream = php_stream_memory_create_rel(mode);
Expand All @@ -566,6 +573,12 @@ PHPAPI php_stream *_php_stream_temp_create(int mode, size_t max_memory_usage STR
}
/* }}} */

/* {{{ _php_stream_temp_create */
PHPAPI php_stream *_php_stream_temp_create(int mode, size_t max_memory_usage STREAMS_DC TSRMLS_DC)
{
return php_stream_temp_create_ex(mode, max_memory_usage, NULL);
}
/* }}} */

/* {{{ _php_stream_temp_open */
PHPAPI php_stream *_php_stream_temp_open(int mode, size_t max_memory_usage, char *buf, size_t length STREAMS_DC TSRMLS_DC)
Expand Down
34 changes: 14 additions & 20 deletions main/streams/plain_wrapper.c
Expand Up @@ -183,31 +183,20 @@ static php_stream *_php_stream_fopen_from_file_int(FILE *file, const char *mode
return php_stream_alloc_rel(&php_stream_stdio_ops, self, 0, mode);
}

PHPAPI php_stream *_php_stream_fopen_temporary_file(const char *dir, const char *pfx, char **opened_path STREAMS_DC TSRMLS_DC)
PHPAPI php_stream *_php_stream_fopen_temporary_file(const char *dir, const char *pfx, char **opened_path_ptr STREAMS_DC TSRMLS_DC)
{
int fd = php_open_temporary_fd(dir, pfx, opened_path TSRMLS_CC);
char *opened_path = NULL;
int fd;

fd = php_open_temporary_fd(dir, pfx, &opened_path TSRMLS_CC);
if (fd != -1) {
php_stream *stream = php_stream_fopen_from_fd_int_rel(fd, "r+b", NULL);
if (stream) {
return stream;
}
close(fd);

php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to allocate stream");

return NULL;
}
return NULL;
}
php_stream *stream;

PHPAPI php_stream *_php_stream_fopen_tmpfile(int dummy STREAMS_DC TSRMLS_DC)
{
char *opened_path = NULL;
int fd = php_open_temporary_fd(NULL, "php", &opened_path TSRMLS_CC);
if (opened_path_ptr) {
*opened_path_ptr = opened_path;
}

if (fd != -1) {
php_stream *stream = php_stream_fopen_from_fd_int_rel(fd, "r+b", NULL);
stream = php_stream_fopen_from_fd_int_rel(fd, "r+b", NULL);
if (stream) {
php_stdio_stream_data *self = (php_stdio_stream_data*)stream->abstract;
stream->wrapper = &php_plain_files_wrapper;
Expand All @@ -227,6 +216,11 @@ PHPAPI php_stream *_php_stream_fopen_tmpfile(int dummy STREAMS_DC TSRMLS_DC)
return NULL;
}

PHPAPI php_stream *_php_stream_fopen_tmpfile(int dummy STREAMS_DC TSRMLS_DC)
{
return php_stream_fopen_temporary_file(NULL, "php", NULL);
}

PHPAPI php_stream *_php_stream_fopen_from_fd(int fd, const char *mode, const char *persistent_id STREAMS_DC TSRMLS_DC)
{
php_stream *stream = php_stream_fopen_from_fd_int_rel(fd, mode, persistent_id);
Expand Down