-
Type:
Bug
-
Resolution: Done
-
Priority:
Major - P3
-
Affects Version/s: None
-
Component/s: Storage
-
Environment:All
-
Fully Compatible
-
ALL
-
None
-
None
-
None
-
None
-
None
-
None
-
None
Fixed potential pointer overflow leading to an infinite loop in
db/storage/record.cpp
In order to iterate over the data in the record there was a previous loop that
compared pointers:
const char * addr = _data;
const char * end = _data + _netLength();
for ( ; addr <= end ; addr += 2048 ) {
__record_touch_dummy += addr[0];
this will not work as expected because the addr pointer may overflow.
Consider the size of _data, where it is defined in mongo::ps::Slice as:
Entry _data[SliceSize]
Here _netLength is defined as:
int _netLength() const
{ return _lengthWithHeaders - HeaderSize; }in mongo/db/pdfile.h. Where HeaderSize = 16 and _lengthWithHeaders is set in a
number of places through the function:
int& lengthWithHeaders()
{ _accessing(); return _lengthWithHeaders; }in mongo/db/pdfile.h.
Assuming we can't guarantee anything about the exact value of _netLength (for
example, that it's always exactly a multiple of 2048) then there will be an
issue with the addr pointer overflowing the bounds of _data.
In C, it is undefined behavior to increment a pointer (in this case addr) more
than 1 past the end of the array (in this case _data) to which it points.
If the compiler so chooses, it may wrap around the pointer if it increases past
_data + SliceSize + 1. This would cause this loop to never exit because addr
would always be less than end.