summaryrefslogtreecommitdiff
path: root/www-servers/lighttpd/files/1.4.25-fix-CVE-2010-0295.patch
diff options
context:
space:
mode:
Diffstat (limited to 'www-servers/lighttpd/files/1.4.25-fix-CVE-2010-0295.patch')
-rw-r--r--www-servers/lighttpd/files/1.4.25-fix-CVE-2010-0295.patch211
1 files changed, 211 insertions, 0 deletions
diff --git a/www-servers/lighttpd/files/1.4.25-fix-CVE-2010-0295.patch b/www-servers/lighttpd/files/1.4.25-fix-CVE-2010-0295.patch
new file mode 100644
index 0000000..fcac318
--- /dev/null
+++ b/www-servers/lighttpd/files/1.4.25-fix-CVE-2010-0295.patch
@@ -0,0 +1,211 @@
+Index: branches/lighttpd-1.4.x/src/base.h
+===================================================================
+--- branches/lighttpd-1.4.x/src/base.h (revision 2709)
++++ branches/lighttpd-1.4.x/src/base.h (revision 2710)
+@@ -431,7 +431,6 @@
+
+ #ifdef USE_OPENSSL
+ SSL *ssl;
+- buffer *ssl_error_want_reuse_buffer;
+ # ifndef OPENSSL_NO_TLSEXT
+ buffer *tlsext_server_name;
+ # endif
+Index: branches/lighttpd-1.4.x/src/connections.c
+===================================================================
+--- branches/lighttpd-1.4.x/src/connections.c (revision 2709)
++++ branches/lighttpd-1.4.x/src/connections.c (revision 2710)
+@@ -192,40 +192,42 @@
+
+ static int connection_handle_read_ssl(server *srv, connection *con) {
+ #ifdef USE_OPENSSL
+- int r, ssl_err, len, count = 0;
++ int r, ssl_err, len, count = 0, read_offset, toread;
+ buffer *b = NULL;
+
+ if (!con->conf.is_ssl) return -1;
+
+- /* don't resize the buffer if we were in SSL_ERROR_WANT_* */
+-
+ ERR_clear_error();
+ do {
+- if (!con->ssl_error_want_reuse_buffer) {
+- b = buffer_init();
+- buffer_prepare_copy(b, SSL_pending(con->ssl) + (16 * 1024)); /* the pending bytes + 16kb */
++ if (NULL != con->read_queue->last) {
++ b = con->read_queue->last->mem;
++ }
+
++ if (NULL == b || b->size - b->used < 1024) {
++ b = chunkqueue_get_append_buffer(con->read_queue);
++ len = SSL_pending(con->ssl);
++ if (len < 4*1024) len = 4*1024; /* always alloc >= 4k buffer */
++ buffer_prepare_copy(b, len + 1);
++
+ /* overwrite everything with 0 */
+ memset(b->ptr, 0, b->size);
+- } else {
+- b = con->ssl_error_want_reuse_buffer;
+ }
+
+- len = SSL_read(con->ssl, b->ptr, b->size - 1);
+- con->ssl_error_want_reuse_buffer = NULL; /* reuse it only once */
++ read_offset = (b->used > 0) ? b->used - 1 : 0;
++ toread = b->size - 1 - read_offset;
+
++ len = SSL_read(con->ssl, b->ptr + read_offset, toread);
++
+ if (len > 0) {
+- b->used = len;
++ if (b->used > 0) b->used--;
++ b->used += len;
+ b->ptr[b->used++] = '\0';
+
+- /* we move the buffer to the chunk-queue, no need to free it */
++ con->bytes_read += len;
+
+- chunkqueue_append_buffer_weak(con->read_queue, b);
+ count += len;
+- con->bytes_read += len;
+- b = NULL;
+ }
+- } while (len > 0 && count < MAX_READ_LIMIT);
++ } while (len == toread && count < MAX_READ_LIMIT);
+
+
+ if (len < 0) {
+@@ -234,11 +236,11 @@
+ case SSL_ERROR_WANT_READ:
+ case SSL_ERROR_WANT_WRITE:
+ con->is_readable = 0;
+- con->ssl_error_want_reuse_buffer = b;
+
+- b = NULL;
++ /* the manual says we have to call SSL_read with the same arguments next time.
++ * we ignore this restriction; no one has complained about it in 1.5 yet, so it probably works anyway.
++ */
+
+- /* we have to steal the buffer from the queue-queue */
+ return 0;
+ case SSL_ERROR_SYSCALL:
+ /**
+@@ -297,16 +299,11 @@
+
+ connection_set_state(srv, con, CON_STATE_ERROR);
+
+- buffer_free(b);
+-
+ return -1;
+ } else if (len == 0) {
+ con->is_readable = 0;
+ /* the other end close the connection -> KEEP-ALIVE */
+
+- /* pipelining */
+- buffer_free(b);
+-
+ return -2;
+ }
+
+@@ -321,26 +318,41 @@
+ static int connection_handle_read(server *srv, connection *con) {
+ int len;
+ buffer *b;
+- int toread;
++ int toread, read_offset;
+
+ if (con->conf.is_ssl) {
+ return connection_handle_read_ssl(srv, con);
+ }
+
++ b = (NULL != con->read_queue->last) ? con->read_queue->last->mem : NULL;
++
++ /* default size for chunks is 4kb; only use bigger chunks if FIONREAD tells
++ * us more than 4kb is available
++ * if FIONREAD doesn't signal a big chunk we fill the previous buffer
++ * if it has >= 1kb free
++ */
+ #if defined(__WIN32)
+- b = chunkqueue_get_append_buffer(con->read_queue);
+- buffer_prepare_copy(b, 4 * 1024);
+- len = recv(con->fd, b->ptr, b->size - 1, 0);
+-#else
+- if (ioctl(con->fd, FIONREAD, &toread) || toread == 0) {
++ if (NULL == b || b->size - b->used < 1024) {
+ b = chunkqueue_get_append_buffer(con->read_queue);
+ buffer_prepare_copy(b, 4 * 1024);
++ }
++
++ read_offset = (b->used == 0) ? 0 : b->used - 1;
++ len = recv(con->fd, b->ptr + read_offset, b->size - 1 - read_offset, 0);
++#else
++ if (ioctl(con->fd, FIONREAD, &toread) || toread == 0 || toread <= 4*1024) {
++ if (NULL == b || b->size - b->used < 1024) {
++ b = chunkqueue_get_append_buffer(con->read_queue);
++ buffer_prepare_copy(b, 4 * 1024);
++ }
+ } else {
+ if (toread > MAX_READ_LIMIT) toread = MAX_READ_LIMIT;
+ b = chunkqueue_get_append_buffer(con->read_queue);
+ buffer_prepare_copy(b, toread + 1);
+ }
+- len = read(con->fd, b->ptr, b->size - 1);
++
++ read_offset = (b->used == 0) ? 0 : b->used - 1;
++ len = read(con->fd, b->ptr + read_offset, b->size - 1 - read_offset);
+ #endif
+
+ if (len < 0) {
+@@ -374,7 +386,8 @@
+ con->is_readable = 0;
+ }
+
+- b->used = len;
++ if (b->used > 0) b->used--;
++ b->used += len;
+ b->ptr[b->used++] = '\0';
+
+ con->bytes_read += len;
+@@ -850,13 +863,6 @@
+ /* The cond_cache gets reset in response.c */
+ /* config_cond_cache_reset(srv, con); */
+
+-#ifdef USE_OPENSSL
+- if (con->ssl_error_want_reuse_buffer) {
+- buffer_free(con->ssl_error_want_reuse_buffer);
+- con->ssl_error_want_reuse_buffer = NULL;
+- }
+-#endif
+-
+ con->header_len = 0;
+ con->in_error_handler = 0;
+
+@@ -1128,8 +1134,15 @@
+ } else {
+ buffer *b;
+
+- b = chunkqueue_get_append_buffer(dst_cq);
+- buffer_copy_string_len(b, c->mem->ptr + c->offset, toRead);
++ if (dst_cq->last &&
++ dst_cq->last->type == MEM_CHUNK) {
++ b = dst_cq->last->mem;
++ } else {
++ b = chunkqueue_get_append_buffer(dst_cq);
++ /* prepare buffer size for remaining POST data; is < 64kb */
++ buffer_prepare_copy(b, con->request.content_length - dst_cq->bytes_in + 1);
++ }
++ buffer_append_string_len(b, c->mem->ptr + c->offset, toRead);
+ }
+
+ c->offset += toRead;
+Index: branches/lighttpd-1.4.x/src/chunk.c
+===================================================================
+--- branches/lighttpd-1.4.x/src/chunk.c (revision 2709)
++++ branches/lighttpd-1.4.x/src/chunk.c (revision 2710)
+@@ -197,8 +197,6 @@
+ int chunkqueue_append_buffer_weak(chunkqueue *cq, buffer *mem) {
+ chunk *c;
+
+- if (mem->used == 0) return 0;
+-
+ c = chunkqueue_get_unused_chunk(cq);
+ c->type = MEM_CHUNK;
+ c->offset = 0;