@@ -61,8 +61,14 @@ struct AllocContext {
61
61
struct DeallocContext {
62
62
void *Ptr;
63
63
};
64
+ struct ReallocContext {
65
+ void *AllocPtr;
66
+ void *DeallocPtr;
67
+ size_t Size;
68
+ };
64
69
static AllocContext AC;
65
70
static DeallocContext DC;
71
+ static ReallocContext RC;
66
72
67
73
#if (SCUDO_ENABLE_HOOKS_TESTS == 1)
68
74
__attribute__ ((visibility(" default" ))) void __scudo_allocate_hook(void *Ptr,
@@ -73,6 +79,28 @@ __attribute__((visibility("default"))) void __scudo_allocate_hook(void *Ptr,
73
79
__attribute__ ((visibility(" default" ))) void __scudo_deallocate_hook(void *Ptr) {
74
80
DC.Ptr = Ptr;
75
81
}
82
+ __attribute__ ((visibility(" default" ))) void
83
+ __scudo_realloc_allocate_hook(void *OldPtr, void *NewPtr, size_t Size) {
84
+ // Verify that __scudo_realloc_deallocate_hook is called first and set the
85
+ // right pointer.
86
+ EXPECT_EQ (OldPtr, RC.DeallocPtr );
87
+ RC.AllocPtr = NewPtr;
88
+ RC.Size = Size;
89
+
90
+ // Note that this is only used for testing. In general, only one pair of hooks
91
+ // will be invoked in `realloc`. if __scudo_realloc_*_hook are not defined,
92
+ // it'll call the general hooks only. To make the test easier, we call the
93
+ // general one here so that either case (whether __scudo_realloc_*_hook are
94
+ // defined) will be verified without separating them into different tests.
95
+ __scudo_allocate_hook (NewPtr, Size);
96
+ }
97
+ __attribute__ ((visibility(" default" ))) void
98
+ __scudo_realloc_deallocate_hook(void *Ptr) {
99
+ RC.DeallocPtr = Ptr;
100
+
101
+ // See the comment in the __scudo_realloc_allocate_hook above.
102
+ __scudo_deallocate_hook (Ptr);
103
+ }
76
104
#endif // (SCUDO_ENABLE_HOOKS_TESTS == 1)
77
105
}
78
106
@@ -88,6 +116,7 @@ class ScudoWrappersCTest : public Test {
88
116
void *InvalidPtr = reinterpret_cast <void *>(0xdeadbeef );
89
117
AC.Ptr = InvalidPtr;
90
118
DC.Ptr = InvalidPtr;
119
+ RC.AllocPtr = RC.DeallocPtr = InvalidPtr;
91
120
}
92
121
}
93
122
void verifyAllocHookPtr (UNUSED void *Ptr) {
@@ -102,6 +131,13 @@ class ScudoWrappersCTest : public Test {
102
131
if (SCUDO_ENABLE_HOOKS_TESTS)
103
132
EXPECT_EQ (Ptr, DC.Ptr );
104
133
}
134
+ void verifyReallocHookPtrs (UNUSED void *OldPtr, void *NewPtr, size_t Size) {
135
+ if (SCUDO_ENABLE_HOOKS_TESTS) {
136
+ EXPECT_EQ (OldPtr, RC.DeallocPtr );
137
+ EXPECT_EQ (NewPtr, RC.AllocPtr );
138
+ EXPECT_EQ (Size, RC.Size );
139
+ }
140
+ }
105
141
};
106
142
using ScudoWrappersCDeathTest = ScudoWrappersCTest;
107
143
@@ -297,6 +333,7 @@ TEST_F(ScudoWrappersCDeathTest, Realloc) {
297
333
verifyAllocHookSize (Size * 2U );
298
334
verifyDeallocHookPtr (OldP);
299
335
}
336
+ verifyReallocHookPtrs (OldP, P, Size * 2U );
300
337
301
338
invalidateHookPtrs ();
302
339
OldP = P;
@@ -312,6 +349,7 @@ TEST_F(ScudoWrappersCDeathTest, Realloc) {
312
349
verifyAllocHookPtr (P);
313
350
verifyAllocHookSize (Size / 2U );
314
351
}
352
+ verifyReallocHookPtrs (OldP, P, Size / 2U );
315
353
free (P);
316
354
317
355
EXPECT_DEATH (P = realloc (P, Size), " " );
0 commit comments