Skip to content

Commit bc354a9

Browse files
goldvitalycopybara-github
authored andcommitted
Avoid subtracting it.control() and table.control() in single element table during erase.
`it.control()` is pointing to `kSooControl` global buffer. The result of subtraction is not used, but that causes UBSAN pointer overflow error. PiperOrigin-RevId: 758683515 Change-Id: Ifa9e3f7f2da3de371dd65f3e1d42c77c20aece59
1 parent 472365f commit bc354a9

File tree

2 files changed

+7
-8
lines changed

2 files changed

+7
-8
lines changed

absl/container/internal/raw_hash_set.cc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -526,9 +526,8 @@ ABSL_ATTRIBUTE_ALWAYS_INLINE inline void InitializeThreeElementsControlBytes(
526526

527527
} // namespace
528528

529-
void EraseMetaOnly(CommonFields& c, size_t index, size_t slot_size) {
530-
ABSL_SWISSTABLE_ASSERT(IsFull(c.control()[index]) &&
531-
"erasing a dangling iterator");
529+
void EraseMetaOnly(CommonFields& c, const ctrl_t* ctrl, size_t slot_size) {
530+
ABSL_SWISSTABLE_ASSERT(IsFull(*ctrl) && "erasing a dangling iterator");
532531
c.decrement_size();
533532
c.infoz().RecordErase();
534533

@@ -538,6 +537,8 @@ void EraseMetaOnly(CommonFields& c, size_t index, size_t slot_size) {
538537
return;
539538
}
540539

540+
size_t index = static_cast<size_t>(ctrl - c.control());
541+
541542
if (WasNeverFull(c, index)) {
542543
SetCtrl(c, index, ctrl_t::kEmpty, slot_size);
543544
c.growth_info().OverwriteFullAsEmpty();

absl/container/internal/raw_hash_set.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1847,7 +1847,7 @@ void ClearBackingArray(CommonFields& c, const PolicyFunctions& policy,
18471847
void* alloc, bool reuse, bool soo_enabled);
18481848

18491849
// Type-erased version of raw_hash_set::erase_meta_only.
1850-
void EraseMetaOnly(CommonFields& c, size_t index, size_t slot_size);
1850+
void EraseMetaOnly(CommonFields& c, const ctrl_t* ctrl, size_t slot_size);
18511851

18521852
// For trivially relocatable types we use memcpy directly. This allows us to
18531853
// share the same function body for raw_hash_set instantiations that have the
@@ -3140,8 +3140,7 @@ class raw_hash_set {
31403140
common().set_empty_soo();
31413141
return;
31423142
}
3143-
EraseMetaOnly(common(), static_cast<size_t>(it.control() - control()),
3144-
sizeof(slot_type));
3143+
EraseMetaOnly(common(), it.control(), sizeof(slot_type));
31453144
}
31463145

31473146
template <class K>
@@ -3691,8 +3690,7 @@ struct HashtableFreeFunctionsAccess {
36913690
auto* slot = static_cast<SlotType*>(slot_void);
36923691
if (pred(Set::PolicyTraits::element(slot))) {
36933692
c->destroy(slot);
3694-
EraseMetaOnly(c->common(), static_cast<size_t>(ctrl - c->control()),
3695-
sizeof(*slot));
3693+
EraseMetaOnly(c->common(), ctrl, sizeof(*slot));
36963694
++num_deleted;
36973695
}
36983696
});

0 commit comments

Comments
 (0)