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