libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit 41d2fc1eba51dbb1c2c23d83d18e985f92cd6d53
parent 90acb6bbbd28beac0567e383a8572b21238a19a4
Author: Christian Grothoff <christian@grothoff.org>
Date:   Mon,  2 Sep 2013 21:00:31 +0000

fix epoll use after free

Diffstat:
MChangeLog | 3+++
Msrc/microhttpd/connection.c | 8++++----
Msrc/microhttpd/daemon.c | 7++++++-
3 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/ChangeLog b/ChangeLog @@ -1,3 +1,6 @@ +Mon Sep 2 22:59:45 CEST 2013 + Fix use-after-free in epoll()-mode on read error. -CG + Sun Sep 1 21:55:53 CEST 2013 Fixing build issues on FreeBSD. -CG diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c @@ -1824,7 +1824,7 @@ int MHD_connection_handle_read (struct MHD_Connection *connection) { update_last_activity (connection); - if (connection->state == MHD_CONNECTION_CLOSED) + if (MHD_CONNECTION_CLOSED == connection->state) return MHD_YES; /* make sure "read" has a reasonable number of bytes in buffer to use per system call (if possible) */ @@ -2169,13 +2169,13 @@ MHD_connection_handle_idle (struct MHD_Connection *connection) continue; case MHD_CONNECTION_HEADERS_RECEIVED: parse_connection_headers (connection); - if (connection->state == MHD_CONNECTION_CLOSED) + if (MHD_CONNECTION_CLOSED == connection->state) continue; connection->state = MHD_CONNECTION_HEADERS_PROCESSED; continue; case MHD_CONNECTION_HEADERS_PROCESSED: call_connection_handler (connection); /* first call */ - if (connection->state == MHD_CONNECTION_CLOSED) + if (MHD_CONNECTION_CLOSED == connection->state) continue; if (need_100_continue (connection)) { @@ -2208,7 +2208,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection) if (connection->read_buffer_offset != 0) { process_request_body (connection); /* loop call */ - if (connection->state == MHD_CONNECTION_CLOSED) + if (MHD_CONNECTION_CLOSED == connection->state) continue; } if ((connection->remaining_upload_size == 0) || diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c @@ -1591,7 +1591,12 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon) pos->addr_len); #if EPOLL_SUPPORT if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) - MHD_PANIC ("Internal error"); + { + EDLL_remove (daemon->eready_head, + daemon->eready_tail, + pos); + pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL; + } if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) && (-1 != daemon->epoll_fd) && (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) )