From 3e9c034c93fa6f59584ec179d3df1333f250c694 Mon Sep 17 00:00:00 2001 From: Nikias Bassen Date: Thu, 5 Nov 2026 09:35:33 +0100 Subject: plist: fix use-after-free in plist_copy_node() on stack realloc plist_copy_node() kept a pointer `f` to the top frame of its traversal stack and dereferenced it after the stack was grown with realloc(), which may move the buffer. Plists nested deeper than 64 levels hit this path, causing a heap-use-after-free when reading f->depth. Read the child depth before the realloc and use it when building the new frame. Thanks to @sdnuhfiu for reporting! Fixes #328 --- src/plist.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plist.c b/src/plist.c index bcd212c..66fe1ab 100644 --- a/src/plist.c +++ b/src/plist.c @@ -921,6 +921,8 @@ static plist_t plist_copy_node(node_t root) f->node_index++; // push child frame to process its children + // (read depth before realloc, which may invalidate f) + int child_depth = f->depth + 1; if (sp == cap) { cap += 64; copy_frame_t *tmp = (copy_frame_t*)realloc(st, cap * sizeof(*st)); @@ -940,7 +942,7 @@ static plist_t plist_copy_node(node_t root) nf.type = newch_type; nf.next_child = node_first_child(ch); nf.node_index = 0; - nf.depth = f->depth + 1; + nf.depth = child_depth; st[sp++] = nf; } -- cgit v1.1-32-gdbae