Skip to content

Commit

Permalink
Remove multiple calls to free when successively calling jq_reset.
Browse files Browse the repository at this point in the history
`jq_reset` calls `jv_free` on the `exit_code` and the `error_message` stored on the jq state.
However, it doesn't replace the actual instance of those members. This means that subsequent
calls to `jq_reset` will call `jv_free` again on those members, which in turn may call `free`
on the same pointer multiple times. Freeing the same pointer multiple times is undefined
behavior and can cause heap corruption, which is how I spotted this issue.

In practice, this issue only occurs when using a program that may `halt_error`, because that
is when the `exit_code` and `error_message` are set to values other than `jv_invalid`.
Subsequent attempts to call `jq_start` (which calls `jq_reset` internally) after hitting a
`halt_error` can cause you to run into this issue.

The changes simply reset the `exit_code` and the `error_message` to `jv_invalid` (the initial
value set in `jq_init`) after they are freed.
  • Loading branch information
Sameesunkaria committed May 30, 2024
1 parent 250475b commit 63b2d0f
Showing 1 changed file with 2 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/execute.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,9 @@ static void jq_reset(jq_state *jq) {

jq->halted = 0;
jv_free(jq->exit_code);
jq->exit_code = jv_invalid();
jv_free(jq->error_message);
jq->error_message = jv_invalid();
if (jv_get_kind(jq->path) != JV_KIND_INVALID)
jv_free(jq->path);
jq->path = jv_null();
Expand Down

0 comments on commit 63b2d0f

Please sign in to comment.