Merge bitcoin/bitcoin#32300: feefrac: avoid integer overflow in temporary
Some checks are pending
CI / Windows native, fuzz, VS 2022 (push) Waiting to run
CI / Linux->Windows cross, no tests (push) Waiting to run
CI / Windows, test cross-built (push) Blocked by required conditions
CI / ASan + LSan + UBSan + integer, no depends, USDT (push) Waiting to run
CI / test each commit (push) Waiting to run
CI / macOS 14 native, arm64, no depends, sqlite only, gui (push) Waiting to run
CI / macOS 14 native, arm64, fuzz (push) Waiting to run
CI / Windows native, VS 2022 (push) Waiting to run

5cb1241814 feefrac: avoid integer overflow in temporary (Pieter Wuille)

Pull request description:

  In `FeeFrac::Div(__int128 n, int32_t d, bool round_down)` in src/util/feefrac.h, the following line computes the result:

  ```c++
          return quot + (mod > 0) - (mod && round_down);
  ```

  The function can only be called under conditions where the result is in range, and thus doesn't involve any integer overflow. However, the intermediary result computed by just `quot + (mod > 0)` may still overflow if it's going to be corrected by the `- (mod && round_down)` that follows.

  Fix this by balancing the two correction steps with each other first:
  ```c++
          return quot + ((mod > 0) - (mod && round_down));
  ```

  Fixes #32294.

ACKs for top commit:
  l0rinc:
    Tested ACK 5cb1241814
  maflcko:
    lgtm ACK 5cb1241814
  achow101:
    ACK 5cb1241814

Tree-SHA512: 9daaccdf9acd7652d53b52cad2dc12872558265e863acdde2d6015f885cb87c0505f9bd5be5499fc0a0eded29bec719643f6af1fbc3604518143985094226c95
This commit is contained in:
Ava Chow 2025-04-18 15:34:04 -07:00
commit 055254e212
No known key found for this signature in database
GPG key ID: 17565732E08E5E41
2 changed files with 3 additions and 1 deletions

View file

@ -148,6 +148,8 @@ BOOST_AUTO_TEST_CASE(feefrac_operators)
FeeFrac max_fee2{1, 1};
BOOST_CHECK(max_fee >= max_fee2);
// Test for integer overflow issue (https://github.com/bitcoin/bitcoin/issues/32294)
BOOST_CHECK_EQUAL((FeeFrac{0x7ffffffdfffffffb, 0x7ffffffd}.EvaluateFeeDown(0x7fffffff)), 0x7fffffffffffffff);
}
BOOST_AUTO_TEST_SUITE_END()

View file

@ -96,7 +96,7 @@ struct FeeFrac
int64_t quot = n / d;
int32_t mod = n % d;
// Correct result if the / operator above rounded in the wrong direction.
return quot + (mod > 0) - (mod && round_down);
return quot + ((mod > 0) - (mod && round_down));
}
#else
static constexpr auto Mul = MulFallback;