-
-
Notifications
You must be signed in to change notification settings - Fork 22k
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 AddressSanitizer: heap-buffer-overflow from embree buffer check #94549
Conversation
043d4ff
to
cccd679
Compare
Looks like the vector 'grows exponentially' so it would have to be exactly sized to hit near a power of 2 to hit this dereference check and possibly cause a crash Edit:
|
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.
It looks like we should use reserve()
instead as well as resize()
here..
reserve()
with the padding, after resize()
without padding.
Also, upon further inspection I suspect this buffer may cause this error:
throw_RTCError(RTC_ERROR_INVALID_OPERATION, "data must be 4 bytes aligned");
on 32 bit systems that don't align their malloc to 16 bytes!!!
Even worse: this would only fail on release builds since debug builds automatically add padding to align to (it's fine, see my next comment)sizeof(uint64_t)
52f9017
to
538714e
Compare
After a more careful reading I realize the byte alignment requirement for the start of the buffer is 4 bytes (not 16). x86_32 malloc implementations seem to align to 8 bytes so I can stop worrying :D on 32 bit GNU/Linux for example, where realloc/malloc specification says
or msvcrt for 32 bit windows
|
Fixes godotengine#94548 Use reserve() instead of resize() when padding the buffer passed to embree, otherwise it will look past the end of the buffer since we pass the size() to rtcSetSharedGeometryBuffer and it dereferences `(int*)getPtr(size()-1) + 3` could cause a segfault if `capacity < size + 12`(bytes) When the address sanitizer is enabled it triggers an assertion /*! checks padding to 16 byte check, fails hard */ __forceinline void checkPadding16() const { if (ptr_ofs && num) volatile int MAYBE_UNUSED w = *((int*)getPtr(size()-1)+3); // FIXME: is failing hard avoidable? }
This seems fine and I trust your judgement. But at this point it feels a bit risky to merge for RC1, so I'm bumping to 4.4. |
The chances of this actually causing a segfault/access violation are pretty slim I don't see it happening in my project without turning on ASAN. Early 4.4/4.3.1/4.2.x etc sounds fine to me :D |
Fixed by #98770 |
Fixes #94548
Embree code seems to do some
incorrectconfusing pointer math when checking the padding, This evaluates to extra 12 bytes dereferencing an additional 4 byte int.When the address sanitizer is enabled it triggers an assertion