-
Notifications
You must be signed in to change notification settings - Fork 583
Description
There is a common pattern in OpenSubdiv where integers of smaller types are passed into the resize method of std::vectors. When the incoming meshes are very large, these types overflow and can cause a crash. We are encountering this issue when loading the Moana island dataset into Solaris on Apple silicon.
For instance:
quadRefinement.cpp:108: _child->_faceVertIndices.resize(_child->getNumFaces() * 4);
getNumFaces returns a 32 bit integer, while resize accepts a size_t. In our crash, getNumFaces returns 625186471 and is multiplied by 4 as a 32 bit integer before being implicitly casted to size_t. This results in the integer overflow.
There is also this pattern, which would also need to be addressed:
int childEdgeFaceIndexSizeEstimate = (int)_parent->_faceVertIndices.size() * 2 +
(int)_parent->_edgeFaceIndices.size() * 2;
_child->_edgeFaceCountsAndOffsets.resize(_child->getNumEdges() * 2);
_child->_edgeFaceIndices.resize( childEdgeFaceIndexSizeEstimate);
The size_t result from _faceVertIndices.size() is narrowed to an integer and then multiplied, which can cause a multiplicative overflow, and is then added to another narrowed result, which could result in an additional overflow. The result of childEdgeFaceIndexSizeEstimate is then multiplied as a 32-bit integer before being casted back to a size_t.
I can see two ways in which this could be resolved. One would be to explicitly cast each call to getNumFaces() and similar methods to size_t before the multiplication. The second way, which would result in less code modification, would be to change the return types of these getNum methods to size_t, however this would change ABI.
FYI: clang-tidy reports these issues as "bugprone-implicit-widening-of-multiplication-result".