Skip to content

Fix NULL pointer deref and memory leak in CSEXP parser#366

Merged
vstakhov merged 1 commit intovstakhov:masterfrom
MarkLee131:fix/csexp-null-deref-and-memleak
Mar 24, 2026
Merged

Fix NULL pointer deref and memory leak in CSEXP parser#366
vstakhov merged 1 commit intovstakhov:masterfrom
MarkLee131:fix/csexp-null-deref-and-memleak

Conversation

@MarkLee131
Copy link
Copy Markdown
Contributor

Fix #365, including two coupled bugs in ucl_parse_csexp:

  1. NULL pointer dereference in read_value (line 181): after closing the outermost list with ')', parser->stack becomes NULL. If trailing data follows (e.g. input "()3:abc"), the parser reaches read_value and dereferences parser->stack->obj without a NULL check. Minimal trigger: ()3:abc — found via libFuzzer + ASan.

  2. Memory leak on error paths: ucl_parser_free frees stack frame structs but not the ucl_object_t they hold. In the CSEXP parser, stack objects are only appended to their parent on ')'. If parsing fails with unclosed lists, inner stack objects are never appended to the tree and are permanently leaked. Minimal trigger: (( — confirmed via macOS leaks tool: 18 leaks / 1152 bytes before fix, 0 after.

These are coupled because fix_1 sends execution to the parse_err state, and fix_2 is the cleanup logic that runs there.

Two coupled bugs in ucl_parse_csexp:

1. NULL pointer dereference in read_value (line 181): after closing the
   outermost list with ')', parser->stack becomes NULL.  If trailing data
   follows (e.g. input "()3:abc"), the parser reaches read_value and
   dereferences parser->stack->obj without a NULL check.
   Minimal trigger: ()3:abc — found via libFuzzer + ASan.

2. Memory leak on error paths: ucl_parser_free frees stack frame structs
   but not the ucl_object_t they hold.  In the CSEXP parser, stack objects
   are only appended to their parent on ')'.  If parsing fails with
   unclosed lists, inner stack objects are never appended to the tree and
   are permanently leaked.
   Minimal trigger: (( — confirmed via macOS leaks tool:
   18 leaks / 1152 bytes before fix, 0 after.

These are coupled because fix vstakhov#1 sends execution to the parse_err state,
and fix vstakhov#2 is the cleanup logic that runs there.

Fix vstakhov#1: add NULL check for parser->stack before ucl_array_append.
Fix vstakhov#2: in parse_err and the "invalid finishing state" error path,
iterate remaining stack frames and ucl_object_unref any object that
is not parser->top_obj (orphaned objects not reachable from the tree).
@vstakhov vstakhov merged commit 0ff125f into vstakhov:master Mar 24, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

NULL pointer dereference and memory leak in CSEXP parser

2 participants