Skip to content

Conversation

@lynxis
Copy link
Member

@lynxis lynxis commented Feb 10, 2026

Fix allocation and minor memleaks in json path

jp_get_token() is using a stack allocated jp_opcode op and
is not using jp_alloc_op() or jp_free().

jp_get_token() is calling match_token() which might assign op->str
and allocate it via strdup().

Fixes: TOB-OWRT-3
Reported-by: Trail of Bits
Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
jp_alloc_op() is not only allocating the memory of the jp_opcode itself,
but might allocate also op->str as a whole block by a single calloc() call.

However match_token() might also assign op->str using strdup().
This might result in further memory problems, as the different memory allocation
strategy happens on the same member.

Remove this optimisation of allocating the jp_opcode and op->str from the same block,
to ensure it is used everywhere in the way same.

Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
@lynxis lynxis self-assigned this Feb 10, 2026
@jow-
Copy link
Contributor

jow- commented Feb 10, 2026

Why is the simplification needed? The idea of the calloc_a() call was to store the string copy and the bookkeeping data in the same heap block, to avoid extra allocations which might lead to additional memory fragmentation. Probably not world moving either way but why drop the optimization if it already is present and working?

@lynxis
Copy link
Member Author

lynxis commented Feb 10, 2026

@jow- yes the current code is working and I see the point in the optimisation of the a single calloc block.
I see an issue with the different memory allocation usages of op->str in lexer.c and ast.c.

lexer.c is assigning op->str via strdup(), however the code is using a static allocated jp_opcode.
ast.c is allocating op->str on alloc as you descrbied.

So depending where the object comes, the op->str requires to be freed or not.
As long the code stays in its current state, there is not a problem. But this could be easily overlooked later. It reminds me a little bit to the old openssl apis where the user must be very careful how to use api.

It would be also fine for me to drop the commit removing this optimization.

Comment on lines +523 to +526
newop = jp_alloc_op(s, op.type, op.num, op.str, NULL);
/* match_token might alloced str using strdup() */
if (op.str)
free(op.str);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't you just

Suggested change
newop = jp_alloc_op(s, op.type, op.num, op.str, NULL);
/* match_token might alloced str using strdup() */
if (op.str)
free(op.str);
newop = jp_alloc_op(s, op.type, op.num, NULL, NULL);
newop->str = op.str;

and avoid the strdup() in jp_alloc_op()?

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.

3 participants