Skip to content

fix: resolve signed integer overflow UB in CoinJoin priority and timeout#7236

Draft
thepastaclaw wants to merge 1 commit intodashpay:developfrom
thepastaclaw:fix-coinjoin-ub
Draft

fix: resolve signed integer overflow UB in CoinJoin priority and timeout#7236
thepastaclaw wants to merge 1 commit intodashpay:developfrom
thepastaclaw:fix-coinjoin-ub

Conversation

@thepastaclaw
Copy link

Summary

Fix two signed integer overflow UB issues in CoinJoin code, found during fuzz testing.

CalculateAmountPriority (common.h)

The return type is int but the computation -(nInputAmount / COIN) operates on
int64_t values. When nInputAmount is extremely large (e.g. near MAX_MONEY),
the result exceeds INT_MAX and the implicit narrowing to int is undefined
behavior under UBSan.

Fix: Clamp the int64_t result to [INT_MIN, INT_MAX] before returning.
This preserves the existing sort ordering for all realistic inputs while making
extreme values well-defined.

IsTimeOutOfBounds (coinjoin.cpp)

The expression current_time - nTime overflows when the two int64_t values
differ by more than INT64_MAX (e.g. one large positive, one large negative).

Fix: Compute the absolute difference using unsigned arithmetic, which is
well-defined for all inputs.

Validation

  • Both functions are non-consensus (CoinJoin sort priority and queue timeout only)
  • Neither overflow is exploitable — CoinJoin queue entries require valid MN signatures,
    and the priority function only affects local sort order
  • The fixes preserve identical behavior for all realistic inputs
  • Found via UBSan-instrumented fuzz testing on the ci/fuzz-regression branch

@thepastaclaw
Copy link
Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Mar 18, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions
Copy link

github-actions bot commented Mar 18, 2026

⚠️ Potential Merge Conflicts Detected

This PR has potential conflicts with the following open PRs:

Please coordinate with the authors of these PRs to avoid merge conflicts.

@coderabbitai
Copy link

coderabbitai bot commented Mar 18, 2026

Walkthrough

The pull request contains two safety and optimization improvements to the coinjoin module. The first change simplifies timeout validation in IsTimeOutOfBounds by replacing a two-branch conditional check with a single unsigned difference computation that checks if the absolute difference between timestamps exceeds the threshold. The second change adds overflow prevention to CalculateAmountPriority by using std::clamp to constrain the computed value within valid integer range before casting. Both changes are localized modifications with no alterations to function signatures or public APIs.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and accurately summarizes the main change: fixing signed integer overflow undefined behavior in CoinJoin priority and timeout functions.
Description check ✅ Passed The description is directly related to the changeset, providing detailed context about the two UB fixes, their causes, solutions, and validation rationale.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/coinjoin/coinjoin.cpp`:
- Around line 57-61: Run clang-format on the indicated block (or the whole file)
to fix the whitespace/line-wrapping so the ternary expression and return
statement match project style; reformat the block containing current_time, nTime
and COINJOIN_QUEUE_TIMEOUT (the diff calculation and return) using your
project's clang-format config and commit the changes so the Clang Diff Format
Check passes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 82b1eff3-1f1e-4510-a19f-8c06e26a762b

📥 Commits

Reviewing files that changed from the base of the PR and between 1d212a1 and 4248612.

📒 Files selected for processing (2)
  • src/coinjoin/coinjoin.cpp
  • src/coinjoin/common.h

Comment on lines 57 to +61
{
return current_time - nTime > COINJOIN_QUEUE_TIMEOUT ||
nTime - current_time > COINJOIN_QUEUE_TIMEOUT;
const uint64_t diff = (current_time > nTime)
? static_cast<uint64_t>(current_time) - static_cast<uint64_t>(nTime)
: static_cast<uint64_t>(nTime) - static_cast<uint64_t>(current_time);
return diff > static_cast<uint64_t>(COINJOIN_QUEUE_TIMEOUT);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Run clang-format on this block to unblock CI.

The pipeline reports formatting differences at Line 57 in this function. Please apply clang-format to this region/file so the Clang Diff Format Check passes.

🧰 Tools
🪛 GitHub Actions: Clang Diff Format Check

[error] 57-57: Clang format differences detected in this file. Please run clang-format to fix formatting issues as shown by the diff.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/coinjoin/coinjoin.cpp` around lines 57 - 61, Run clang-format on the
indicated block (or the whole file) to fix the whitespace/line-wrapping so the
ternary expression and return statement match project style; reformat the block
containing current_time, nTime and COINJOIN_QUEUE_TIMEOUT (the diff calculation
and return) using your project's clang-format config and commit the changes so
the Clang Diff Format Check passes.

CalculateAmountPriority in common.h could overflow when assigning a
negated int64_t division result to an int return type with extreme
CAmount values. Clamp the result to INT_MIN/INT_MAX before returning.

IsTimeOutOfBounds in coinjoin.cpp could overflow on signed subtraction
when current_time and nTime differ by more than INT64_MAX. Use unsigned
arithmetic to compute the absolute difference safely.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant