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

Fix buffer overflow in DWI bootstrapping #2779

Merged
merged 3 commits into from
Apr 18, 2024
Merged

Conversation

Lestropie
Copy link
Member

Two components to change:

  • Removal of current_chunk should have no effect. It looks to me like vestigial code from trying different approaches to keep track of buffer chunks, but the use of next_voxel & last_voxel satisfies the requirement.

  • While get_voxel() looks like it's doing exactly the same thing, though perhaps less elegantly, it nevertheless resolves a buffer overflow. Though it looks to me like an invalid or overwritten address rather than a conventional "off-by-one"-type overflow.
    On dev, within an individual thread, the value_type* yielded by the map for a previously sampled voxel is occasionally different to that used when buffer data were allocated for that voxel. Maybe one in every 1000 times that a pointer for a previously sampled voxel is requested.
    I can't report exactly what is wrong with the dev code. If it were possible for the std::map implementation to perform an internal tree rebalancing after it has done its search as part of insert(), but the yielded pointer address pointer were that from before rather than after the rebalancing, that would seem to me like a pretty large STL implementation bug.

Fix applies to tckgen -algorithm tensor_prob.
@Lestropie Lestropie added the bug label Jan 16, 2024
@Lestropie Lestropie added this to the 3.1.0 updates milestone Jan 16, 2024
@Lestropie Lestropie self-assigned this Jan 16, 2024
github-actions[bot]

This comment was marked as outdated.

@Lestropie
Copy link
Member Author

Lestropie commented Jan 17, 2024

@MRtrix3/mrtrix3-devs:

clang-tidy:

  1. is complaining about if statements without braces, which I think we're permitting in clang-format? Do we want to disable that check?

  2. doesn't like single-character variable names, but we use these quite extensively. Do we want to disable this check, or agree to not do this with any new code going forward?

@daljit46
Copy link
Member

daljit46 commented Jan 18, 2024

As mentioned in #2745, we should discuss which clang-tidy checks we should enable as some of them may be either undesirable or superfluous in the context of our codebase. However, it's strange that it's complaining about [readability-identifier-length] and [readability-braces-around-statements] since they should be disabled according to our current settings.

Copy link

clang-tidy review says "All clean, LGTM! 👍"

@Lestropie
Copy link
Member Author

After fixing merge conflicts to get this to dev following #2764, this proposed fix is no longer passing tests with address sanitiser; so not yet ready to merge.

- Different syntax for adding elements to std::map<> Bootstrap::voxels seems to prevent meory leaks; it seems that using std::make_pair<> to add elements is somehow inappropriate.
- Re-introduce tracking of chunk index that was erroneously removed in 7fa0142, but with an additional fix:
  - If previous chunks have previously been allocated, those memory allocations are preserved. Therefore, for a new streamline, once a chunk has been fully utilised, the next pre-allocated chunk should then be used. This was misunderstood in the generation of 7fa0142.
  - Includes a fix for this intended behaviour. Previously, once transitioning to a new chunk, value_type *next_voxel would erroneously point to the start of the final chunk, rather than the start of the next chunk. This is rectified by this commit.
-  Additionally, allocate the first chunk of memory in the constructor. While this does not resolve any specific memory issue, it IMO more clearly conveys where and why memory chunks are allocated.
Copy link

clang-tidy review says "All clean, LGTM! 👍"

@Lestropie Lestropie requested a review from jdtournier January 23, 2024 01:51
voxel_buffer.push_back(std::vector<value_type>(NUM_VOX_PER_CHUNK * size(3)));
assert(current_chunk < voxel_buffer.size());
next_voxel = &voxel_buffer.back()[0];
next_voxel = &voxel_buffer[current_chunk][0];
Copy link
Member Author

Choose a reason for hiding this comment

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

@jdtournier Note bug here resolved in b2fa527.

@Lestropie
Copy link
Member Author

OK, this now passes tests with address sanitiser.
Turns out there was a bug in the implementation that resulted in my being deceived regarding its operation. It looks good to me now, but I'd prefer to have an explicit review from @jdtournier before merging.
Also: IMO this class belongs in src/dwi/tractography/ rather than src/dwi/. It specifically deals with the case of storing results of bootstrapping only for some subset of voxels, for which I don't foresee any application other than tractography.

@jdtournier jdtournier merged commit 6bf4cec into dev Apr 18, 2024
6 checks passed
@jdtournier jdtournier deleted the tckgen_tensorprob_fix branch April 18, 2024 15:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants