Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 404 WTF_EXPORT void partitionPurgeMemory(PartitionRoot*, int); | 404 WTF_EXPORT void partitionPurgeMemory(PartitionRoot*, int); |
| 405 WTF_EXPORT void partitionPurgeMemoryGeneric(PartitionRootGeneric*, int); | 405 WTF_EXPORT void partitionPurgeMemoryGeneric(PartitionRootGeneric*, int); |
| 406 | 406 |
| 407 WTF_EXPORT NEVER_INLINE void* partitionAllocSlowPath(PartitionRootBase*, int, si ze_t, PartitionBucket*); | 407 WTF_EXPORT NEVER_INLINE void* partitionAllocSlowPath(PartitionRootBase*, int, si ze_t, PartitionBucket*); |
| 408 WTF_EXPORT NEVER_INLINE void partitionFreeSlowPath(PartitionPage*); | 408 WTF_EXPORT NEVER_INLINE void partitionFreeSlowPath(PartitionPage*); |
| 409 WTF_EXPORT NEVER_INLINE void* partitionReallocGeneric(PartitionRootGeneric*, voi d*, size_t); | 409 WTF_EXPORT NEVER_INLINE void* partitionReallocGeneric(PartitionRootGeneric*, voi d*, size_t); |
| 410 | 410 |
| 411 WTF_EXPORT void partitionDumpStats(PartitionRoot*, const char* partitionName, bo ol isLightDump, PartitionStatsDumper*); | 411 WTF_EXPORT void partitionDumpStats(PartitionRoot*, const char* partitionName, bo ol isLightDump, PartitionStatsDumper*); |
| 412 WTF_EXPORT void partitionDumpStatsGeneric(PartitionRootGeneric*, const char* par titionName, bool isLightDump, PartitionStatsDumper*); | 412 WTF_EXPORT void partitionDumpStatsGeneric(PartitionRootGeneric*, const char* par titionName, bool isLightDump, PartitionStatsDumper*); |
| 413 | 413 |
| 414 class WTF_EXPORT PartitionHooks { | |
|
Primiano Tucci (use gerrit)
2015/10/14 10:10:12
nit: PartitionAllocHooks ? otherwise it seems that
Ruud van Asseldonk
2015/10/14 12:30:18
Done.
| |
| 415 public: | |
| 416 typedef void AllocationHook(void* address, size_t); | |
| 417 typedef void FreeHook(void* address); | |
| 418 | |
| 419 // Pointers to hook functions that PartitionAlloc will call on allocation an d | |
| 420 // free if the pointers are non-null. | |
| 421 static AllocationHook* allocationHook; | |
|
Primiano Tucci (use gerrit)
2015/10/14 10:10:12
nit: m_allocationHook i believe
Ruud van Asseldonk
2015/10/14 12:30:18
Done.
| |
| 422 static FreeHook* freeHook; | |
|
Primiano Tucci (use gerrit)
2015/10/14 10:10:12
I think you can make the static private: and expos
Ruud van Asseldonk
2015/10/14 12:30:18
Great idea, done.
| |
| 423 }; | |
| 424 | |
| 414 ALWAYS_INLINE PartitionFreelistEntry* partitionFreelistMask(PartitionFreelistEnt ry* ptr) | 425 ALWAYS_INLINE PartitionFreelistEntry* partitionFreelistMask(PartitionFreelistEnt ry* ptr) |
| 415 { | 426 { |
| 416 // We use bswap on little endian as a fast mask for two reasons: | 427 // We use bswap on little endian as a fast mask for two reasons: |
| 417 // 1) If an object is freed and its vtable used where the attacker doesn't | 428 // 1) If an object is freed and its vtable used where the attacker doesn't |
| 418 // get the chance to run allocations between the free and use, the vtable | 429 // get the chance to run allocations between the free and use, the vtable |
| 419 // dereference is likely to fault. | 430 // dereference is likely to fault. |
| 420 // 2) If the attacker has a linear buffer overflow and elects to try and | 431 // 2) If the attacker has a linear buffer overflow and elects to try and |
| 421 // corrupt a freelist pointer, partial pointer overwrite attacks are | 432 // corrupt a freelist pointer, partial pointer overwrite attacks are |
| 422 // thwarted. | 433 // thwarted. |
| 423 // For big endian, similar guarantees are arrived at with a negation. | 434 // For big endian, similar guarantees are arrived at with a negation. |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 606 slotSize = rawSize; | 617 slotSize = rawSize; |
| 607 } | 618 } |
| 608 size_t noCookieSize = partitionCookieSizeAdjustSubtract(slotSize); | 619 size_t noCookieSize = partitionCookieSizeAdjustSubtract(slotSize); |
| 609 char* charRet = static_cast<char*>(ret); | 620 char* charRet = static_cast<char*>(ret); |
| 610 // The value given to the application is actually just after the cookie. | 621 // The value given to the application is actually just after the cookie. |
| 611 ret = charRet + kCookieSize; | 622 ret = charRet + kCookieSize; |
| 612 memset(ret, kUninitializedByte, noCookieSize); | 623 memset(ret, kUninitializedByte, noCookieSize); |
| 613 partitionCookieWriteValue(charRet); | 624 partitionCookieWriteValue(charRet); |
| 614 partitionCookieWriteValue(charRet + kCookieSize + noCookieSize); | 625 partitionCookieWriteValue(charRet + kCookieSize + noCookieSize); |
| 615 #endif | 626 #endif |
| 627 | |
| 628 if (UNLIKELY(PartitionHooks::allocationHook != nullptr)) | |
| 629 PartitionHooks::allocationHook(ret, size); | |
| 630 | |
| 616 return ret; | 631 return ret; |
| 617 } | 632 } |
| 618 | 633 |
| 619 ALWAYS_INLINE void* partitionAlloc(PartitionRoot* root, size_t size) | 634 ALWAYS_INLINE void* partitionAlloc(PartitionRoot* root, size_t size) |
| 620 { | 635 { |
| 621 #if defined(MEMORY_TOOL_REPLACES_ALLOCATOR) | 636 #if defined(MEMORY_TOOL_REPLACES_ALLOCATOR) |
| 622 void* result = malloc(size); | 637 void* result = malloc(size); |
| 623 RELEASE_ASSERT(result); | 638 RELEASE_ASSERT(result); |
| 624 return result; | 639 return result; |
| 625 #else | 640 #else |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 638 // If these asserts fire, you probably corrupted memory. | 653 // If these asserts fire, you probably corrupted memory. |
| 639 #if ENABLE(ASSERT) | 654 #if ENABLE(ASSERT) |
| 640 size_t slotSize = page->bucket->slotSize; | 655 size_t slotSize = page->bucket->slotSize; |
| 641 size_t rawSize = partitionPageGetRawSize(page); | 656 size_t rawSize = partitionPageGetRawSize(page); |
| 642 if (rawSize) | 657 if (rawSize) |
| 643 slotSize = rawSize; | 658 slotSize = rawSize; |
| 644 partitionCookieCheckValue(ptr); | 659 partitionCookieCheckValue(ptr); |
| 645 partitionCookieCheckValue(reinterpret_cast<char*>(ptr) + slotSize - kCookieS ize); | 660 partitionCookieCheckValue(reinterpret_cast<char*>(ptr) + slotSize - kCookieS ize); |
| 646 memset(ptr, kFreedByte, slotSize); | 661 memset(ptr, kFreedByte, slotSize); |
| 647 #endif | 662 #endif |
| 663 | |
| 664 if (UNLIKELY(PartitionHooks::freeHook != nullptr)) | |
| 665 PartitionHooks::freeHook(ptr); | |
| 666 | |
| 648 ASSERT(page->numAllocatedSlots); | 667 ASSERT(page->numAllocatedSlots); |
| 649 PartitionFreelistEntry* freelistHead = page->freelistHead; | 668 PartitionFreelistEntry* freelistHead = page->freelistHead; |
| 650 ASSERT(!freelistHead || partitionPointerIsValid(freelistHead)); | 669 ASSERT(!freelistHead || partitionPointerIsValid(freelistHead)); |
| 651 RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(ptr != freelistHead); // Catches an immediate double free. | 670 RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(ptr != freelistHead); // Catches an immediate double free. |
| 652 ASSERT_WITH_SECURITY_IMPLICATION(!freelistHead || ptr != partitionFreelistMa sk(freelistHead->next)); // Look for double free one level deeper in debug. | 671 ASSERT_WITH_SECURITY_IMPLICATION(!freelistHead || ptr != partitionFreelistMa sk(freelistHead->next)); // Look for double free one level deeper in debug. |
| 653 PartitionFreelistEntry* entry = static_cast<PartitionFreelistEntry*>(ptr); | 672 PartitionFreelistEntry* entry = static_cast<PartitionFreelistEntry*>(ptr); |
| 654 entry->next = partitionFreelistMask(freelistHead); | 673 entry->next = partitionFreelistMask(freelistHead); |
| 655 page->freelistHead = entry; | 674 page->freelistHead = entry; |
| 656 --page->numAllocatedSlots; | 675 --page->numAllocatedSlots; |
| 657 if (UNLIKELY(page->numAllocatedSlots <= 0)) { | 676 if (UNLIKELY(page->numAllocatedSlots <= 0)) { |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 814 using WTF::partitionAlloc; | 833 using WTF::partitionAlloc; |
| 815 using WTF::partitionFree; | 834 using WTF::partitionFree; |
| 816 using WTF::partitionAllocGeneric; | 835 using WTF::partitionAllocGeneric; |
| 817 using WTF::partitionFreeGeneric; | 836 using WTF::partitionFreeGeneric; |
| 818 using WTF::partitionReallocGeneric; | 837 using WTF::partitionReallocGeneric; |
| 819 using WTF::partitionAllocActualSize; | 838 using WTF::partitionAllocActualSize; |
| 820 using WTF::partitionAllocSupportsGetSize; | 839 using WTF::partitionAllocSupportsGetSize; |
| 821 using WTF::partitionAllocGetSize; | 840 using WTF::partitionAllocGetSize; |
| 822 | 841 |
| 823 #endif // WTF_PartitionAlloc_h | 842 #endif // WTF_PartitionAlloc_h |
| OLD | NEW |