11
11
12
12
#include " chunk.h"
13
13
#include " common.h"
14
+ #include " internal_defs.h"
14
15
#include " list.h"
15
16
#include " mem_map.h"
16
17
#include " memtag.h"
@@ -476,6 +477,23 @@ template <typename Config> class MapAllocator {
476
477
DCHECK_EQ (FreedBytes, 0U );
477
478
Cache.init (ReleaseToOsInterval);
478
479
Stats.init ();
480
+
481
+ if (Config::Secondary::VerifyInUseAddresses) {
482
+ ReservedMemoryT InUseReserved;
483
+ InUseReserved.create (
484
+ 0U , sizeof (void *) * (Config::Secondary::InUseBlocksSize + 1 ),
485
+ " scudo:secondary_integrity" );
486
+ DCHECK_NE (InUseReserved.getBase (), 0U );
487
+
488
+ InUseAddresses = InUseReserved.dispatch (
489
+ InUseReserved.getBase (),
490
+ sizeof (void *) * (Config::Secondary::InUseBlocksSize + 1 ));
491
+ CHECK (InUseAddresses.isAllocated ());
492
+ InUseAddresses.setMemoryPermission (
493
+ InUseAddresses.getBase (),
494
+ sizeof (void *) * (Config::Secondary::InUseBlocksSize + 1 ), 0 );
495
+ }
496
+
479
497
if (LIKELY (S))
480
498
S->link (&Stats);
481
499
}
@@ -544,6 +562,8 @@ template <typename Config> class MapAllocator {
544
562
u32 NumberOfAllocs GUARDED_BY (Mutex) = 0;
545
563
u32 NumberOfFrees GUARDED_BY (Mutex) = 0;
546
564
LocalStats Stats GUARDED_BY (Mutex);
565
+
566
+ MemMapT InUseAddresses GUARDED_BY (Mutex) = {};
547
567
};
548
568
549
569
// As with the Primary, the size passed to this function includes any desired
@@ -588,6 +608,54 @@ void *MapAllocator<Config>::allocate(const Options &Options, uptr Size,
588
608
BlockEnd - PtrInt);
589
609
{
590
610
ScopedLock L (Mutex);
611
+
612
+ if (Config::Secondary::VerifyInUseAddresses) {
613
+ void **IntegrityList =
614
+ reinterpret_cast <void **>(InUseAddresses.getBase ());
615
+ bool isFull = true ;
616
+ bool reachedEnd = false ;
617
+
618
+ while (!reachedEnd) {
619
+ for (u32 I = 0 ; I < Config::Secondary::InUseBlocksSize; I++) {
620
+ if (IntegrityList[I] == nullptr ) {
621
+ isFull = false ;
622
+ IntegrityList[I] = Ptr ;
623
+ break ;
624
+ }
625
+ }
626
+ if (isFull &&
627
+ IntegrityList[Config::Secondary::InUseBlocksSize] != nullptr ) {
628
+ IntegrityList = static_cast <void **>(
629
+ IntegrityList[Config::Secondary::InUseBlocksSize]);
630
+ } else {
631
+ reachedEnd = true ;
632
+ }
633
+ }
634
+
635
+ if (isFull) {
636
+ ReservedMemoryT InUseReserved;
637
+ InUseReserved.create (
638
+ 0U , sizeof (void *) * (Config::Secondary::InUseBlocksSize + 1 ),
639
+ " scudo:secondary_integrity" );
640
+ DCHECK_NE (InUseReserved.getBase (), 0U );
641
+
642
+ MemMapT NewAddresses = InUseReserved.dispatch (
643
+ InUseReserved.getBase (),
644
+ sizeof (void *) * (Config::Secondary::InUseBlocksSize + 1 ));
645
+ CHECK (NewAddresses.isAllocated ());
646
+ NewAddresses.setMemoryPermission (
647
+ NewAddresses.getBase (),
648
+ sizeof (void *) * (Config::Secondary::InUseBlocksSize + 1 ), 0 );
649
+
650
+ IntegrityList[Config::Secondary::InUseBlocksSize] =
651
+ reinterpret_cast <void *>(NewAddresses.getBase ());
652
+
653
+ IntegrityList = static_cast <void **>(
654
+ IntegrityList[Config::Secondary::InUseBlocksSize]);
655
+ IntegrityList[0 ] = Ptr ;
656
+ }
657
+ }
658
+
591
659
InUseBlocks.push_back (H);
592
660
AllocatedBytes += H->CommitSize ;
593
661
FragmentedBytes += H->MemMap .getCapacity () - H->CommitSize ;
@@ -662,6 +730,56 @@ void *MapAllocator<Config>::allocate(const Options &Options, uptr Size,
662
730
*BlockEndPtr = CommitBase + CommitSize;
663
731
{
664
732
ScopedLock L (Mutex);
733
+
734
+ if (Config::Secondary::VerifyInUseAddresses) {
735
+ void **IntegrityList =
736
+ reinterpret_cast <void **>(InUseAddresses.getBase ());
737
+ bool isFull = true ;
738
+ bool reachedEnd = false ;
739
+
740
+ while (!reachedEnd) {
741
+ for (u32 I = 0 ; I < Config::Secondary::InUseBlocksSize; I++) {
742
+ if (IntegrityList[I] == nullptr ) {
743
+ isFull = false ;
744
+ IntegrityList[I] = reinterpret_cast <void *>(
745
+ HeaderPos + LargeBlock::getHeaderSize ());
746
+ break ;
747
+ }
748
+ }
749
+ if (isFull &&
750
+ IntegrityList[Config::Secondary::InUseBlocksSize] != nullptr ) {
751
+ IntegrityList = static_cast <void **>(
752
+ IntegrityList[Config::Secondary::InUseBlocksSize]);
753
+ } else {
754
+ reachedEnd = true ;
755
+ }
756
+ }
757
+
758
+ if (isFull) {
759
+ ReservedMemoryT InUseReserved;
760
+ InUseReserved.create (
761
+ 0U , sizeof (void *) * (Config::Secondary::InUseBlocksSize + 1 ),
762
+ " scudo:secondary_integrity" );
763
+ DCHECK_NE (InUseReserved.getBase (), 0U );
764
+
765
+ MemMapT NewAddresses = InUseReserved.dispatch (
766
+ InUseReserved.getBase (),
767
+ sizeof (void *) * (Config::Secondary::InUseBlocksSize + 1 ));
768
+ CHECK (NewAddresses.isAllocated ());
769
+ NewAddresses.setMemoryPermission (
770
+ NewAddresses.getBase (),
771
+ sizeof (void *) * (Config::Secondary::InUseBlocksSize + 1 ), 0 );
772
+
773
+ IntegrityList[Config::Secondary::InUseBlocksSize] =
774
+ reinterpret_cast <void *>(NewAddresses.getBase ());
775
+
776
+ IntegrityList = static_cast <void **>(
777
+ IntegrityList[Config::Secondary::InUseBlocksSize]);
778
+ IntegrityList[0 ] =
779
+ reinterpret_cast <void *>(HeaderPos + LargeBlock::getHeaderSize ());
780
+ }
781
+ }
782
+
665
783
InUseBlocks.push_back (H);
666
784
AllocatedBytes += CommitSize;
667
785
FragmentedBytes += H->MemMap .getCapacity () - CommitSize;
@@ -681,6 +799,35 @@ void MapAllocator<Config>::deallocate(const Options &Options, void *Ptr)
681
799
const uptr CommitSize = H->CommitSize ;
682
800
{
683
801
ScopedLock L (Mutex);
802
+
803
+ if (Config::Secondary::VerifyInUseAddresses) {
804
+ void **IntegrityList =
805
+ reinterpret_cast <void **>(InUseAddresses.getBase ());
806
+ bool isValid = false ;
807
+ bool reachedEnd = false ;
808
+
809
+ while (!reachedEnd) {
810
+ for (u32 I = 0 ; I < Config::Secondary::InUseBlocksSize; I++) {
811
+ if (IntegrityList[I] == Ptr ) {
812
+ isValid = true ;
813
+ IntegrityList[I] = nullptr ;
814
+ break ;
815
+ }
816
+ }
817
+ if (!isValid &&
818
+ IntegrityList[Config::Secondary::InUseBlocksSize] != nullptr ) {
819
+ IntegrityList = static_cast <void **>(
820
+ IntegrityList[Config::Secondary::InUseBlocksSize]);
821
+ } else {
822
+ reachedEnd = true ;
823
+ }
824
+ }
825
+
826
+ if (!isValid) {
827
+ return ;
828
+ }
829
+ }
830
+
684
831
InUseBlocks.remove (H);
685
832
FreedBytes += CommitSize;
686
833
FragmentedBytes -= H->MemMap .getCapacity () - CommitSize;
0 commit comments