Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/interchainstaking: Keeper.UpdateWithdrawalRecordsForSlash should validate that each Distribution.Valoper's amount is positive before additions otherwise an overflow can trigger wrong results #607

Closed
1 of 3 tasks
odeke-em opened this issue Sep 16, 2023 · 1 comment · Fixed by #789
Assignees

Comments

@odeke-em
Copy link
Contributor

Summary of Bug

This code

newAmount := sdk.NewDec(int64(d.Amount)).Quo(delta).TruncateInt()
thisSubAmount := sdkmath.NewInt(int64(d.Amount)).Sub(newAmount)
blindly creates an sdk.NewInt(int64(d.Amount)) then performs operations on it assuming the result will always be positive! Same as in
record.Amount = record.Amount.Sub(sdk.NewCoin(zone.BaseDenom, recordSubAmount))

Firstly let's note that WithdrawalRecord.Distribution[].Amount is a uint64 per

If someone wanted to control how much money was to be withdrawn they could intercept traffic or maliciously set a large to be sent into amount that's larger than int64 (given .Amount is a uint64) and that would cause a negative value which could then when subtracted from record.Amount cause a large value or any value of the attacker's choosing

Suggestion

dAmount := sdk.NewDec(int64(d.Amount))
if dAmount.IsNegative() {
    // TODO: Log or report or punish for this serious overflow
    continue
}

then also for

record.Amount = record.Amount.Sub(sdk.NewCoin(zone.BaseDenom, recordSubAmount))
we could do

deductedTotal := record.Amount.Sub(sdk.NewCoin(zone.BaseDenom, recordSubAmount))
if deductedTotal.GTE(record.Amount) {
    // TODO: Log or report or punish for this serious overflow
    return false
}

record.Distribution = distr
record.Amount = deductedTotal
k.SetWithdrawalRecord(ctx, record)

Version

13bf586

/cc @elias-orijtech


For Admin Use

  • Not duplicate issue
  • Appropriate labels applied
  • Appropriate contributors tagged/assigned
@ThanhNhann
Copy link
Contributor

ThanhNhann commented Sep 19, 2023

I see this code is updated WithdrawalRecords for the slashing when the validator jailed so I think the result will always be positive
cc: @joe-bowman

@joe-bowman joe-bowman self-assigned this Nov 18, 2023
faddat pushed a commit that referenced this issue Dec 10, 2023
* fix: defensive checks in UpdateWithdrawalRecordsForSlash; add tests; fixes #607

* remove debug lines

* lint
joe-bowman pushed a commit that referenced this issue Dec 27, 2023
* add improved supply queries

* make supply endpoint config

* fix: improve performance of lsm share token validation; fixes #787

* fix: defensive checks in UpdateWithdrawalRecordsForSlash; add tests; fixes #607

* lint

* lint

* bump depdendencies; remove hanging reference to lsm types

* fixes

* tools: use xbuild for release builds

* tools: bump go/alpine

* tools: makefile build tags

* tools: bump hermes to v1.7.4

* fix: further lint fixes

* fix error response on no validator found

* upgrade: add v1.4.5-rc2 upgrade handler
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 a pull request may close this issue.

3 participants