{static_,}range_map: fix overflows under ubsan

Explicitly call out where overflows are expected, and add appropriate
checking for them.

BUG=b:235999011
TEST=Unittests on CrOS and Linux

Change-Id: I999a6996183c2f4afc16a1c0188dee3bd64d7f09
Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/3759630
Reviewed-by: Mike Frysinger <vapier@chromium.org>
This commit is contained in:
George Burgess IV 2022-07-12 21:35:52 -07:00 committed by George Burgess
parent eb087c3383
commit 335e61656f
8 changed files with 242 additions and 15 deletions

View file

@ -39,6 +39,7 @@
#include <assert.h>
#include "common/safe_math.h"
#include "processor/range_map.h"
#include "processor/linked_ptr.h"
#include "processor/logging.h"
@ -57,10 +58,15 @@ template<typename AddressType, typename EntryType>
bool RangeMap<AddressType, EntryType>::StoreRangeInternal(
const AddressType& base, const AddressType& delta,
const AddressType& size, const EntryType& entry) {
AddressType high = base + (size - 1);
AddressType high;
bool high_ok = false;
if (size > 0) {
std::pair<AddressType, bool> result = AddWithOverflowCheck(base, size - 1);
high = result.first;
high_ok = !result.second;
}
// Check for undersize or overflow.
if (size <= 0 || high < base) {
if (!high_ok) {
// The processor will hit this case too frequently with common symbol
// files in the size == 0 case, which is more suited to a DEBUG channel.
// Filter those out since there's no DEBUG channel at the moment.

View file

@ -43,11 +43,10 @@
namespace {
using google_breakpad::AddIgnoringOverflow;
using google_breakpad::linked_ptr;
using google_breakpad::scoped_ptr;
using google_breakpad::RangeMap;
using google_breakpad::scoped_ptr;
// A CountedObject holds an int. A global (not thread safe!) count of
// allocated CountedObjects is maintained to help test memory management.
@ -148,10 +147,10 @@ static bool RetrieveTest(TestMap* range_map, const RangeTest* range_test) {
}
for (AddressType offset = low_offset; offset <= high_offset; ++offset) {
AddressType address =
offset +
(!side ? range_test->address :
range_test->address + range_test->size - 1);
AddressType address = AddIgnoringOverflow(
offset, (!side ? range_test->address
: AddIgnoringOverflow(range_test->address,
range_test->size - 1)));
bool expected_result = false; // This is correct for tests not stored.
if (range_test->expect_storable) {

View file

@ -228,10 +228,10 @@ void TestStaticRangeMap::RetrieveTest(TestMap* range_map,
}
for (AddressType offset = low_offset; offset <= high_offset; ++offset) {
AddressType address =
offset +
(!side ? range_test->address :
range_test->address + range_test->size - 1);
AddressType address = AddIgnoringOverflow(
offset, (!side ? range_test->address
: AddIgnoringOverflow(range_test->address,
range_test->size - 1)));
bool expected_result = false; // This is correct for tests not stored.
if (range_test->expect_storable) {