1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
|
Subject: Fixed bug #54092 (Segmentation fault when using HTTP proxy with the FTP wrapper).
Origin: http://svn.php.net/viewvc?view=revision&revision=308734
#php_stream->wrapperdata should hold an array zval (like its zval* type
#indicates...), it's not a place where the wrapper can drop an arbitrary
#pointer. For that, .wrapperthis should be used.
#Also, since the ftp dir wrapper defines its own stream type, it's more
#appropriate to use .abstract to store the stream instance specific data.
CVE-2011-1469
Patch differs from upstream commit in that it drops the added NEWS file
entry to reduce patch conflicts, and adjusted for earlier versions of
php.
--- a/ext/standard/ftp_fopen_wrapper.c
+++ b/ext/standard/ftp_fopen_wrapper.c
@@ -72,6 +72,12 @@
#define FTPS_ENCRYPT_DATA 1
#define GET_FTP_RESULT(stream) get_ftp_result((stream), tmp_line, sizeof(tmp_line) TSRMLS_CC)
+typedef struct _php_ftp_dirstream_data {
+ php_stream *datastream;
+ php_stream *controlstream;
+ php_stream *dirstream;
+} php_ftp_dirstream_data;
+
/* {{{ get_ftp_result
*/
static inline int get_ftp_result(php_stream *stream, char *buffer, size_t buffer_size TSRMLS_DC)
@@ -97,12 +103,12 @@ static int php_stream_ftp_stream_stat(ph
*/
static int php_stream_ftp_stream_close(php_stream_wrapper *wrapper, php_stream *stream TSRMLS_DC)
{
- php_stream *controlstream = (php_stream *)stream->wrapperdata;
+ php_stream *controlstream = stream->wrapperthis;
if (controlstream) {
php_stream_write_string(controlstream, "QUIT\r\n");
php_stream_close(controlstream);
- stream->wrapperdata = NULL;
+ stream->wrapperthis = NULL;
}
return 0;
}
@@ -564,7 +570,7 @@ php_stream * php_stream_url_wrap_ftp(php
}
/* remember control stream */
- datastream->wrapperdata = (zval *)stream;
+ datastream->wrapperthis = stream;
php_url_free(resource);
return datastream;
@@ -588,11 +594,13 @@ errexit:
static size_t php_ftp_dirstream_read(php_stream *stream, char *buf, size_t count TSRMLS_DC)
{
php_stream_dirent *ent = (php_stream_dirent *)buf;
- php_stream *innerstream = (php_stream *)stream->abstract;
+ php_stream *innerstream;
size_t tmp_len;
char *basename;
size_t basename_len;
+ innerstream = ((php_ftp_dirstream_data *)stream->abstract)->datastream;
+
if (count != sizeof(php_stream_dirent)) {
return 0;
}
@@ -636,13 +644,18 @@ static size_t php_ftp_dirstream_read(php
*/
static int php_ftp_dirstream_close(php_stream *stream, int close_handle TSRMLS_DC)
{
- php_stream *innerstream = (php_stream *)stream->abstract;
+ php_ftp_dirstream_data *data = stream->abstract;
- if (innerstream->wrapperdata) {
- php_stream_close((php_stream *)innerstream->wrapperdata);
- innerstream->wrapperdata = NULL;
- }
- php_stream_close((php_stream *)stream->abstract);
+ /* close control connection */
+ if (data->controlstream) {
+ php_stream_close(data->controlstream);
+ data->controlstream = NULL;
+ }
+ /* close data connection */
+ php_stream_close(data->datastream);
+ data->datastream = NULL;
+
+ efree(data);
stream->abstract = NULL;
return 0;
@@ -668,6 +681,7 @@ static php_stream_ops php_ftp_dirstream_
php_stream * php_stream_ftp_opendir(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC)
{
php_stream *stream, *reuseid, *datastream = NULL;
+ php_ftp_dirstream_data *dirsdata;
php_url *resource = NULL;
int result = 0, use_ssl, use_ssl_on_data = 0;
char *hoststart = NULL, tmp_line[512];
@@ -727,11 +741,14 @@ php_stream * php_stream_ftp_opendir(php_
goto opendir_errexit;
}
- /* remember control stream */
- datastream->wrapperdata = (zval *)stream;
-
php_url_free(resource);
- return php_stream_alloc(&php_ftp_dirstream_ops, datastream, 0, mode);
+
+ dirsdata = emalloc(sizeof *dirsdata);
+ dirsdata->datastream = datastream;
+ dirsdata->controlstream = stream;
+ dirsdata->dirstream = php_stream_alloc(&php_ftp_dirstream_ops, dirsdata, 0, mode);
+
+ return dirsdata->dirstream;
opendir_errexit:
if (resource) {
|