Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove multiple calls to free when successively calling jq_reset. #3134

Merged
merged 1 commit into from
Jun 5, 2024

Conversation

Sameesunkaria
Copy link
Contributor

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.

@wader
Copy link
Member

wader commented May 31, 2024

Hey, thanks. Possible to add a minimal reuse/reset regression test case to https://github.com/jqlang/jq/blob/master/src/jq_test.c that would be detected by valgrind?

@Sameesunkaria
Copy link
Contributor Author

Added a separate function for testing the jq_state after calls to jq_start. In theory these tests could be baked into the existing run_jq_tests but currently it only ever calls jq_start once for each program. To correctly validate the changes, we must run it against a "dirty" jq_state that was reset by jq_start.

Please let me know if you had something else in mind. :)

Copy link
Member

@wader wader left a comment

Choose a reason for hiding this comment

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

Thanks! looks good to me. Let's merge once one more maintainer is happy

@itchyny
Copy link
Contributor

itchyny commented Jun 3, 2024

Please drop the change to gitignore file. Files generated not by the project should not be in per-project gitignore file.

`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.
@Sameesunkaria
Copy link
Contributor Author

Removed the commit with the changes to gitignore

Copy link
Contributor

@itchyny itchyny left a comment

Choose a reason for hiding this comment

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

LGTM

@itchyny itchyny merged commit 7be6870 into jqlang:master Jun 5, 2024
28 checks passed
Sameesunkaria referenced this pull request in Sameesunkaria/SwiftJQ Aug 11, 2024
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