Skip to content

Commit

Permalink
fix(esp_http_server): prevent concurrent access to socket used in asy…
Browse files Browse the repository at this point in the history
…nc http requests
  • Loading branch information
fgrfl authored and david-cermak committed Nov 6, 2024
1 parent 9f4b1bd commit 8b559ce
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 4 deletions.
7 changes: 6 additions & 1 deletion components/esp_http_server/src/httpd_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ static esp_err_t httpd_accept_conn(struct httpd_data *hd, int listen_fd)
if (!httpd_is_sess_available(hd)) {
/* Queue asynchronous closure of the least recently used session */
return httpd_sess_close_lru(hd);
/* Returning from this allowes the main server thread to process
/* Returning from this allows the main server thread to process
* the queued asynchronous control message for closing LRU session.
* Since connection request hasn't been addressed yet using accept()
* therefore httpd_accept_conn() will be called again, but this time
Expand Down Expand Up @@ -254,6 +254,11 @@ static int httpd_process_session(struct sock_db *session, void *context)
return 1;
}

// session is busy in an async task, do not process here.
if (session->for_async_req) {
return 1;
}

process_session_context_t *ctx = (process_session_context_t *)context;
int fd = session->fd;

Expand Down
3 changes: 2 additions & 1 deletion components/esp_http_server/src/httpd_sess.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ static int enum_function(struct sock_db *session, void *context)
case HTTPD_TASK_INIT:
session->fd = -1;
session->ctx = NULL;
session->for_async_req = false;
break;
// Get active session
case HTTPD_TASK_GET_ACTIVE:
Expand All @@ -87,7 +88,7 @@ static int enum_function(struct sock_db *session, void *context)
break;
// Set descriptor
case HTTPD_TASK_SET_DESCRIPTOR:
if (session->fd != -1) {
if (session->fd != -1 && !session->for_async_req) {
FD_SET(session->fd, ctx->fdset);
if (session->fd > ctx->max_fd) {
ctx->max_fd = session->fd;
Expand Down
6 changes: 4 additions & 2 deletions components/esp_http_server/src/httpd_txrx.c
Original file line number Diff line number Diff line change
Expand Up @@ -627,9 +627,11 @@ esp_err_t httpd_req_async_handler_begin(httpd_req_t *r, httpd_req_t **out)
}
memcpy(async_aux->resp_hdrs, r_aux->resp_hdrs, hd->config.max_resp_headers * sizeof(struct resp_hdr));

// Prevent the main thread from reading the rest of the request after the handler returns.
r_aux->remaining_len = 0;

// mark socket as "in use"
struct httpd_req_aux *ra = r->aux;
ra->sd->for_async_req = true;
r_aux->sd->for_async_req = true;

*out = async;

Expand Down

0 comments on commit 8b559ce

Please sign in to comment.