Changeset 83564 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Apr 5, 2020 2:14:13 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/MMHeap.cpp
r82968 r83564 304 304 305 305 /** 306 * Links @a pHdr into the heap block list (tail). 307 * 308 * @param pHeap Heap handle. 309 * @param pHdr The block to link. 310 * 311 * @note Caller has locked the heap! 312 */ 313 DECLINLINE(void) mmR3HeapLink(PMMHEAP pHeap, PMMHEAPHDR pHdr) 314 { 315 /* Tail insertion: */ 316 pHdr->pNext = NULL; 317 PMMHEAPHDR pTail = pHeap->pTail; 318 pHdr->pPrev = pTail; 319 if (pTail) 320 { 321 Assert(!pTail->pNext); 322 pTail->pNext = pHdr; 323 } 324 else 325 { 326 Assert(!pHeap->pHead); 327 pHeap->pHead = pHdr; 328 } 329 pHeap->pTail = pHdr; 330 } 331 332 333 /** 334 * Unlinks @a pHdr from the heal block list. 335 * 336 * @param pHeap Heap handle. 337 * @param pHdr The block to unlink. 338 * 339 * @note Caller has locked the heap! 340 */ 341 DECLINLINE(void) mmR3HeapUnlink(PMMHEAP pHeap, PMMHEAPHDR pHdr) 342 { 343 PMMHEAPHDR const pPrev = pHdr->pPrev; 344 PMMHEAPHDR const pNext = pHdr->pNext; 345 if (pPrev) 346 pPrev->pNext = pNext; 347 else 348 pHeap->pHead = pNext; 349 350 if (pNext) 351 pNext->pPrev = pPrev; 352 else 353 pHeap->pTail = pHdr->pPrev; 354 } 355 356 357 /** 306 358 * Allocate memory from the heap. 307 359 * … … 373 425 RTCritSectLeave(&pHeap->Lock); 374 426 #endif 427 AssertFailed(); 375 428 return NULL; 376 429 } … … 380 433 */ 381 434 cbSize = RT_ALIGN_Z(cbSize, MMR3HEAP_SIZE_ALIGNMENT) + sizeof(MMHEAPHDR); 382 PMMHEAPHDR pHdr = (PMMHEAPHDR)(fZero ? RTMemAllocZ(cbSize) : RTMemAlloc(cbSize)); 383 if (!pHdr) 435 PMMHEAPHDR const pHdr = (PMMHEAPHDR)(fZero ? RTMemAllocZ(cbSize) : RTMemAlloc(cbSize)); 436 if (pHdr) 437 { /* likely */ } 438 else 384 439 { 385 440 AssertMsgFailed(("Failed to allocate heap block %d, enmTag=%x(%.4s).\n", cbSize, enmTag, &enmTag)); … … 394 449 Assert(!((uintptr_t)pHdr & (RTMEM_ALIGNMENT - 1))); 395 450 396 RTCritSectEnter(&pHeap->Lock);397 398 451 /* 399 452 * Init and link in the header. 400 453 */ 401 pHdr->pNext = NULL;402 pHdr->pPrev = pHeap->pTail;403 if (pHdr->pPrev)404 pHdr->pPrev->pNext = pHdr;405 else406 pHeap->pHead = pHdr;407 pHeap->pTail = pHdr;408 454 #ifdef MMR3HEAP_WITH_STATISTICS 409 455 pHdr->pStat = pStat; … … 412 458 #endif 413 459 pHdr->cbSize = cbSize; 460 461 RTCritSectEnter(&pHeap->Lock); 462 463 mmR3HeapLink(pHeap, pHdr); 414 464 415 465 /* … … 430 480 431 481 /** 432 * Reallocate memory allocated with MMR3HeapAlloc() or MMR3HeapRealloc(). 482 * Reallocate memory allocated with MMR3HeapAlloc(), MMR3HeapAllocZ() or 483 * MMR3HeapRealloc(). 484 * 485 * Any additional memory is zeroed (only reliable if the initial allocation was 486 * also of the zeroing kind). 433 487 * 434 488 * @returns Pointer to reallocated memory. … … 455 509 * Validate header. 456 510 */ 457 PMMHEAPHDR pHdr = (PMMHEAPHDR)pv - 1; 458 if ( pHdr->cbSize & (MMR3HEAP_SIZE_ALIGNMENT - 1) 459 || (uintptr_t)pHdr & (RTMEM_ALIGNMENT - 1)) 460 { 461 AssertMsgFailed(("Invalid heap header! pv=%p, size=%#x\n", pv, pHdr->cbSize)); 462 return NULL; 463 } 511 PMMHEAPHDR const pHdr = (PMMHEAPHDR)pv - 1; 512 size_t const cbOldSize = pHdr->cbSize; 513 AssertMsgReturn( !(cbOldSize & (MMR3HEAP_SIZE_ALIGNMENT - 1)) 514 && !((uintptr_t)pHdr & (RTMEM_ALIGNMENT - 1)), 515 ("Invalid heap header! pv=%p, size=%#x\n", pv, cbOldSize), 516 NULL); 464 517 Assert(pHdr->pStat != NULL); 465 518 Assert(!((uintptr_t)pHdr->pNext & (RTMEM_ALIGNMENT - 1))); … … 468 521 PMMHEAP pHeap = pHdr->pStat->pHeap; 469 522 470 #ifdef MMR3HEAP_WITH_STATISTICS 523 /* 524 * Unlink the header before we reallocate the block. 525 */ 471 526 RTCritSectEnter(&pHeap->Lock); 527 #ifdef MMR3HEAP_WITH_STATISTICS 472 528 pHdr->pStat->cReallocations++; 473 529 pHeap->Stat.cReallocations++; 530 #endif 531 mmR3HeapUnlink(pHeap, pHdr); 474 532 RTCritSectLeave(&pHeap->Lock); 475 #endif 476 477 /* 478 * Reallocate the block. 533 534 /* 535 * Reallocate the block. Clear added space. 479 536 */ 480 537 cbNewSize = RT_ALIGN_Z(cbNewSize, MMR3HEAP_SIZE_ALIGNMENT) + sizeof(MMHEAPHDR); 481 PMMHEAPHDR pHdrNew = (PMMHEAPHDR)RTMemRealloc(pHdr, cbNewSize); 482 if (!pHdrNew) 483 { 484 #ifdef MMR3HEAP_WITH_STATISTICS 538 PMMHEAPHDR pHdrNew = (PMMHEAPHDR)RTMemReallocZ(pHdr, cbOldSize, cbNewSize); 539 if (pHdrNew) 540 pHdrNew->cbSize = cbNewSize; 541 else 542 { 485 543 RTCritSectEnter(&pHeap->Lock); 544 mmR3HeapLink(pHeap, pHdr); 545 #ifdef MMR3HEAP_WITH_STATISTICS 486 546 pHdr->pStat->cFailures++; 487 547 pHeap->Stat.cFailures++; 548 #endif 488 549 RTCritSectLeave(&pHeap->Lock); 489 #endif490 550 return NULL; 491 551 } 492 552 493 /* 494 * Update pointers. 495 */ 496 if (pHdrNew != pHdr) 497 { 498 RTCritSectEnter(&pHeap->Lock); 499 if (pHdrNew->pPrev) 500 pHdrNew->pPrev->pNext = pHdrNew; 501 else 502 pHeap->pHead = pHdrNew; 503 504 if (pHdrNew->pNext) 505 pHdrNew->pNext->pPrev = pHdrNew; 506 else 507 pHeap->pTail = pHdrNew; 508 RTCritSectLeave(&pHeap->Lock); 509 } 553 RTCritSectEnter(&pHeap->Lock); 554 555 /* 556 * Relink the header. 557 */ 558 mmR3HeapLink(pHeap, pHdrNew); 510 559 511 560 /* … … 513 562 */ 514 563 #ifdef MMR3HEAP_WITH_STATISTICS 515 RTCritSectEnter(&pHeap->Lock);516 564 pHdrNew->pStat->cbAllocated += cbNewSize - pHdrNew->cbSize; 517 565 pHeap->Stat.cbAllocated += cbNewSize - pHdrNew->cbSize; 566 #endif 567 518 568 RTCritSectLeave(&pHeap->Lock); 519 #endif520 521 pHdrNew->cbSize = cbNewSize;522 569 523 570 return pHdrNew + 1; … … 650 697 * Releases memory allocated with MMR3HeapAlloc() or MMR3HeapRealloc(). 651 698 * 699 * The memory is cleared/filled before freeing to prevent heap spraying, info 700 * leaks, and help detect use after free trouble. 701 * 652 702 * @param pv Pointer to the memory block to free. 653 703 */ … … 661 711 * Validate header. 662 712 */ 663 PMMHEAPHDR pHdr = (PMMHEAPHDR)pv - 1; 664 if ( pHdr->cbSize & (MMR3HEAP_SIZE_ALIGNMENT - 1) 665 || (uintptr_t)pHdr & (RTMEM_ALIGNMENT - 1)) 666 { 667 AssertMsgFailed(("Invalid heap header! pv=%p, size=%#x\n", pv, pHdr->cbSize)); 668 return; 669 } 670 Assert(pHdr->pStat != NULL); 713 PMMHEAPHDR const pHdr = (PMMHEAPHDR)pv - 1; 714 size_t const cbAllocation = pHdr->cbSize; 715 AssertMsgReturnVoid( !(pHdr->cbSize & (MMR3HEAP_SIZE_ALIGNMENT - 1)) 716 && !((uintptr_t)pHdr & (RTMEM_ALIGNMENT - 1)), 717 ("Invalid heap header! pv=%p, size=%#x\n", pv, pHdr->cbSize)); 718 AssertPtr(pHdr->pStat); 671 719 Assert(!((uintptr_t)pHdr->pNext & (RTMEM_ALIGNMENT - 1))); 672 720 Assert(!((uintptr_t)pHdr->pPrev & (RTMEM_ALIGNMENT - 1))); … … 681 729 pHdr->pStat->cFrees++; 682 730 pHeap->Stat.cFrees++; 683 pHdr->pStat->cbFreed += pHdr->cbSize;684 pHeap->Stat.cbFreed += pHdr->cbSize;685 pHdr->pStat->cbCurAllocated -= pHdr->cbSize;686 pHeap->Stat.cbCurAllocated -= pHdr->cbSize;731 pHdr->pStat->cbFreed += cbAllocation; 732 pHeap->Stat.cbFreed += cbAllocation; 733 pHdr->pStat->cbCurAllocated -= cbAllocation; 734 pHeap->Stat.cbCurAllocated -= cbAllocation; 687 735 #endif 688 736 … … 690 738 * Unlink it. 691 739 */ 692 if (pHdr->pPrev) 693 pHdr->pPrev->pNext = pHdr->pNext; 694 else 695 pHeap->pHead = pHdr->pNext; 696 697 if (pHdr->pNext) 698 pHdr->pNext->pPrev = pHdr->pPrev; 699 else 700 pHeap->pTail = pHdr->pPrev; 740 mmR3HeapUnlink(pHeap, pHdr); 701 741 702 742 RTCritSectLeave(&pHeap->Lock); 703 743 704 744 /* 705 * Free the memory. 706 */ 707 RTMemFree(pHdr); 708 } 709 745 * Free the memory. We clear just to be on the safe size wrt 746 * heap spraying and leaking sensitive info (also helps detecting 747 * double freeing). 748 */ 749 RTMemFreeZ(pHdr, cbAllocation); 750 } 751
Note:
See TracChangeset
for help on using the changeset viewer.