From 06d47abf41187eb7eb31f821a1a83cc98aa464b8 Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Sat, 12 Aug 2017 09:37:17 +0000 Subject: [PATCH] Add the pointer to the receive buffer to the csp It allows to free it outside of handle_established_connection() and will allow to use it in other functions in the future. --- jcc.c | 66 ++++++++++++++++++++----------------------------------- project.h | 8 ++++++- 2 files changed, 31 insertions(+), 43 deletions(-) diff --git a/jcc.c b/jcc.c index 3bbacd15..fdcd69b8 100644 --- a/jcc.c +++ b/jcc.c @@ -1,4 +1,4 @@ -const char jcc_rcs[] = "$Id: jcc.c,v 1.468 2017/08/12 09:33:25 fabiankeil Exp $"; +const char jcc_rcs[] = "$Id: jcc.c,v 1.469 2017/08/12 09:36:42 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/jcc.c,v $ @@ -1966,7 +1966,6 @@ static int send_http_request(struct client_state *csp) *********************************************************************/ static void handle_established_connection(struct client_state *csp) { - char *receive_buffer; char *hdr; char *p; int n; @@ -1989,10 +1988,10 @@ static void handle_established_connection(struct client_state *csp) #ifdef FEATURE_CONNECTION_KEEP_ALIVE int watch_client_socket; #endif - const size_t receive_buffer_size = csp->config->receive_buffer_size; - receive_buffer = zalloc(receive_buffer_size + 1); - if (receive_buffer == NULL) + csp->receive_buffer_size = csp->config->receive_buffer_size; + csp->receive_buffer = zalloc(csp->receive_buffer_size + 1); + if (csp->receive_buffer == NULL) { log_error(LOG_LEVEL_ERROR, "Out of memory. Failed to allocate the receive buffer."); @@ -2123,7 +2122,6 @@ static void handle_established_connection(struct client_state *csp) send_crunch_response(csp, error_response(csp, "connection-timeout")); } mark_server_socket_tainted(csp); - freez(receive_buffer); return; } else if (n < 0) @@ -2134,7 +2132,6 @@ static void handle_established_connection(struct client_state *csp) log_error(LOG_LEVEL_ERROR, "select() failed!: %E"); #endif mark_server_socket_tainted(csp); - freez(receive_buffer); return; } @@ -2161,7 +2158,7 @@ static void handle_established_connection(struct client_state *csp) if (FD_ISSET(csp->cfd, &rfds)) #endif /* def HAVE_POLL*/ { - int max_bytes_to_read = (int)receive_buffer_size; + int max_bytes_to_read = (int)csp->receive_buffer_size; #ifdef FEATURE_CONNECTION_KEEP_ALIVE if ((csp->flags & CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ)) @@ -2195,7 +2192,7 @@ static void handle_established_connection(struct client_state *csp) } if (csp->expected_client_content_length != 0) { - if (csp->expected_client_content_length < receive_buffer_size) + if (csp->expected_client_content_length < csp->receive_buffer_size) { max_bytes_to_read = (int)csp->expected_client_content_length; } @@ -2203,10 +2200,10 @@ static void handle_established_connection(struct client_state *csp) "Waiting for up to %d bytes from the client.", max_bytes_to_read); } - assert(max_bytes_to_read <= receive_buffer_size); + assert(max_bytes_to_read <= csp->receive_buffer_size); #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */ - len = read_socket(csp->cfd, receive_buffer, max_bytes_to_read); + len = read_socket(csp->cfd, csp->receive_buffer, max_bytes_to_read); if (len <= 0) { @@ -2233,11 +2230,10 @@ static void handle_established_connection(struct client_state *csp) } #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */ - if (write_socket(csp->server_connection.sfd, receive_buffer, (size_t)len)) + if (write_socket(csp->server_connection.sfd, csp->receive_buffer, (size_t)len)) { log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", http->host); mark_server_socket_tainted(csp); - freez(receive_buffer); return; } continue; @@ -2271,13 +2267,12 @@ static void handle_established_connection(struct client_state *csp) log_error(LOG_LEVEL_CONNECT, "The server still wants to talk, but the client hung up on us."); mark_server_socket_tainted(csp); - freez(receive_buffer); return; #endif /* def _WIN32 */ } #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */ - len = read_socket(csp->server_connection.sfd, receive_buffer, (int)receive_buffer_size); + len = read_socket(csp->server_connection.sfd, csp->receive_buffer, (int)csp->receive_buffer_size); if (len < 0) { @@ -2292,7 +2287,6 @@ static void handle_established_connection(struct client_state *csp) */ log_error(LOG_LEVEL_ERROR, "CONNECT already confirmed. Unable to tell the client about the problem."); - freez(receive_buffer); return; } else if (byte_count) @@ -2307,7 +2301,6 @@ static void handle_established_connection(struct client_state *csp) log_error(LOG_LEVEL_ERROR, "Already forwarded the original headers. " "Unable to tell the client about the problem."); mark_server_socket_tainted(csp); - freez(receive_buffer); return; } /* @@ -2320,7 +2313,7 @@ static void handle_established_connection(struct client_state *csp) #ifdef FEATURE_CONNECTION_KEEP_ALIVE if (csp->flags & CSP_FLAG_CHUNKED) { - if ((len >= 5) && !memcmp(receive_buffer+len-5, "0\r\n\r\n", 5)) + if ((len >= 5) && !memcmp(csp->receive_buffer+len-5, "0\r\n\r\n", 5)) { /* XXX: this is a temporary hack */ log_error(LOG_LEVEL_CONNECT, @@ -2337,19 +2330,19 @@ static void handle_established_connection(struct client_state *csp) * This is guaranteed by allocating with zalloc_or_die() * and never (intentionally) writing to the last byte. * - * receive_buffer_size is the size of the part of the + * csp->receive_buffer_size is the size of the part of the * buffer we intentionally write to, but we actually - * allocated receive_buffer_size+1 bytes so the assertion + * allocated csp->receive_buffer_size+1 bytes so the assertion * stays within the allocated range. */ - assert(receive_buffer[receive_buffer_size] == '\0'); + assert(csp->receive_buffer[csp->receive_buffer_size] == '\0'); /* * Add a trailing zero to let be able to use string operations. * XXX: do we still need this with filter_popups gone? */ - assert(len <= receive_buffer_size); - receive_buffer[len] = '\0'; + assert(len <= csp->receive_buffer_size); + csp->receive_buffer[len] = '\0'; /* * Normally, this would indicate that we've read @@ -2428,7 +2421,6 @@ static void handle_established_connection(struct client_state *csp) freez(hdr); freez(p); mark_server_socket_tainted(csp); - freez(receive_buffer); return; } @@ -2443,8 +2435,8 @@ static void handle_established_connection(struct client_state *csp) * This is NOT the body, so * Let's pretend the server just sent us a blank line. */ - snprintf(receive_buffer, receive_buffer_size, "\r\n"); - len = (int)strlen(receive_buffer); + snprintf(csp->receive_buffer, csp->receive_buffer_size, "\r\n"); + len = (int)strlen(csp->receive_buffer); /* * Now, let the normal header parsing algorithm below do its @@ -2468,7 +2460,7 @@ static void handle_established_connection(struct client_state *csp) * has been reached, switch to non-filtering mode, i.e. make & write the * header, flush the iob and buf, and get out of the way. */ - if (add_to_iob(csp->iob, csp->config->buffer_limit, receive_buffer, len)) + if (add_to_iob(csp->iob, csp->config->buffer_limit, csp->receive_buffer, len)) { size_t hdrlen; long flushed; @@ -2487,20 +2479,18 @@ static void handle_established_connection(struct client_state *csp) rsp = cgi_error_memory(); send_crunch_response(csp, rsp); mark_server_socket_tainted(csp); - freez(receive_buffer); return; } hdrlen = strlen(hdr); if (write_socket(csp->cfd, hdr, hdrlen) || ((flushed = flush_socket(csp->cfd, csp->iob)) < 0) - || (write_socket(csp->cfd, receive_buffer, (size_t)len))) + || (write_socket(csp->cfd, csp->receive_buffer, (size_t)len))) { log_error(LOG_LEVEL_CONNECT, "Flush header and buffers to client failed: %E"); freez(hdr); mark_server_socket_tainted(csp); - freez(receive_buffer); return; } @@ -2517,11 +2507,10 @@ static void handle_established_connection(struct client_state *csp) } else { - if (write_socket(csp->cfd, receive_buffer, (size_t)len)) + if (write_socket(csp->cfd, csp->receive_buffer, (size_t)len)) { log_error(LOG_LEVEL_ERROR, "write to client failed: %E"); mark_server_socket_tainted(csp); - freez(receive_buffer); return; } } @@ -2535,13 +2524,12 @@ static void handle_established_connection(struct client_state *csp) * Buffer up the data we just read. If that fails, there's * little we can do but send our static out-of-memory page. */ - if (add_to_iob(csp->iob, csp->config->buffer_limit, receive_buffer, len)) + if (add_to_iob(csp->iob, csp->config->buffer_limit, csp->receive_buffer, len)) { log_error(LOG_LEVEL_ERROR, "Out of memory while looking for end of server headers."); rsp = cgi_error_memory(); send_crunch_response(csp, rsp); mark_server_socket_tainted(csp); - freez(receive_buffer); return; } @@ -2562,7 +2550,6 @@ static void handle_established_connection(struct client_state *csp) write_socket(csp->cfd, INVALID_SERVER_HEADERS_RESPONSE, strlen(INVALID_SERVER_HEADERS_RESPONSE)); mark_server_socket_tainted(csp); - freez(receive_buffer); return; } else @@ -2608,7 +2595,6 @@ static void handle_established_connection(struct client_state *csp) } free_http_request(http); mark_server_socket_tainted(csp); - freez(receive_buffer); return; } @@ -2649,7 +2635,6 @@ static void handle_established_connection(struct client_state *csp) strlen(INVALID_SERVER_HEADERS_RESPONSE)); free_http_request(http); mark_server_socket_tainted(csp); - freez(receive_buffer); return; } hdr = list_to_text(csp->headers); @@ -2684,7 +2669,6 @@ static void handle_established_connection(struct client_state *csp) */ freez(hdr); mark_server_socket_tainted(csp); - freez(receive_buffer); return; } /* Buffer and pcrs filter this if appropriate. */ @@ -2715,7 +2699,6 @@ static void handle_established_connection(struct client_state *csp) */ freez(hdr); mark_server_socket_tainted(csp); - freez(receive_buffer); return; } } @@ -2740,17 +2723,14 @@ static void handle_established_connection(struct client_state *csp) write_socket(csp->cfd, INVALID_SERVER_HEADERS_RESPONSE, strlen(INVALID_SERVER_HEADERS_RESPONSE)); mark_server_socket_tainted(csp); - freez(receive_buffer); return; } } continue; } mark_server_socket_tainted(csp); - freez(receive_buffer); return; /* huh? we should never get here */ } - freez(receive_buffer); if (csp->content_length == 0) { @@ -3032,6 +3012,7 @@ static void chat(struct client_state *csp) csp->server_connection.request_sent = time(NULL); handle_established_connection(csp); + freez(csp->receive_buffer); } @@ -3090,6 +3071,7 @@ extern int fuzz_server_response(struct client_state *csp, char *fuzz_input_file) cgi_init_error_messages(); handle_established_connection(csp); + freez(csp->receive_buffer); return 0; } diff --git a/project.h b/project.h index aa642d32..c8b7ea23 100644 --- a/project.h +++ b/project.h @@ -1,7 +1,7 @@ #ifndef PROJECT_H_INCLUDED #define PROJECT_H_INCLUDED /** Version string. */ -#define PROJECT_H_VERSION "$Id: project.h,v 1.222 2017/06/26 12:11:13 fabiankeil Exp $" +#define PROJECT_H_VERSION "$Id: project.h,v 1.223 2017/06/26 12:13:52 fabiankeil Exp $" /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/project.h,v $ @@ -953,6 +953,12 @@ struct client_state /** An I/O buffer used for buffering data read from the client */ struct iob client_iob[1]; + /** Buffer used to briefly store data read from the network + * before forwarding or processing it. + */ + char *receive_buffer; + size_t receive_buffer_size; + /** List of all headers for this request */ struct list headers[1]; -- 2.39.2