[libc-commits] [libc] [libc][stdlib] Fix UB in freelist (PR #95330)
via libc-commits
libc-commits at lists.llvm.org
Thu Jun 13 13:48:11 PDT 2024
================
@@ -92,19 +93,14 @@ bool FreeList<NUM_BUCKETS>::add_chunk(span<cpp::byte> chunk) {
if (chunk.size() < sizeof(FreeListNode))
return false;
- union {
- FreeListNode *node;
- cpp::byte *bytes;
- } aliased;
-
- aliased.bytes = chunk.data();
-
+ // Add it to the correct list.
size_t chunk_ptr = find_chunk_ptr_for_size(chunk.size(), false);
- // Add it to the correct list.
- aliased.node->size = chunk.size();
- aliased.node->next = chunks_[chunk_ptr];
- chunks_[chunk_ptr] = aliased.node;
+ FreeListNode node;
+ node.next = chunks_[chunk_ptr];
+ node.size = chunk.size();
+ LIBC_NAMESPACE::memcpy(chunk.data(), &node, sizeof(node));
----------------
PiJoules wrote:
Actually, since this is the only place a FreeListNode is created, I think a better way to do this would be placement new via
```
FreeListNode *node = new (chunk.data()) FreeListNode(chunks_[chunk_ptr], chunk.size());
```
This way we start the object lifetime of a FreeListNode at `chunk.data()`. This only requires `chunk.data()` being properly aligned but I think this should always be the case because a FreeListNode should always be stored after a Block which will have alignment large enough to hold a pointer.
https://github.com/llvm/llvm-project/pull/95330
More information about the libc-commits
mailing list