mirror of
https://git.suyu.dev/suyu/breakpad.git
synced 2026-01-07 06:58:20 +01:00
{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:
parent
eb087c3383
commit
335e61656f
8 changed files with 242 additions and 15 deletions
|
|
@ -163,6 +163,7 @@
|
|||
'memory_range.h',
|
||||
'module.cc',
|
||||
'module.h',
|
||||
'safe_math.h',
|
||||
'scoped_ptr.h',
|
||||
'simple_string_dictionary.cc',
|
||||
'simple_string_dictionary.h',
|
||||
|
|
@ -233,6 +234,7 @@
|
|||
'memory_allocator_unittest.cc',
|
||||
'memory_range_unittest.cc',
|
||||
'module_unittest.cc',
|
||||
'safe_math_unittest.cc',
|
||||
'simple_string_dictionary_unittest.cc',
|
||||
'stabs_reader_unittest.cc',
|
||||
'stabs_to_module_unittest.cc',
|
||||
|
|
|
|||
82
src/common/safe_math.h
Normal file
82
src/common/safe_math.h
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
// Copyright (c) 2022, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// safe_math.h: Helpful math functions.
|
||||
#ifndef SAFE_MATH_H__
|
||||
#define SAFE_MATH_H__
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace google_breakpad {
|
||||
|
||||
// Adds `a` and `b`, returning a pair of:
|
||||
// - The result after any truncation.
|
||||
// - Whether an overflow/underflow occurred.
|
||||
template <typename T>
|
||||
std::pair<T, bool> AddWithOverflowCheck(T a, T b) {
|
||||
#ifdef _WIN32
|
||||
// Since C++11, unsigned overflow is well-defined; do everything unsigned,
|
||||
// assuming 2's complement.
|
||||
if (std::is_unsigned<T>::value) {
|
||||
T result = a + b;
|
||||
// Since we're adding two values >= 0, having a smaller value implies
|
||||
// overflow.
|
||||
bool overflow = result < a;
|
||||
return {result, overflow};
|
||||
}
|
||||
|
||||
using TUnsigned = typename std::make_unsigned<T>::type;
|
||||
T result = TUnsigned(a) + TUnsigned(b);
|
||||
bool overflow;
|
||||
if ((a >= 0) == (b >= 0)) {
|
||||
if (a >= 0) {
|
||||
overflow = result < a;
|
||||
} else {
|
||||
overflow = result > a;
|
||||
}
|
||||
} else {
|
||||
// If signs are different, it's impossible for overflow to happen.
|
||||
overflow = false;
|
||||
}
|
||||
return {result, overflow};
|
||||
#else
|
||||
T result;
|
||||
bool overflow = __builtin_add_overflow(a, b, &result);
|
||||
return {result, overflow};
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T AddIgnoringOverflow(T a, T b) {
|
||||
return AddWithOverflowCheck(a, b).first;
|
||||
}
|
||||
|
||||
} // namespace google_breakpad
|
||||
|
||||
#endif // SAFE_MATH_H__
|
||||
73
src/common/safe_math_unittest.cc
Normal file
73
src/common/safe_math_unittest.cc
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
// Copyright (c) 2022 Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// safe_math_unittest.cc: Unit tests for SafeMath
|
||||
|
||||
#include "safe_math.h"
|
||||
#include "breakpad_googletest_includes.h"
|
||||
|
||||
namespace {
|
||||
|
||||
using google_breakpad::AddIgnoringOverflow;
|
||||
using google_breakpad::AddWithOverflowCheck;
|
||||
|
||||
TEST(SafeMath, AddOverflowWorksAsIntended) {
|
||||
EXPECT_EQ(AddWithOverflowCheck<uint8_t>(0, 0),
|
||||
std::make_pair<uint8_t>(0, false));
|
||||
EXPECT_EQ(AddWithOverflowCheck<uint8_t>(0, 255),
|
||||
std::make_pair<uint8_t>(255, false));
|
||||
EXPECT_EQ(AddWithOverflowCheck<uint8_t>(1, 255),
|
||||
std::make_pair<uint8_t>(0, true));
|
||||
|
||||
EXPECT_EQ(AddWithOverflowCheck<int8_t>(-128, 127),
|
||||
std::make_pair<int8_t>(-1, false));
|
||||
EXPECT_EQ(AddWithOverflowCheck<int8_t>(127, -128),
|
||||
std::make_pair<int8_t>(-1, false));
|
||||
EXPECT_EQ(AddWithOverflowCheck<int8_t>(1, -128),
|
||||
std::make_pair<int8_t>(-127, false));
|
||||
EXPECT_EQ(AddWithOverflowCheck<int8_t>(127, -1),
|
||||
std::make_pair<int8_t>(126, false));
|
||||
|
||||
EXPECT_EQ(AddWithOverflowCheck<int8_t>(-128, -1),
|
||||
std::make_pair<int8_t>(127, true));
|
||||
EXPECT_EQ(AddWithOverflowCheck<int8_t>(-128, -128),
|
||||
std::make_pair<int8_t>(0, true));
|
||||
EXPECT_EQ(AddWithOverflowCheck<int8_t>(127, 1),
|
||||
std::make_pair<int8_t>(-128, true));
|
||||
EXPECT_EQ(AddWithOverflowCheck<int8_t>(127, 127),
|
||||
std::make_pair<int8_t>(-2, true));
|
||||
}
|
||||
|
||||
TEST(SafeMath, AddIgnoringOverflowWorksAsIntended) {
|
||||
EXPECT_EQ(AddIgnoringOverflow<uint8_t>(0, 0), 0);
|
||||
EXPECT_EQ(AddIgnoringOverflow<uint8_t>(0, 255), 255);
|
||||
EXPECT_EQ(AddIgnoringOverflow<uint8_t>(1, 255), 0);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
Loading…
Add table
Add a link
Reference in a new issue