Added assertion to guard against memory corruption#7360
Added assertion to guard against memory corruption#7360TwentyPast4 wants to merge 7 commits intoisl-org:mainfrom
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.
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_ |
There was a problem hiding this comment.
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."); |
There was a problem hiding this comment.
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."); |
There was a problem hiding this comment.
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."); |
|
Hi @TwentyPast4 thanks for this useful PR! How does this compare to the behavior of PyTorch and Numpy? The Open3D tensors are designed to be consistent with them. Also, |
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.