From 24e6fae12582256e39a8e753efd7c9f3344d91fc Mon Sep 17 00:00:00 2001 From: Davidson Francis Date: Thu, 14 Dec 2023 00:00:06 -0300 Subject: [PATCH] Bug Fix: Race condition between ws_accept() and function return In PR #82, the signature of the ws_socket() function was modified to receive a 'ws_server' structure as a parameter. However, the content of this structure was only copied later when the thread for performing accepts() was created. This could lead to a situation where, if the 'ws_server' structure was allocated on the stack, a potential function return (prior to thread execution) would render the address invalid, effectively creating a race condition between thread creation and function return. The fix is straightforward: simply have the 'ws_accept_params' structure store the 'ws_server' structure itself instead of a pointer to it. This should address issue #86. --- src/ws.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/ws.c b/src/ws.c index 30909e8..705feb0 100644 --- a/src/ws.c +++ b/src/ws.c @@ -1627,7 +1627,7 @@ static void *ws_establishconnection(void *vclient) struct ws_accept_params { int sock; - struct ws_server *ws_srv; + struct ws_server ws_srv; }; /** @@ -1687,7 +1687,7 @@ static void *ws_accept(void *data) { if (client_socks[i].client_sock == -1) { - memcpy(&client_socks[i].ws_srv, ws_prm->ws_srv, + memcpy(&client_socks[i].ws_srv, &ws_prm->ws_srv, sizeof(struct ws_server)); client_socks[i].client_sock = new_sock; @@ -1810,11 +1810,13 @@ int ws_socket(struct ws_server *ws_srv) /* Ignore 'unused functions' warnings. */ ((void)skip_frame); - /* Allocates our parameters data. */ + /* Allocates our parameters data and copy the ws_server structure. */ ws_prm = malloc(sizeof(*ws_prm)); if (!ws_prm) panic("Unable to allocate ws parameters, out of memory!\n"); + memcpy(&ws_prm->ws_srv, ws_srv, sizeof(*ws_srv)); + #ifdef _WIN32 WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) @@ -1844,8 +1846,7 @@ int ws_socket(struct ws_server *ws_srv) memset(client_socks, -1, sizeof(client_socks)); /* Accept connections. */ - ws_prm->sock = sock; - ws_prm->ws_srv = ws_srv; + ws_prm->sock = sock; if (!ws_srv->thread_loop) ws_accept(ws_prm);