Commit 4e3e49f9 authored by Calder Kitagawa's avatar Calder Kitagawa Committed by Commit Bot

[Zucchini]: Fix bugs found by Apply fuzzer

Located by fuzzing ZTF Apply (WIP):
https://chromium-review.googlesource.com/c/chromium/src/+/1072231

Found two fatal errors:
- OffsetForKey always assumes a key is valid however, the validity of
  the key is not checked prior to the caller invoking the method. The
  caller also had no way to check validity if it was external to
  TargetPool.
  Fix: Add a method to check for key validity ahead of calling
       OffsetForKey.

- ConvertToTargetLineCol for absolute references had a logic bug that
  resulted in attempting to dereference an invalid base::Optional
  Fix: Change the logic to avoid issue.

Bug: 835341
Change-Id: I99c91741eef41dfaa3036af8e708eb3f0d5ca84a
Reviewed-on: https://chromium-review.googlesource.com/1072272
Commit-Queue: Calder Kitagawa <ckitagawa@chromium.org>
Reviewed-by: default avatarSamuel Huang <huangs@chromium.org>
Cr-Commit-Position: refs/heads/master@{#561642}
parent 77d87185
......@@ -351,7 +351,7 @@ class ZtfReferenceWriter : public ReferenceWriter {
// Returns true on success.
bool ConvertToTargetLineCol(Reference reference, ztf::LineCol* out_lc) {
auto temp_lc = translator_.OffsetToLineCol(reference.target);
if (!temp_lc.has_value() && translator_.IsValid(temp_lc.value()))
if (!temp_lc.has_value() || !translator_.IsValid(temp_lc.value()))
return false;
*out_lc = temp_lc.value();
......
......@@ -54,6 +54,9 @@ class TargetPool {
// this class.
offset_t OffsetForKey(key_t key) const { return targets_[key]; }
// Returns whether a particular key is valid.
bool KeyIsValid(key_t key) const { return key < targets_.size(); }
// Uses |offset_mapper| to transform "old" |targets_| to "new" |targets_|,
// resulting in sorted and unique targets.
void FilterAndProject(const OffsetMapper& offset_mapper);
......
......@@ -151,6 +151,11 @@ bool ApplyReferencesCorrection(ExecutableType exe_type,
LOG(ERROR) << "Error reading reference_delta";
return false;
}
const key_t key = expected_key + delta.value();
if (!targets.KeyIsValid(key)) {
LOG(ERROR) << "Invalid reference_delta";
return false;
}
ref->target = targets.OffsetForKey(expected_key + delta.value());
ref->location =
ref->location - equivalence->src_offset + equivalence->dst_offset;
......
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