[VRT] Fix null ptr deref when a buddy superblock is full#122
Open
merkelmarrow wants to merge 1 commit into
Open
[VRT] Fix null ptr deref when a buddy superblock is full#122merkelmarrow wants to merge 1 commit into
merkelmarrow wants to merge 1 commit into
Conversation
BuddySuperblockBase::allocate returned a null UntypedBuffer when no free buddy of the requested size remained, but Allocator::allocate only catches std::bad_alloc to advance to the next superblock or create a new one. The null buffer was therefore wrapped in a MediumBlock/SmallBlock and returned, and Buffer::initAllocate then dereferenced its null backing buffer in view->getPhysAddr(), causing a segfault. This surfaces when using MEM/HBM_VNOC: three 32 MiB buffers fill one 64 MiB superblock after two allocations, so the third allocation needs a new superblock and instead crashes. Throwing bad_alloc on full matches the existing throw at the top of the same function. Signed-off-by: Marco Blackwell <mblackwe@amd.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
BuddySuperblockBase::allocatereturned nullptr when a superblock had no free buddy large enough for a request. However, its callers inAllocator::allocateare written to expect astd::bad_allocinstead. This means that, instead of moving on to the next superblock, the null was wrapped in a MediumBlock and returned as a valid allocation, then dereferenced host-side which produces a segfault.To reproduce
A host program crashes immediately in the
vrt::Bufferconstructor when allocating three 32 MiB buffers on the MEM/HBM_VNOC path. The fault is host-side, the actual vbin design doesn't matter much.LargeBlockSuperblockis fixed at 64 MiB, so two 32 MiB buffers fill one superblock and the third needs a new one:BuddySuperblockBase::allocatefalls through its search loop and returnsnullptr.The caller catches
bad_allocto fall through, but a returned null is not an exception, so thecatchnever fires and the new-superblock fallback below the loop is skipped:Fix
Replace
return nullptrwith athrow std::bad_alloc(). Matches the exception already used at the top of the same function for the oversize-index case.Testing
Reproduced and fixed on V80 with libvrt built from this branch.
vrtd::Buffer::getPhysAddr(this=0x0), called fromBuffer::initAllocateviaview->getPhysAddr(). Buffers 0 and 1 sit at 0x4000000000 and 0x4002000000, 32 MiB apart.