Skip to content

Commit 8c61e4c

Browse files
authored
Merge pull request #41210 from mikeash/clear-async-slab-metadatas
[Concurrency] Clear Slab's fake metadata pointer before freeing it.
2 parents e2bd75d + 1020a1a commit 8c61e4c

File tree

2 files changed

+29
-0
lines changed

2 files changed

+29
-0
lines changed

stdlib/public/Concurrency/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ else()
6161
list(APPEND SWIFT_RUNTIME_CONCURRENCY_C_FLAGS "-fswift-async-fp=never")
6262
endif()
6363

64+
list(APPEND SWIFT_RUNTIME_CONCURRENCY_C_FLAGS
65+
"-D__STDC_WANT_LIB_EXT1__=1")
66+
6467
add_swift_target_library(swift_Concurrency ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_STDLIB
6568
../CompatibilityOverride/CompatibilityOverride.cpp
6669
Actor.cpp

stdlib/public/runtime/StackAllocator.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@
1414
//
1515
//===----------------------------------------------------------------------===//
1616

17+
// Define __STDC_WANT_LIB_EXT1__ to get memset_s on platforms that have it.
18+
// Other files may have included string.h without it already, so we also set
19+
// this with a -D flag when building, but this allows tests to build without
20+
// additional trouble.
21+
#define __STDC_WANT_LIB_EXT1__ 1
22+
#include <string.h>
23+
1724
#include "swift/ABI/MetadataValues.h"
1825
#include "swift/Runtime/Debug.h"
1926
#include "llvm/Support/Alignment.h"
@@ -118,6 +125,22 @@ class StackAllocator {
118125
return headerSize() + size;
119126
}
120127

128+
/// Clear the fake metadata pointer. Call before freeing so that leftover
129+
/// heap garbage doesn't have slab metadata pointers in it.
130+
void clearMetadata() {
131+
// Use memset_s or explicit_bzero where available. Fall back to a plain
132+
// assignment on unknown platforms. This is not necessary for correctness,
133+
// just as an aid to analysis tools, so it's OK if the fallback gets
134+
// optimized out.
135+
#if defined(__APPLE__)
136+
memset_s(&metadata, sizeof(metadata), 0, sizeof(metadata));
137+
#elif defined(__linux__)
138+
explicit_bzero(&metadata, sizeof(metadata));
139+
#else
140+
metadata = 0;
141+
#endif
142+
}
143+
121144
/// Return the payload buffer address at \p atOffset.
122145
///
123146
/// Note: it's valid to call this function on a not-yet-constructed slab.
@@ -247,6 +270,7 @@ class StackAllocator {
247270
while (slab) {
248271
Slab *next = slab->next;
249272
freedCapacity += slab->capacity;
273+
slab->clearMetadata();
250274
free(slab);
251275
numAllocatedSlabs--;
252276
slab = next;
@@ -272,6 +296,8 @@ class StackAllocator {
272296
~StackAllocator() {
273297
if (lastAllocation)
274298
SWIFT_FATAL_ERROR(0, "not all allocations are deallocated");
299+
if (firstSlabIsPreallocated)
300+
firstSlab->clearMetadata();
275301
(void)freeAllSlabs(firstSlabIsPreallocated ? firstSlab->next : firstSlab);
276302
assert(getNumAllocatedSlabs() == 0);
277303
}

0 commit comments

Comments
 (0)