Fixed bug found by fuzzing.
Thanks to OSS-Fuzz for finding the bug.
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=6468
diff --git a/src/bloaty.cc b/src/bloaty.cc
index 9887529..025f5be 100644
--- a/src/bloaty.cc
+++ b/src/bloaty.cc
@@ -874,10 +874,10 @@
uint64_t debug_vmaddr = -1;
uint64_t debug_fileoff = -1;
-bool RangeSink::ContainsVerboseVMAddr(uint64_t vmstart, uint64_t vmsize) {
+bool RangeSink::ContainsVerboseVMAddr(uint64_t vmaddr, uint64_t vmsize) {
return options_.verbose_level() > 2 ||
- (options_.has_debug_vmaddr() && options_.debug_vmaddr() >= vmstart &&
- options_.debug_vmaddr() < (vmstart + vmsize));
+ (options_.has_debug_vmaddr() && options_.debug_vmaddr() >= vmaddr &&
+ options_.debug_vmaddr() < (vmaddr + vmsize));
}
bool RangeSink::ContainsVerboseFileOffset(uint64_t fileoff, uint64_t filesize) {
@@ -886,12 +886,16 @@
options_.debug_fileoff() < (fileoff + filesize));
}
-bool RangeSink::IsVerboseForVMRange(uint64_t vmstart, uint64_t vmsize) {
+bool RangeSink::IsVerboseForVMRange(uint64_t vmaddr, uint64_t vmsize) {
if (vmsize == RangeMap::kUnknownSize) {
- vmsize = UINT64_MAX - vmstart;
+ vmsize = UINT64_MAX - vmaddr;
}
- if (ContainsVerboseVMAddr(vmstart, vmsize)) {
+ if (vmaddr + vmsize < vmaddr) {
+ THROWF("Overflow in vm range, vmaddr=$0, vmsize=$1", vmaddr, vmsize);
+ }
+
+ if (ContainsVerboseVMAddr(vmaddr, vmsize)) {
return true;
}
@@ -899,7 +903,7 @@
RangeMap vm_map;
RangeMap file_map;
bool contains = false;
- vm_map.AddRangeWithTranslation(vmstart, vmsize, "", translator_->vm_map,
+ vm_map.AddRangeWithTranslation(vmaddr, vmsize, "", translator_->vm_map,
false, &file_map);
file_map.ForEachRange(
[this, &contains](uint64_t fileoff, uint64_t filesize) {
@@ -918,6 +922,11 @@
filesize = UINT64_MAX - fileoff;
}
+ if (fileoff + filesize < fileoff) {
+ THROWF("Overflow in file range, fileoff=$0, filesize=$1", fileoff,
+ filesize);
+ }
+
if (ContainsVerboseFileOffset(fileoff, filesize)) {
return true;
}
@@ -928,8 +937,8 @@
bool contains = false;
file_map.AddRangeWithTranslation(fileoff, filesize, "",
translator_->file_map, false, &vm_map);
- vm_map.ForEachRange([this, &contains](uint64_t vmstart, uint64_t vmsize) {
- if (ContainsVerboseVMAddr(vmstart, vmsize)) {
+ vm_map.ForEachRange([this, &contains](uint64_t vmaddr, uint64_t vmsize) {
+ if (ContainsVerboseVMAddr(vmaddr, vmsize)) {
contains = true;
}
});
@@ -1074,15 +1083,6 @@
}
}
- if (vmaddr + vmsize < vmaddr) {
- THROWF("Overflow in vm range, vmaddr=$0, vmsize=$1", vmaddr, vmsize);
- }
-
- if (fileoff + filesize < fileoff) {
- THROWF("Overflow in file range, fileoff=$0, filesize=$1", fileoff,
- filesize);
- }
-
for (auto& pair : outputs_) {
const std::string label = pair.second->Munge(name);
uint64_t common = std::min(vmsize, filesize);
diff --git a/src/bloaty.h b/src/bloaty.h
index 60a99f4..8f6f8e3 100644
--- a/src/bloaty.h
+++ b/src/bloaty.h
@@ -230,9 +230,9 @@
return ptr >= file_data.data() && ptr < file_data.data() + file_data.size();
}
- bool ContainsVerboseVMAddr(uint64_t vmstart, uint64_t vmsize);
+ bool ContainsVerboseVMAddr(uint64_t vmaddr, uint64_t vmsize);
bool ContainsVerboseFileOffset(uint64_t fileoff, uint64_t filesize);
- bool IsVerboseForVMRange(uint64_t vmstart, uint64_t vmsize);
+ bool IsVerboseForVMRange(uint64_t vmaddr, uint64_t vmsize);
bool IsVerboseForFileRange(uint64_t fileoff, uint64_t filesize);
const InputFile* file_;
diff --git a/tests/testdata/fuzz_corpus/37209ceacf21ce2796c98824dc9be60b876274a2 b/tests/testdata/fuzz_corpus/37209ceacf21ce2796c98824dc9be60b876274a2
new file mode 100644
index 0000000..6f49440
--- /dev/null
+++ b/tests/testdata/fuzz_corpus/37209ceacf21ce2796c98824dc9be60b876274a2
Binary files differ