-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Added assertion to guard against memory corruption #7360
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
base: main
Are you sure you want to change the base?
Conversation
|
Thanks for submitting this pull request! The maintainers of this repository would appreciate if you could update the CHANGELOG.md based on your changes. |
…non-templated one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds bounds checking assertions to guard against memory corruption in tensor indexing operations. The changes introduce runtime validation to ensure that advanced indexing operations do not access memory outside of valid tensor bounds.
Key Changes:
- Added bounds checking in
Indexer::GetWorkloadDataPtr()to validate computed offsets before dereferencing pointers - Introduced
total_byte_size_tracking inTensorRefto properly handle both contiguous and non-contiguous tensor layouts - Added comprehensive test coverage for the new assertions on both CPU and CUDA devices
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| cpp/open3d/core/Indexer.h | Added total_byte_size_ field to TensorRef and bounds checking assertions in GetWorkloadDataPtr() methods |
| cpp/open3d/core/AdvancedIndexing.h | Added bounds checking assertion for index values in advanced indexing operations |
| cpp/tests/core/TensorCheck.cpp | Added death tests to verify assertion behavior for out-of-bounds indexing on CPU and CUDA devices |
| CHANGELOG.md | Documented the addition of assertion guards for invalid indexing operations |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // dimension block This way, we can compute the total buffer size in | ||
| // both cases (when tensor is contiguous and when it is not) If it | ||
| // is not contiguous, the actual "end" of the buffer may not be | ||
| // simply NumElements() * dtype_byte_size_ |
Copilot
AI
Jan 5, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing punctuation at the end of sentences in the comment. Lines 123-125 should end with periods for consistency.
| // dimension block This way, we can compute the total buffer size in | |
| // both cases (when tensor is contiguous and when it is not) If it | |
| // is not contiguous, the actual "end" of the buffer may not be | |
| // simply NumElements() * dtype_byte_size_ | |
| // dimension block. This way, we can compute the total buffer size in | |
| // both cases (when tensor is contiguous and when it is not). If it | |
| // is not contiguous, the actual "end" of the buffer may not be | |
| // simply NumElements() * dtype_byte_size_. |
| assert(index >= -indexed_shape_[i] && index < indexed_shape_[i] && "Index out of bounds."); | ||
| #else | ||
| OPEN3D_ASSERT(index >= -indexed_shape_[i] && | ||
| index < indexed_shape_[i] && "Index out of bounds."); |
Copilot
AI
Jan 5, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The assertion message 'Index out of bounds.' differs from the CPU version's message 'Index out of bounds.' (line 190) in that the CUDA version uses a period. For consistency, both messages should be identical since they represent the same error condition.
| assert(index >= -indexed_shape_[i] && index < indexed_shape_[i] && "Index out of bounds."); | |
| #else | |
| OPEN3D_ASSERT(index >= -indexed_shape_[i] && | |
| index < indexed_shape_[i] && "Index out of bounds."); | |
| assert(index >= -indexed_shape_[i] && index < indexed_shape_[i] && "Index out of bounds"); | |
| #else | |
| OPEN3D_ASSERT(index >= -indexed_shape_[i] && | |
| index < indexed_shape_[i] && "Index out of bounds"); |
| assert(offset >= 0 && offset < input_.total_byte_size_); | ||
| #else | ||
| OPEN3D_ASSERT(offset >= 0 && offset < input_.total_byte_size_ && | ||
| "TensorIterator operation data pointer is out of range."); |
Copilot
AI
Jan 5, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error message differs between TensorIterator::GetInputPtr() ('TensorIterator operation...') and Indexer::GetWorkloadDataPtr() ('Index operation...'). Consider using consistent terminology across similar assertions for clarity.
| "TensorIterator operation data pointer is out of range."); | |
| "Index operation data pointer is out of range."); |
Type
Motivation and Context
This is not strictly a bug fix, it is just a low-cost method of making sure advanced indexing operations don't go out of bounds. The consequence of this happening could be either memory corruption, illegal memory access, or just undefined behavior. It makes sense to guard against these cases, as it is probably one of the more opaque ways a tensor operation might result in such behavior. Other comparable invalid operations might be caught by the user, but in my experience this one is the most opaque one. An example that would cause this issue:
The use cases of IndexSet, IndexGet, IndexAdd that I've come across have been of a computational nature, meaning the index was computed based on some arbitrary input data. Meaning that without proper due diligence, the validity of the indices is dependent on input data.
Checklist:
python util/check_style.py --applyto apply Open3D code styleto my code.
updated accordingly.
results (e.g. screenshots or numbers) here.
Description
Added an assertion check to Indexer, in a function which all index operations call to get input & output pointers.