From: Wez Furlong Date: Thu, 26 Sep 2002 12:12:27 +0000 (+0000) Subject: Fix segfault in wrapper error log mechanism when errors are logged on X-Git-Tag: MODERN_SYMMETRIC_SESSION_BEHAVIOUR_20021003~160 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c484eb8c97b084b09e7368e0ac0947c0c4f4f46f;p=php Fix segfault in wrapper error log mechanism when errors are logged on second and subsequent events. Implement very simple recursion protection for user streams written like this: class urlEncodeStream { var $fp = NULL; function stream_open($path, $mode, $options, &$opened_path) { $this->fp = fopen($path, $mode); // <-- this recurses infinitely return is_resource($this->fp); } } file_register_wrapper('urlencode', 'urlEncodeStream'); $fp = fopen('urlencode:///tmp/outputfile.txt', 'w'); Noticed by: Yasuo. --- diff --git a/ext/standard/file.c b/ext/standard/file.c index b3d2fb539f..38497a4a71 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -132,6 +132,7 @@ static ZEND_RSRC_DTOR_FUNC(file_context_dtor) static void file_globals_ctor(php_file_globals *file_globals_p TSRMLS_DC) { FG(pclose_ret) = 0; + FG(user_stream_current_filename) = NULL; FG(def_chunk_size) = PHP_SOCK_CHUNK_SIZE; } diff --git a/ext/standard/file.h b/ext/standard/file.h index 3990504509..4e5eba55dd 100644 --- a/ext/standard/file.h +++ b/ext/standard/file.h @@ -115,6 +115,7 @@ typedef struct { int auto_detect_line_endings; int default_socket_timeout; char *user_agent; + char *user_stream_current_filename; /* for simple recursion protection */ } php_file_globals; #ifdef ZTS diff --git a/main/streams.c b/main/streams.c index fd22218901..ba8176dd63 100755 --- a/main/streams.c +++ b/main/streams.c @@ -1988,7 +1988,7 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(char *path, char *mode, int optio int free_msg = 0; if (wrapper) { - if (wrapper->err_count) { + if (wrapper->err_count > 0) { int i; size_t l; int brlen; @@ -2038,6 +2038,7 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(char *path, char *mode, int optio if (wrapper->err_stack) efree(wrapper->err_stack); wrapper->err_stack = NULL; + wrapper->err_count = 0; } #if ZEND_DEBUG if (stream == NULL && copy_of_path != NULL) diff --git a/main/user_streams.c b/main/user_streams.c index a6aff3cb8a..5c4ef63b92 100644 --- a/main/user_streams.c +++ b/main/user_streams.c @@ -21,6 +21,7 @@ #include "php.h" #include "php_globals.h" +#include "ext/standard/file.h" static int le_protocols; @@ -137,6 +138,13 @@ static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, char *filena int call_result; php_stream *stream = NULL; + /* Try to catch bad usage without prevent flexibility */ + if (FG(user_stream_current_filename) != NULL && strcmp(filename, FG(user_stream_current_filename)) == 0) { + php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "infinite recursion prevented"); + return NULL; + } + FG(user_stream_current_filename) = filename; + us = emalloc(sizeof(*us)); us->wrapper = uwrap; @@ -206,6 +214,8 @@ static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, char *filena zval_ptr_dtor(&zmode); zval_ptr_dtor(&zfilename); + FG(user_stream_current_filename) = NULL; + return stream; }