From edd3b14ddf049048e5d6bd952677133237adb652 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Thu, 19 Dec 2024 16:29:40 -0500 Subject: [PATCH] LibCrypto: Protect the SignedBigInteger ctor against integer overflow In particular, if given a value of -2147483648, we would invoke signed integer overflow (which is UB). --- Libraries/LibCrypto/BigInt/SignedBigInteger.h | 2 +- Tests/LibCrypto/TestBigInteger.cpp | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Libraries/LibCrypto/BigInt/SignedBigInteger.h b/Libraries/LibCrypto/BigInt/SignedBigInteger.h index 1a61e310994..a410da22d09 100644 --- a/Libraries/LibCrypto/BigInt/SignedBigInteger.h +++ b/Libraries/LibCrypto/BigInt/SignedBigInteger.h @@ -21,7 +21,7 @@ public: requires(sizeof(T) <= sizeof(i32)) SignedBigInteger(T value) : m_sign(value < 0) - , m_unsigned_data(abs(static_cast(value))) + , m_unsigned_data(static_cast(abs(static_cast(value)))) { } diff --git a/Tests/LibCrypto/TestBigInteger.cpp b/Tests/LibCrypto/TestBigInteger.cpp index 0165bcbbd1d..c87f90c4d3a 100644 --- a/Tests/LibCrypto/TestBigInteger.cpp +++ b/Tests/LibCrypto/TestBigInteger.cpp @@ -698,6 +698,17 @@ TEST_CASE(test_negative_zero_is_not_allowed) EXPECT(!zero.is_negative()); } +TEST_CASE(test_i32_limits) +{ + Crypto::SignedBigInteger min { AK::NumericLimits::min() }; + EXPECT(min.is_negative()); + EXPECT(min.unsigned_value().to_u64() == static_cast(AK::NumericLimits::max()) + 1); + + Crypto::SignedBigInteger max { AK::NumericLimits::max() }; + EXPECT(!max.is_negative()); + EXPECT(max.unsigned_value().to_u64() == AK::NumericLimits::max()); +} + TEST_CASE(double_comparisons) { #define EXPECT_LESS_THAN(bigint, double_value) EXPECT_EQ(bigint.compare_to_double(double_value), Crypto::UnsignedBigInteger::CompareResult::DoubleGreaterThanBigInt)