Skip to content
Snippets Groups Projects
Commit 31c01008 authored by Rob Swindell's avatar Rob Swindell :speech_balloon:
Browse files

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!
parent d83ae02b
Branches
Tags
No related merge requests found
Pipeline #7962 passed
......@@ -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;
......
......@@ -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 */);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment