|
|
30ceb2 |
From ac2832935435556dc593784cd0087b5e576bbe4d Mon Sep 17 00:00:00 2001
|
|
|
30ceb2 |
From: Stanislav Malyshev <stas@php.net>
|
|
|
30ceb2 |
Date: Wed, 29 Apr 2015 21:57:33 -0700
|
|
|
30ceb2 |
Subject: [PATCH] Fix bug #69545 - avoid overflow when reading list
|
|
|
30ceb2 |
|
|
|
30ceb2 |
---
|
|
|
30ceb2 |
ext/ftp/ftp.c | 82 +++++++++++++++++++++++++++++------------------------------
|
|
|
30ceb2 |
1 file changed, 41 insertions(+), 41 deletions(-)
|
|
|
30ceb2 |
|
|
|
30ceb2 |
diff --git a/ext/ftp/ftp.c b/ext/ftp/ftp.c
|
|
|
30ceb2 |
index 3ff54ff..53560eb 100644
|
|
|
30ceb2 |
--- a/ext/ftp/ftp.c
|
|
|
30ceb2 |
+++ b/ext/ftp/ftp.c
|
|
|
30ceb2 |
@@ -188,9 +188,9 @@ ftp_close(ftpbuf_t *ftp)
|
|
|
30ceb2 |
SSL_shutdown(ftp->ssl_handle);
|
|
|
30ceb2 |
SSL_free(ftp->ssl_handle);
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
-#endif
|
|
|
30ceb2 |
+#endif
|
|
|
30ceb2 |
closesocket(ftp->fd);
|
|
|
30ceb2 |
- }
|
|
|
30ceb2 |
+ }
|
|
|
30ceb2 |
ftp_gc(ftp);
|
|
|
30ceb2 |
efree(ftp);
|
|
|
30ceb2 |
return NULL;
|
|
|
30ceb2 |
@@ -262,7 +262,7 @@ ftp_login(ftpbuf_t *ftp, const char *user, const char *pass TSRMLS_DC)
|
|
|
30ceb2 |
if (!ftp_getresp(ftp)) {
|
|
|
30ceb2 |
return 0;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
-
|
|
|
30ceb2 |
+
|
|
|
30ceb2 |
if (ftp->resp != 234) {
|
|
|
30ceb2 |
if (!ftp_putcmd(ftp, "AUTH", "SSL")) {
|
|
|
30ceb2 |
return 0;
|
|
|
30ceb2 |
@@ -270,7 +270,7 @@ ftp_login(ftpbuf_t *ftp, const char *user, const char *pass TSRMLS_DC)
|
|
|
30ceb2 |
if (!ftp_getresp(ftp)) {
|
|
|
30ceb2 |
return 0;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
-
|
|
|
30ceb2 |
+
|
|
|
30ceb2 |
if (ftp->resp != 334) {
|
|
|
30ceb2 |
return 0;
|
|
|
30ceb2 |
} else {
|
|
|
30ceb2 |
@@ -278,7 +278,7 @@ ftp_login(ftpbuf_t *ftp, const char *user, const char *pass TSRMLS_DC)
|
|
|
30ceb2 |
ftp->use_ssl_for_data = 1;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
-
|
|
|
30ceb2 |
+
|
|
|
30ceb2 |
ctx = SSL_CTX_new(SSLv23_client_method());
|
|
|
30ceb2 |
if (ctx == NULL) {
|
|
|
30ceb2 |
php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to create the SSL context");
|
|
|
30ceb2 |
@@ -325,8 +325,8 @@ ftp_login(ftpbuf_t *ftp, const char *user, const char *pass TSRMLS_DC)
|
|
|
30ceb2 |
if (!ftp_getresp(ftp)) {
|
|
|
30ceb2 |
return 0;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
-
|
|
|
30ceb2 |
- ftp->use_ssl_for_data = (ftp->resp >= 200 && ftp->resp <=299);
|
|
|
30ceb2 |
+
|
|
|
30ceb2 |
+ ftp->use_ssl_for_data = (ftp->resp >= 200 && ftp->resp <=299);
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
#endif
|
|
|
30ceb2 |
@@ -360,7 +360,7 @@ ftp_reinit(ftpbuf_t *ftp)
|
|
|
30ceb2 |
{
|
|
|
30ceb2 |
if (ftp == NULL) {
|
|
|
30ceb2 |
return 0;
|
|
|
30ceb2 |
- }
|
|
|
30ceb2 |
+ }
|
|
|
30ceb2 |
|
|
|
30ceb2 |
ftp_gc(ftp);
|
|
|
30ceb2 |
|
|
|
30ceb2 |
@@ -395,7 +395,7 @@ ftp_syst(ftpbuf_t *ftp)
|
|
|
30ceb2 |
if (!ftp_putcmd(ftp, "SYST", NULL)) {
|
|
|
30ceb2 |
return NULL;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
- if (!ftp_getresp(ftp) || ftp->resp != 215) {
|
|
|
30ceb2 |
+ if (!ftp_getresp(ftp) || ftp->resp != 215) {
|
|
|
30ceb2 |
return NULL;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
syst = ftp->inbuf;
|
|
|
30ceb2 |
@@ -431,14 +431,14 @@ ftp_pwd(ftpbuf_t *ftp)
|
|
|
30ceb2 |
if (!ftp_putcmd(ftp, "PWD", NULL)) {
|
|
|
30ceb2 |
return NULL;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
- if (!ftp_getresp(ftp) || ftp->resp != 257) {
|
|
|
30ceb2 |
+ if (!ftp_getresp(ftp) || ftp->resp != 257) {
|
|
|
30ceb2 |
return NULL;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
/* copy out the pwd from response */
|
|
|
30ceb2 |
- if ((pwd = strchr(ftp->inbuf, '"')) == NULL) {
|
|
|
30ceb2 |
+ if ((pwd = strchr(ftp->inbuf, '"')) == NULL) {
|
|
|
30ceb2 |
return NULL;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
- if ((end = strrchr(++pwd, '"')) == NULL) {
|
|
|
30ceb2 |
+ if ((end = strrchr(++pwd, '"')) == NULL) {
|
|
|
30ceb2 |
return NULL;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
ftp->pwd = estrndup(pwd, end - pwd);
|
|
|
30ceb2 |
@@ -608,7 +608,7 @@ ftp_chmod(ftpbuf_t *ftp, const int mode, const char *filename, const int filenam
|
|
|
30ceb2 |
if (!ftp_getresp(ftp) || ftp->resp != 200) {
|
|
|
30ceb2 |
return 0;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
-
|
|
|
30ceb2 |
+
|
|
|
30ceb2 |
return 1;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
/* }}} */
|
|
|
30ceb2 |
@@ -625,7 +625,7 @@ ftp_alloc(ftpbuf_t *ftp, const long size, char **response)
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
|
|
|
30ceb2 |
snprintf(buffer, sizeof(buffer) - 1, "%ld", size);
|
|
|
30ceb2 |
-
|
|
|
30ceb2 |
+
|
|
|
30ceb2 |
if (!ftp_putcmd(ftp, "ALLO", buffer)) {
|
|
|
30ceb2 |
return 0;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
@@ -642,7 +642,7 @@ ftp_alloc(ftpbuf_t *ftp, const long size, char **response)
|
|
|
30ceb2 |
return 0;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
|
|
|
30ceb2 |
- return 1;
|
|
|
30ceb2 |
+ return 1;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
/* }}} */
|
|
|
30ceb2 |
|
|
|
30ceb2 |
@@ -674,7 +674,7 @@ ftp_type(ftpbuf_t *ftp, ftptype_t type)
|
|
|
30ceb2 |
if (ftp == NULL) {
|
|
|
30ceb2 |
return 0;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
- if (type == ftp->type) {
|
|
|
30ceb2 |
+ if (type == ftp->type) {
|
|
|
30ceb2 |
return 1;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
if (type == FTPTYPE_ASCII) {
|
|
|
30ceb2 |
@@ -765,7 +765,7 @@ ftp_pasv(ftpbuf_t *ftp, int pasv)
|
|
|
30ceb2 |
if (!ftp_putcmd(ftp, "PASV", NULL)) {
|
|
|
30ceb2 |
return 0;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
- if (!ftp_getresp(ftp) || ftp->resp != 227) {
|
|
|
30ceb2 |
+ if (!ftp_getresp(ftp) || ftp->resp != 227) {
|
|
|
30ceb2 |
return 0;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
/* parse out the IP and port */
|
|
|
30ceb2 |
@@ -807,7 +807,7 @@ ftp_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type,
|
|
|
30ceb2 |
if ((data = ftp_getdata(ftp TSRMLS_CC)) == NULL) {
|
|
|
30ceb2 |
goto bail;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
-
|
|
|
30ceb2 |
+
|
|
|
30ceb2 |
ftp->data = data;
|
|
|
30ceb2 |
|
|
|
30ceb2 |
if (resumepos > 0) {
|
|
|
30ceb2 |
@@ -900,7 +900,7 @@ ftp_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, l
|
|
|
30ceb2 |
if ((data = ftp_getdata(ftp TSRMLS_CC)) == NULL) {
|
|
|
30ceb2 |
goto bail;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
- ftp->data = data;
|
|
|
30ceb2 |
+ ftp->data = data;
|
|
|
30ceb2 |
|
|
|
30ceb2 |
if (startpos > 0) {
|
|
|
30ceb2 |
snprintf(arg, sizeof(arg), "%ld", startpos);
|
|
|
30ceb2 |
@@ -1101,7 +1101,7 @@ ftp_putcmd(ftpbuf_t *ftp, const char *cmd, const char *args)
|
|
|
30ceb2 |
|
|
|
30ceb2 |
if (strpbrk(cmd, "\r\n")) {
|
|
|
30ceb2 |
return 0;
|
|
|
30ceb2 |
- }
|
|
|
30ceb2 |
+ }
|
|
|
30ceb2 |
/* build the output buffer */
|
|
|
30ceb2 |
if (args && args[0]) {
|
|
|
30ceb2 |
/* "cmd args\r\n\0" */
|
|
|
30ceb2 |
@@ -1247,7 +1247,7 @@ my_send(ftpbuf_t *ftp, php_socket_t s, void *buf, size_t len)
|
|
|
30ceb2 |
#if HAVE_OPENSSL_EXT
|
|
|
30ceb2 |
if (ftp->use_ssl && ftp->fd == s && ftp->ssl_active) {
|
|
|
30ceb2 |
sent = SSL_write(ftp->ssl_handle, buf, size);
|
|
|
30ceb2 |
- } else if (ftp->use_ssl && ftp->fd != s && ftp->use_ssl_for_data && ftp->data->ssl_active) {
|
|
|
30ceb2 |
+ } else if (ftp->use_ssl && ftp->fd != s && ftp->use_ssl_for_data && ftp->data->ssl_active) {
|
|
|
30ceb2 |
sent = SSL_write(ftp->data->ssl_handle, buf, size);
|
|
|
30ceb2 |
} else {
|
|
|
30ceb2 |
#endif
|
|
|
30ceb2 |
@@ -1287,14 +1287,14 @@ my_recv(ftpbuf_t *ftp, php_socket_t s, void *buf, size_t len)
|
|
|
30ceb2 |
#if HAVE_OPENSSL_EXT
|
|
|
30ceb2 |
if (ftp->use_ssl && ftp->fd == s && ftp->ssl_active) {
|
|
|
30ceb2 |
nr_bytes = SSL_read(ftp->ssl_handle, buf, len);
|
|
|
30ceb2 |
- } else if (ftp->use_ssl && ftp->fd != s && ftp->use_ssl_for_data && ftp->data->ssl_active) {
|
|
|
30ceb2 |
+ } else if (ftp->use_ssl && ftp->fd != s && ftp->use_ssl_for_data && ftp->data->ssl_active) {
|
|
|
30ceb2 |
nr_bytes = SSL_read(ftp->data->ssl_handle, buf, len);
|
|
|
30ceb2 |
} else {
|
|
|
30ceb2 |
#endif
|
|
|
30ceb2 |
nr_bytes = recv(s, buf, len, 0);
|
|
|
30ceb2 |
#if HAVE_OPENSSL_EXT
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
-#endif
|
|
|
30ceb2 |
+#endif
|
|
|
30ceb2 |
return (nr_bytes);
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
/* }}} */
|
|
|
30ceb2 |
@@ -1511,7 +1511,7 @@ data_accept(databuf_t *data, ftpbuf_t *ftp TSRMLS_DC)
|
|
|
30ceb2 |
|
|
|
30ceb2 |
data_accepted:
|
|
|
30ceb2 |
#if HAVE_OPENSSL_EXT
|
|
|
30ceb2 |
-
|
|
|
30ceb2 |
+
|
|
|
30ceb2 |
/* now enable ssl if we need to */
|
|
|
30ceb2 |
if (ftp->use_ssl && ftp->use_ssl_for_data) {
|
|
|
30ceb2 |
ctx = SSL_CTX_new(SSLv23_client_method());
|
|
|
30ceb2 |
@@ -1531,23 +1531,23 @@ data_accepted:
|
|
|
30ceb2 |
SSL_CTX_free(ctx);
|
|
|
30ceb2 |
return 0;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
-
|
|
|
30ceb2 |
-
|
|
|
30ceb2 |
+
|
|
|
30ceb2 |
+
|
|
|
30ceb2 |
SSL_set_fd(data->ssl_handle, data->fd);
|
|
|
30ceb2 |
|
|
|
30ceb2 |
if (ftp->old_ssl) {
|
|
|
30ceb2 |
SSL_copy_session_id(data->ssl_handle, ftp->ssl_handle);
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
-
|
|
|
30ceb2 |
+
|
|
|
30ceb2 |
if (SSL_connect(data->ssl_handle) <= 0) {
|
|
|
30ceb2 |
php_error_docref(NULL TSRMLS_CC, E_WARNING, "data_accept: SSL/TLS handshake failed");
|
|
|
30ceb2 |
SSL_shutdown(data->ssl_handle);
|
|
|
30ceb2 |
SSL_free(data->ssl_handle);
|
|
|
30ceb2 |
return 0;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
-
|
|
|
30ceb2 |
+
|
|
|
30ceb2 |
data->ssl_active = 1;
|
|
|
30ceb2 |
- }
|
|
|
30ceb2 |
+ }
|
|
|
30ceb2 |
|
|
|
30ceb2 |
#endif
|
|
|
30ceb2 |
|
|
|
30ceb2 |
@@ -1562,14 +1562,14 @@ data_close(ftpbuf_t *ftp, databuf_t *data)
|
|
|
30ceb2 |
{
|
|
|
30ceb2 |
#if HAVE_OPENSSL_EXT
|
|
|
30ceb2 |
SSL_CTX *ctx;
|
|
|
30ceb2 |
-#endif
|
|
|
30ceb2 |
+#endif
|
|
|
30ceb2 |
if (data == NULL) {
|
|
|
30ceb2 |
return NULL;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
if (data->listener != -1) {
|
|
|
30ceb2 |
#if HAVE_OPENSSL_EXT
|
|
|
30ceb2 |
if (data->ssl_active) {
|
|
|
30ceb2 |
-
|
|
|
30ceb2 |
+
|
|
|
30ceb2 |
ctx = SSL_get_SSL_CTX(data->ssl_handle);
|
|
|
30ceb2 |
SSL_CTX_free(ctx);
|
|
|
30ceb2 |
|
|
|
30ceb2 |
@@ -1577,9 +1577,9 @@ data_close(ftpbuf_t *ftp, databuf_t *data)
|
|
|
30ceb2 |
SSL_free(data->ssl_handle);
|
|
|
30ceb2 |
data->ssl_active = 0;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
-#endif
|
|
|
30ceb2 |
+#endif
|
|
|
30ceb2 |
closesocket(data->listener);
|
|
|
30ceb2 |
- }
|
|
|
30ceb2 |
+ }
|
|
|
30ceb2 |
if (data->fd != -1) {
|
|
|
30ceb2 |
#if HAVE_OPENSSL_EXT
|
|
|
30ceb2 |
if (data->ssl_active) {
|
|
|
30ceb2 |
@@ -1590,9 +1590,9 @@ data_close(ftpbuf_t *ftp, databuf_t *data)
|
|
|
30ceb2 |
SSL_free(data->ssl_handle);
|
|
|
30ceb2 |
data->ssl_active = 0;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
-#endif
|
|
|
30ceb2 |
+#endif
|
|
|
30ceb2 |
closesocket(data->fd);
|
|
|
30ceb2 |
- }
|
|
|
30ceb2 |
+ }
|
|
|
30ceb2 |
if (ftp) {
|
|
|
30ceb2 |
ftp->data = NULL;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
@@ -1610,8 +1610,8 @@ ftp_genlist(ftpbuf_t *ftp, const char *cmd, const char *path TSRMLS_DC)
|
|
|
30ceb2 |
databuf_t *data = NULL;
|
|
|
30ceb2 |
char *ptr;
|
|
|
30ceb2 |
int ch, lastch;
|
|
|
30ceb2 |
- int size, rcvd;
|
|
|
30ceb2 |
- int lines;
|
|
|
30ceb2 |
+ size_t size, rcvd;
|
|
|
30ceb2 |
+ size_t lines;
|
|
|
30ceb2 |
char **ret = NULL;
|
|
|
30ceb2 |
char **entry;
|
|
|
30ceb2 |
char *text;
|
|
|
30ceb2 |
@@ -1629,7 +1629,7 @@ ftp_genlist(ftpbuf_t *ftp, const char *cmd, const char *path TSRMLS_DC)
|
|
|
30ceb2 |
if ((data = ftp_getdata(ftp TSRMLS_CC)) == NULL) {
|
|
|
30ceb2 |
goto bail;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
- ftp->data = data;
|
|
|
30ceb2 |
+ ftp->data = data;
|
|
|
30ceb2 |
|
|
|
30ceb2 |
if (!ftp_putcmd(ftp, cmd, path)) {
|
|
|
30ceb2 |
goto bail;
|
|
|
30ceb2 |
@@ -1653,7 +1653,7 @@ ftp_genlist(ftpbuf_t *ftp, const char *cmd, const char *path TSRMLS_DC)
|
|
|
30ceb2 |
lines = 0;
|
|
|
30ceb2 |
lastch = 0;
|
|
|
30ceb2 |
while ((rcvd = my_recv(ftp, data->fd, data->buf, FTP_BUFSIZE))) {
|
|
|
30ceb2 |
- if (rcvd == -1) {
|
|
|
30ceb2 |
+ if (rcvd == -1 || rcvd > ((size_t)(-1))-size) {
|
|
|
30ceb2 |
goto bail;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
|
|
|
30ceb2 |
@@ -1858,7 +1858,7 @@ ftp_nb_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type
|
|
|
30ceb2 |
if (!ftp_getresp(ftp) || (ftp->resp != 150 && ftp->resp != 125)) {
|
|
|
30ceb2 |
goto bail;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
- if ((data = data_accept(data, ftp TSRMLS_CC)) == NULL) {
|
|
|
30ceb2 |
+ if ((data = data_accept(data, ftp TSRMLS_CC)) == NULL) {
|
|
|
30ceb2 |
goto bail;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
ftp->data = data;
|
|
|
30ceb2 |
@@ -1914,7 +1914,7 @@ ftp_nb_continue_write(ftpbuf_t *ftp TSRMLS_DC)
|
|
|
30ceb2 |
goto bail;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
ftp->data = data_close(ftp, ftp->data);
|
|
|
30ceb2 |
-
|
|
|
30ceb2 |
+
|
|
|
30ceb2 |
if (!ftp_getresp(ftp) || (ftp->resp != 226 && ftp->resp != 250)) {
|
|
|
30ceb2 |
goto bail;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
--
|
|
|
30ceb2 |
2.1.4
|
|
|
30ceb2 |
|
|
|
30ceb2 |
From 0765623d6991b62ffcd93ddb6be8a5203a2fa7e2 Mon Sep 17 00:00:00 2001
|
|
|
30ceb2 |
From: Stanislav Malyshev <stas@php.net>
|
|
|
30ceb2 |
Date: Sun, 31 May 2015 17:23:06 -0700
|
|
|
30ceb2 |
Subject: [PATCH] improve fix for Bug #69545
|
|
|
30ceb2 |
|
|
|
30ceb2 |
---
|
|
|
30ceb2 |
NEWS | 4 ++++
|
|
|
30ceb2 |
ext/ftp/ftp.c | 2 --
|
|
|
30ceb2 |
2 files changed, 4 insertions(+), 2 deletions(-)
|
|
|
30ceb2 |
|
|
|
30ceb2 |
diff --git a/ext/ftp/ftp.c b/ext/ftp/ftp.c
|
|
|
30ceb2 |
index 53560eb..50d8def 100644
|
|
|
30ceb2 |
--- a/ext/ftp/ftp.c
|
|
|
30ceb2 |
+++ b/ext/ftp/ftp.c
|
|
|
30ceb2 |
@@ -1663,8 +1663,6 @@ ftp_genlist(ftpbuf_t *ftp, const char *cmd, const char *path TSRMLS_DC)
|
|
|
30ceb2 |
for (ptr = data->buf; rcvd; rcvd--, ptr++) {
|
|
|
30ceb2 |
if (*ptr == '\n' && lastch == '\r') {
|
|
|
30ceb2 |
lines++;
|
|
|
30ceb2 |
- } else {
|
|
|
30ceb2 |
- size++;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
lastch = *ptr;
|
|
|
30ceb2 |
}
|
|
|
30ceb2 |
--
|
|
|
30ceb2 |
2.1.4
|
|
|
30ceb2 |
|