Skip to content

Commit 469a9f3

Browse files
committed
Fix two nasty use-after-free-bugs
Summary: These bugs were caught by ASAN crash test. 1. The first one, in table/filter_block.cc is very nasty. We first reference entries_ and store the reference to Slice prev. Then, we call entries_.append(), which can change the reference. The Slice prev now points to junk. 2. The second one is a bug in a test, so it's not very serious. Once we set read_opts.prefix, we never clear it, so some other function might still reference it. Test Plan: asan crash test now runs more than 5 mins. Before, it failed immediately. I will run the full one, but the full one takes quite some time (5 hours) Reviewers: dhruba, haobo, kailiu Reviewed By: dhruba CC: leveldb Differential Revision: https://reviews.facebook.net/D14223
1 parent 8906ab5 commit 469a9f3

File tree

2 files changed

+12
-8
lines changed

2 files changed

+12
-8
lines changed

table/filter_block.cc

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,19 +52,22 @@ bool FilterBlockBuilder::SamePrefix(const Slice &key1,
5252
void FilterBlockBuilder::AddKey(const Slice& key) {
5353
// get slice for most recently added entry
5454
Slice prev;
55-
if (start_.size() > 0) {
56-
size_t prev_start = start_[start_.size() - 1];
57-
const char* base = entries_.data() + prev_start;
58-
size_t length = entries_.size() - prev_start;
59-
prev = Slice(base, length);
60-
}
55+
size_t added_to_start = 0;
6156

6257
// add key to filter if needed
6358
if (whole_key_filtering_) {
6459
start_.push_back(entries_.size());
60+
++added_to_start;
6561
entries_.append(key.data(), key.size());
6662
}
6763

64+
if (start_.size() > added_to_start) {
65+
size_t prev_start = start_[start_.size() - 1 - added_to_start];
66+
const char* base = entries_.data() + prev_start;
67+
size_t length = entries_.size() - prev_start;
68+
prev = Slice(base, length);
69+
}
70+
6871
// add prefix to filter if needed
6972
if (prefix_extractor_ && prefix_extractor_->InDomain(ExtractUserKey(key))) {
7073
// If prefix_extractor_, this filter_block layer assumes we only

tools/db_stress.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,6 +1118,7 @@ class StressTest {
11181118
} else {
11191119
MultiPrefixScan(thread, read_opts, prefix);
11201120
}
1121+
read_opts.prefix = nullptr;
11211122
} else if (prefixBound <= prob_op && prob_op < writeBound) {
11221123
// OPERATION write
11231124
uint32_t value_base = thread->rand.Next();
@@ -1126,8 +1127,8 @@ class StressTest {
11261127
if (!FLAGS_test_batches_snapshots) {
11271128
MutexLock l(thread->shared->GetMutexForKey(rand_key));
11281129
if (FLAGS_verify_before_write) {
1129-
std::string keystr = Key(rand_key);
1130-
Slice k = keystr;
1130+
std::string keystr2 = Key(rand_key);
1131+
Slice k = keystr2;
11311132
Status s = db_->Get(read_opts, k, &from_db);
11321133
VerifyValue(rand_key,
11331134
read_opts,

0 commit comments

Comments
 (0)