Commit d22d402e authored by Xiao Shi's avatar Xiao Shi Committed by Facebook Github Bot

fix erase use-after-free in F14Vector containers

Summary:
Upon `erase`, F14 vector containers destroys the value and erases the item
(i.e., index into the `values_` vector) from the underlying hashtable. However,
the item still needs to be hashable when erasing from the hashtable, so we have
to destroy the value _afterwards_.

This diff fixes the bug.

There are a couple of reasons that this was previous undetected / did not cause
a problem:
  * for POD types, `allocator_traits::destroy` is a no-op.
  * this code path is only hit if the chunk of the destroyed item has hosted
    overflowed items
  * the use was immediately after free
  * our test coverage did not have vector policy + non-SSO string keys

Reviewed By: nbronson

Differential Revision: D7488050

fbshipit-source-id: ea29e875a0c7a39b8deed40a15777a6983438836
parent 3cec1c6b
main v2022.02.14.00 v2022.02.07.00 v2022.01.31.00 v2022.01.24.00 v2022.01.17.00 v2022.01.10.00 v2022.01.03.00 v2021.12.27.00 v2021.12.20.00 v2021.12.13.00 v2021.12.06.00 v2021.11.29.00 v2021.11.15.00 v2021.11.08.00 v2021.11.01.00 v2021.10.25.00 v2021.10.18.00 v2021.10.11.00 v2021.10.04.00 v2021.09.27.00 v2021.09.20.00 v2021.09.13.00 v2021.09.06.00 v2021.08.30.00 v2021.08.23.00 v2021.08.02.00 v2021.07.22.00 v2021.07.20.01 v2021.07.20.00 v2021.06.28.00 v2021.06.14.00 v2021.06.07.00 v2021.05.31.00 v2021.05.24.00 v2021.05.17.00 v2021.05.10.00 v2021.05.03.00 v2021.04.26.00 v2021.04.19.00 v2021.04.12.00 v2021.04.05.00 v2021.03.29.00 v2021.03.22.00 v2021.03.15.00 v2021.03.08.00 v2021.03.01.00 v2021.02.22.00 v2021.02.15.00 v2021.02.08.00 v2021.02.01.00 v2021.01.25.00 v2021.01.18.01 v2021.01.18.00 v2021.01.11.00 v2021.01.04.00 v2020.12.28.00 v2020.12.21.00 v2020.12.14.00 v2020.12.07.00 v2020.11.30.00 v2020.11.23.00 v2020.11.16.00 v2020.11.09.00 v2020.11.02.00 v2020.10.26.00 v2020.10.19.00 v2020.10.12.00 v2020.10.05.00 v2020.09.28.00 v2020.09.21.00 v2020.09.14.00 v2020.09.07.00 v2020.08.31.00 v2020.08.24.00 v2020.08.17.00 v2020.08.10.00 v2020.08.03.00 v2020.07.27.00 v2020.07.20.00 v2020.07.13.00 v2020.07.06.00 v2020.06.29.00 v2020.06.15.00 v2020.06.08.00 v2020.06.01.00 v2020.05.25.00 v2020.05.18.00 v2020.05.11.00 v2020.05.04.00 v2020.04.27.00 v2020.04.20.00 v2020.04.13.00 v2020.04.06.00 v2020.03.30.00 v2020.03.23.00 v2020.03.16.00 v2020.03.09.00 v2020.03.02.00 v2020.02.24.00 v2020.02.17.00 v2020.02.10.00 v2020.02.03.00 v2020.01.27.00 v2020.01.20.00 v2020.01.13.00 v2020.01.06.00 v2019.12.30.00 v2019.12.23.00 v2019.12.16.00 v2019.12.09.00 v2019.12.06.00 v2019.12.02.00 v2019.11.11.00 v2019.11.04.00 v2019.10.28.00 v2019.10.21.00 v2019.10.14.00 v2019.10.07.00 v2019.09.30.00 v2019.09.23.00 v2019.09.16.00 v2019.09.09.00 v2019.09.02.00 v2019.08.26.00 v2019.08.19.00 v2019.08.12.00 v2019.08.05.00 v2019.07.29.00 v2019.07.22.00 v2019.06.17.00 v2019.06.10.00 v2019.06.03.00 v2019.05.27.00 v2019.05.20.00 v2019.05.13.00 v2019.05.06.00 v2019.04.29.00 v2019.04.22.00 v2019.04.15.00 v2019.04.08.00 v2019.04.01.00 v2019.03.25.00 v2019.03.18.00 v2019.03.04.00 v2019.02.25.00 v2019.02.18.00 v2019.02.11.00 v2019.02.04.00 v2019.01.28.00 v2019.01.21.00 v2019.01.14.00 v2019.01.07.00 v2018.12.31.00 v2018.12.24.00 v2018.12.17.00 v2018.12.10.00 v2018.12.03.00 v2018.11.26.00 v2018.11.19.00 v2018.11.12.00 v2018.11.05.00 v2018.10.29.00 v2018.10.22.00 v2018.10.15.00 v2018.10.08.00 v2018.10.01.00 v2018.09.24.00 v2018.09.17.00 v2018.09.10.01 v2018.09.10.00 v2018.09.03.01 v2018.09.03.00 v2018.08.27.00 v2018.08.20.00 v2018.08.13.00 v2018.08.09.00 v2018.08.06.00 v2018.07.30.00 v2018.07.23.00 v2018.07.16.00 v2018.07.09.00 v2018.07.02.00 v2018.06.25.00 v2018.06.18.00 v2018.06.11.00 v2018.06.04.00 v2018.05.28.00 v2018.05.21.00 v2018.05.14.00 v2018.05.07.00 v2018.04.30.00 v2018.04.23.00 v2018.04.16.00 v2018.04.09.00
No related merge requests found
......@@ -965,10 +965,12 @@ class F14VectorMap
Alloc& a = this->table_.alloc();
auto values = this->table_.values_;
// destroy the value and remove the ptr from the base table
// Remove the ptr from the base table and destroy the value.
auto index = underlying.item();
std::allocator_traits<Alloc>::destroy(a, std::addressof(values[index]));
// The item still needs to be hashable during this call, so we must destroy
// the value _afterwards_.
this->table_.erase(underlying);
std::allocator_traits<Alloc>::destroy(a, std::addressof(values[index]));
// move the last element in values_ down and fix up the inbound index
auto tailIndex = this->size();
......
......@@ -520,6 +520,32 @@ TEST(F14ValueMap, steady_state_stats) {
F14TableStats::compute(h);
}
TEST(F14VectorMap, steady_state_stats) {
// 10k keys, 14% probability of insert, 90% chance of erase, so the
// table should converge to 1400 size without triggering the rehash
// that would occur at 1536.
F14VectorMap<std::string, uint64_t> h;
std::mt19937_64 gen(0);
std::uniform_int_distribution<> dist(0, 10000);
for (std::size_t i = 0; i < 100000; ++i) {
auto key = "0123456789ABCDEFGHIJKLMNOPQ" + std::to_string(dist(gen));
if (dist(gen) < 1400) {
h.insert_or_assign(key, i);
} else {
h.erase(key);
}
if (((i + 1) % 10000) == 0) {
auto stats = F14TableStats::compute(h);
// Verify that average miss probe length is bounded despite continued
// erase + reuse. p99 of the average across 10M random steps is 4.69,
// average is 2.96.
EXPECT_LT(f14::expectedProbe(stats.missProbeLengthHisto), 10.0);
}
}
// F14ValueMap at steady state
F14TableStats::compute(h);
}
TEST(Tracked, baseline) {
Tracked<0> a0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment