Skip to content

Conversation

@Rot127
Copy link
Member

@Rot127 Rot127 commented Jan 6, 2026

Your checklist for this pull request

  • I've read the guidelines for contributing to this repository.
  • I made sure to follow the project's coding style.
  • I've documented every RZ_API function and struct this PR changes.
  • I've added tests that prove my changes are effective (required for changes to RZ_API).
  • I've updated the Rizin book with the relevant information (if needed).
  • I've used AI tools to generate fully or partially these code changes and I'm sure the changes are not copyrighted by somebody else.

Detailed description

The previous assumption of RzILMem was that the buffer is not owned by it. This made sense, because in the beginning it only held an RzIO buffer.

But the Xtensa and Sparc RzAnalysisILInitCallback definition initializes an additional RzILMem object. This additional RzILMem has a sparse buffer in both cases. The Xtensa and Sparc plugin pass the sparse buffer to RzILMem with the assumption that it is owned. They have to, because there is no fini() version of RzAnalysisILInitCallback in which they could free the buffer. There are also no API functions to free the buffer in RzILMem. So the plugins don't have a nice way to clean it up in a theoretical fini() callback.

This commit fixes the leak by adding a flag to rz_il_mem_new() to mark the ownership of the given buffer.
This seems the most natural solution, because buffers can abstract from all kind of backends (RzIO, a file, some memory etc.). Each time the ownership of the buffer is different. So the creator of rz_il_mem_new() can decide what buffer with what ownership they pass.

Test plan

All green no crashes.

Closing issues

...

Copy link
Contributor

@notxvilka notxvilka left a comment

Choose a reason for hiding this comment

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

LGTM with one unclear thing

…rship.

The previous assumption of RzILMem was that the buffer is not owned by it.
This made sense, because in the beginning it only held an RzIO buffer.

But the Xtensa and Sparc RzAnalysisILInitCallback definition initializes
an additional RzILMem object. This additional RzILMem has a sparse buffer in both cases.
The Xtensa and Sparc plugin pass the sparse buffer to RzILMem with the assumption that it takes ownership.
They have to, because there is no fini() version of RzAnalysisILInitCallback in which they could free the buffer.
There are also no API functions to free the buffer in RzILMem.
So the plugins don't have a nice way to clean it up in a theoretical fini() callback.

This commit fixes the leak by splitting rz_il_mem_new() into two version.
One to taking the ownership of the buffer, one borrowing it.
This seems the most natural solution, because buffers can abstract from
all kind of backends (RzIO, a file, some memory etc.).
Each time the ownership of the buffer is different.
So the creator of rz_il_mem_new_*() can decide what buffer with what ownership they pass.
Copy link
Contributor

@notxvilka notxvilka left a comment

Choose a reason for hiding this comment

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

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants