From 31c010080e7c0d643f8b19757202f8a50b1b3862 Mon Sep 17 00:00:00 2001 From: "Rob Swindell (on Debian Linux)" <rob@synchro.net> Date: Wed, 22 Jan 2025 13:57:24 -0800 Subject: [PATCH] Add/use new function: listAddNodeWithFlags() Fixes race condition/possible crash in listAddNodeData(), listAddNodeString() and listAddNodeList(). These functions were modifying the node->flags *after* a node was added to the list and list lock released. This is most likely the cause of the issue caught by valgrind when running the jsexec-testsuite: https://gitlab.synchro.net/main/sbbs/-/jobs/498286 Thank you Deuce and valgrind, nice catch! --- src/xpdev/link_list.c | 17 ++++++++++------- src/xpdev/link_list.h | 3 +++ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/xpdev/link_list.c b/src/xpdev/link_list.c index ab4ecf0dd7..9c44919932 100644 --- a/src/xpdev/link_list.c +++ b/src/xpdev/link_list.c @@ -569,7 +569,7 @@ static list_node_t* list_add_node(link_list_t* list, list_node_t* node, list_nod return node; } -list_node_t* listAddNode(link_list_t* list, void* data, list_node_tag_t tag, list_node_t* after) +list_node_t* listAddNodeWithFlags(link_list_t* list, void* data, list_node_tag_t tag, long flags, list_node_t* after) { list_node_t* node; @@ -582,10 +582,16 @@ list_node_t* listAddNode(link_list_t* list, void* data, list_node_tag_t tag, lis memset(node, 0, sizeof(list_node_t)); node->data = data; node->tag = tag; + node->flags = flags; return list_add_node(list, node, after); } +list_node_t* listAddNode(link_list_t* list, void* data, list_node_tag_t tag, list_node_t* after) +{ + return listAddNodeWithFlags(list, data, tag, 0, after); +} + long listAddNodes(link_list_t* list, void** data, list_node_tag_t* tag, list_node_t* after) { long i; @@ -610,11 +616,10 @@ list_node_t* listAddNodeData(link_list_t* list, const void* data, size_t length, return NULL; memcpy(buf, data, length); - if ((node = listAddNode(list, buf, tag, after)) == NULL) { + if ((node = listAddNodeWithFlags(list, buf, tag, LINK_LIST_MALLOC, after)) == NULL) { free(buf); return NULL; } - node->flags |= LINK_LIST_MALLOC; return node; } @@ -630,11 +635,10 @@ list_node_t* listAddNodeString(link_list_t* list, const char* str, list_node_tag if ((buf = strdup(str)) == NULL) return NULL; - if ((node = listAddNode(list, buf, tag, after)) == NULL) { + if ((node = listAddNodeWithFlags(list, buf, tag, LINK_LIST_MALLOC, after)) == NULL) { free(buf); return NULL; } - node->flags |= LINK_LIST_MALLOC; return node; } @@ -668,9 +672,8 @@ long listAddNodeList(link_list_t* list, const link_list_t* src, list_node_t* aft return -1; for (src_node = src->first; src_node != NULL; src_node = src_node->next, count++) { - if ((node = listAddNode(list, src_node->data, src_node->tag, node == NULL ? after:node)) == NULL) + if ((node = listAddNodeWithFlags(list, src_node->data, src_node->tag, src_node->flags, node == NULL ? after:node)) == NULL) return count; - node->flags = src_node->flags; } return count; diff --git a/src/xpdev/link_list.h b/src/xpdev/link_list.h index 61d2f3c304..3a12ffc0f5 100644 --- a/src/xpdev/link_list.h +++ b/src/xpdev/link_list.h @@ -148,6 +148,9 @@ DLLEXPORT bool listNodeIsLocked(const list_node_t*); /* Add node to list, returns pointer to new node or NULL on error */ DLLEXPORT list_node_t* listAddNode(link_list_t*, void* data, list_node_tag_t, list_node_t * after /* NULL=insert */); +/* Add node to list with flags, returns pointer to new node or NULL on error */ +DLLEXPORT list_node_t* listAddNodeWithFlags(link_list_t*, void* data, list_node_tag_t, long flags, list_node_t * after /* NULL=insert */); + /* Add array of node data to list, returns number of nodes added (or negative on error) */ /* tag array may be NULL */ DLLEXPORT long listAddNodes(link_list_t*, void** data, list_node_tag_t*, list_node_t* after /* NULL=insert */); -- GitLab