Browse Source

detect endless loops and kill them

git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.3.x@470 152afb58-edef-0310-8abb-c4023f1b3aa9
svn/heads/lighttpd-1.3.x
Jan Kneschke 17 years ago
parent
commit
7126a0f2bc
  1. 5
      src/base.h
  2. 4
      src/connections.c
  3. 12
      src/mod_fastcgi.c
  4. 8
      src/response.c

5
src/base.h

@ -293,6 +293,11 @@ typedef struct {
struct timeval start_tv;
size_t request_count; /* number of requests handled in this connection */
size_t loops_per_request; /* to catch endless loops in a single request
*
* used by mod_rewrite, mod_fastcgi, ... and others
* this is self-protection
*/
int fd; /* the FD for this connection */
int fde_ndx; /* index for the fdevent-handler */

4
src/connections.c

@ -561,7 +561,7 @@ connection *connection_init(server *srv) {
con->bytes_written = 0;
con->bytes_read = 0;
con->bytes_header = 0;
con->loops_per_request = 0;
#define CLEAN(x) \
con->x = buffer_init();
@ -675,6 +675,7 @@ int connection_reset(server *srv, connection *con) {
con->bytes_written_cur_second = 0;
con->bytes_read = 0;
con->bytes_header = 0;
con->loops_per_request = 0;
con->request.http_method = HTTP_METHOD_UNSET;
con->request.http_version = HTTP_VERSION_UNSET;
@ -1184,6 +1185,7 @@ int connection_state_machine(server *srv, connection *con) {
con->read_idle_ts = srv->cur_ts;
con->request_count++;
con->loops_per_request = 0;
connection_set_state(srv, con, CON_STATE_READ);

12
src/mod_fastcgi.c

@ -2657,11 +2657,21 @@ SUBREQUEST_FUNC(mod_fastcgi_handle_subrequest) {
buffer_reset(con->physical.path);
con->mode = DIRECT;
joblist_append(srv, con);
/* mis-using HANDLER_WAIT_FOR_FD to break out of the loop
* and hope that the childs will be restarted
*
*/
/* we might get into a LOOP here
*
* but how to handle this ?
*
* if we enter a endless loop, we will burn the CPU
*
* let this handle by the loop-detection
*/
return HANDLER_WAIT_FOR_FD;
} else {
fcgi_connection_cleanup(srv, hctx);

8
src/response.c

@ -946,6 +946,14 @@ int http_response_handle_cachable(server *srv, connection *con, time_t mtime) {
handler_t http_response_prepare(server *srv, connection *con) {
handler_t r;
if (con->loops_per_request++ > 1000) {
/* protect us again endless loops in a single request */
log_error_write(srv, __FILE__, __LINE__, "s", "ENDLESS LOOP DETECTED ... aborting request");
return HANDLER_ERROR;
}
/* looks like someone has already done a decision */
if (con->mode == DIRECT &&
(con->http_status != 0 && con->http_status != 200)) {

Loading…
Cancel
Save