Skip to content

Commit

Permalink
fix: decrement types.Dec max length to keep decimal bits in DecimalPr…
Browse files Browse the repository at this point in the history
…ecisionBits (#11772)

## Description

Closes: #11732

As found by OSS-Fuzz, large numbers may overflow the current maxDecBitLen because
it assumes that DecimalPrecisionBits (60) can always be represented by Precision (18)
base-10 digits. Since 2^60 is larger than 2^18, this assumption is false.

This change fixes #11732 by only allowing 59 bits of precision on top of the 256
maxBitLen allowed for the integer part.

---

### Author Checklist

*All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.*

I have...

- [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [x] added `!` to the type prefix if API or client breaking change
- [x] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/main/CONTRIBUTING.md#pr-targeting))
- [x] provided a link to the relevant issue or specification
- [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/main/docs/building-modules)
- [x] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/main/CONTRIBUTING.md#testing)
- [ ] added a changelog entry to `CHANGELOG.md`
- [ ] included comments for [documenting Go code](https://blog.golang.org/godoc)
- [x] updated the relevant documentation or specification
- [x] reviewed "Files changed" and left comments if necessary
- [ ] confirmed all CI checks have passed

### Reviewers Checklist

*All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.*

I have...

- [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] confirmed `!` in the type prefix if API or client breaking change
- [ ] confirmed all author checklist items have been addressed
- [ ] reviewed state machine logic
- [ ] reviewed API design and naming
- [ ] reviewed documentation is accurate
- [ ] reviewed tests and test coverage
- [ ] manually tested (if applicable)

(cherry picked from commit f9913c1)

# Conflicts:
#	CHANGELOG.md
  • Loading branch information
elias-orijtech authored and mergify[bot] committed Apr 27, 2022
1 parent c405df4 commit 9b05b53
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 15 deletions.
39 changes: 39 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,45 @@ Ref: https://keepachangelog.com/en/1.0.0/

### Improvements

<<<<<<< HEAD
=======
* [\#11696](https://github.com/cosmos/cosmos-sdk/pull/11696) Rename `helpers.GenTx` to `GenSignedMockTx` to avoid confusion with genutil's `GenTxCmd`.
* (x/auth/vesting) [\#11652](https://github.com/cosmos/cosmos-sdk/pull/11652) Add util functions for `Period(s)`
* [\#11630](https://github.com/cosmos/cosmos-sdk/pull/11630) Add SafeSub method to sdk.Coin.
* [\#11511](https://github.com/cosmos/cosmos-sdk/pull/11511) Add api server flags to start command.
* [\#11484](https://github.com/cosmos/cosmos-sdk/pull/11484) Implement getter for keyring backend option.
* [\#11449](https://github.com/cosmos/cosmos-sdk/pull/11449) Improved error messages when node isn't synced.
* [\#11349](https://github.com/cosmos/cosmos-sdk/pull/11349) Add `RegisterAminoMsg` function that checks that a msg name is <40 chars (else this would break ledger nano signing) then registers the concrete msg type with amino, it should be used for registering `sdk.Msg`s with amino instead of `cdc.RegisterConcrete`.
* [\#11089](https://github.com/cosmos/cosmos-sdk/pull/11089]) Now cosmos-sdk consumers can upgrade gRPC to its newest versions.
* [\#10439](https://github.com/cosmos/cosmos-sdk/pull/10439) Check error for `RegisterQueryHandlerClient` in all modules `RegisterGRPCGatewayRoutes`.
* [\#9780](https://github.com/cosmos/cosmos-sdk/pull/9780) Remove gogoproto `moretags` YAML annotations and add `sigs.k8s.io/yaml` for YAML marshalling.
* (x/bank) [\#10134](https://github.com/cosmos/cosmos-sdk/pull/10134) Add `HasDenomMetadata` function to bank `Keeper` to check if a client coin denom metadata exists in state.
* (x/bank) [\#10022](https://github.com/cosmos/cosmos-sdk/pull/10022) `BankKeeper.SendCoins` now takes less execution time.
* (deps) [\#9987](https://github.com/cosmos/cosmos-sdk/pull/9987) Bump Go version minimum requirement to `1.17`
* (cli) [\#9856](https://github.com/cosmos/cosmos-sdk/pull/9856) Overwrite `--sequence` and `--account-number` flags with default flag values when used with `offline=false` in `sign-batch` command.
* (rosetta) [\#10001](https://github.com/cosmos/cosmos-sdk/issues/10001) Add documentation for rosetta-cli dockerfile and rename folder for the rosetta-ci dockerfile
* [\#9699](https://github.com/cosmos/cosmos-sdk/pull/9699) Add `:`, `.`, `-`, and `_` as allowed characters in the default denom regular expression.
* (genesis) [\#9697](https://github.com/cosmos/cosmos-sdk/pull/9697) Ensure `InitGenesis` returns with non-empty validator set.
* [\#10341](https://github.com/cosmos/cosmos-sdk/pull/10341) Move from `io/ioutil` to `io` and `os` packages.
* [\#10468](https://github.com/cosmos/cosmos-sdk/pull/10468) Allow futureOps to queue additional operations in simulations
* [\#10625](https://github.com/cosmos/cosmos-sdk/pull/10625) Add `--fee-payer` CLI flag
* (cli) [\#10683](https://github.com/cosmos/cosmos-sdk/pull/10683) In CLI, allow 1 SIGN_MODE_DIRECT signer in transactions with multiple signers.
* (deps) [\#10210](https://github.com/cosmos/cosmos-sdk/pull/10210) Bump Tendermint to [v0.35.0](https://github.com/tendermint/tendermint/releases/tag/v0.35.0).
* (deps) [\#10706](https://github.com/cosmos/cosmos-sdk/issues/10706) Bump rosetta-sdk-go to v0.7.2 and rosetta-cli to v0.7.3
* (types/errors) [\#10779](https://github.com/cosmos/cosmos-sdk/pull/10779) Move most functionality in `types/errors` to a standalone `errors` go module, except the `RootCodespace` errors and ABCI response helpers. All functions and types that used to live in `types/errors` are now aliased so this is not a breaking change.
* (gov) [\#10854](https://github.com/cosmos/cosmos-sdk/pull/10854) v1beta2's vote doesn't include the deprecate `option VoteOption` anymore. Instead, it only uses `WeightedVoteOption`.
* (types) [\#11004](https://github.com/cosmos/cosmos-sdk/pull/11004) Added mutable versions of many of the sdk.Dec types operations. This improves performance when used by avoiding reallocating a new bigint for each operation.
* (x/auth) [\#10880](https://github.com/cosmos/cosmos-sdk/pull/10880) Added a new query to the tx query service that returns a block with transactions fully decoded.
* (types) [\#11200](https://github.com/cosmos/cosmos-sdk/pull/11200) Added `Min()` and `Max()` operations on sdk.Coins.
* (gov) [\#11287](https://github.com/cosmos/cosmos-sdk/pull/11287) Fix error message when no flags are provided while executing `submit-legacy-proposal` transaction.
* (x/auth) [\#11482](https://github.com/cosmos/cosmos-sdk/pull/11482) Improve panic message when attempting to register a method handler for a message that does not implement sdk.Msg
* (x/staking) [\#11596](https://github.com/cosmos/cosmos-sdk/pull/11596) Add (re)delegation getters

### Bug Fixes

* [\#11772](https://github.com/cosmos/cosmos-sdk/pull/11772) Limit types.Dec length to avoid overflow.
* [\#11724](https://github.com/cosmos/cosmos-sdk/pull/11724) Fix data race issues with api.Server
>>>>>>> f9913c139 (fix: decrement types.Dec max length to keep decimal bits in DecimalPrecisionBits (#11772))
* [\#11693](https://github.com/cosmos/cosmos-sdk/pull/11693) Add validation for gentx cmd.
* [\#11686](https://github.com/cosmos/cosmos-sdk/pull/11686) Update the min required Golang version to `1.17`.
* (x/auth/vesting) [\#11652](https://github.com/cosmos/cosmos-sdk/pull/11652) Add util functions for `Period(s)`
Expand Down
1 change: 1 addition & 0 deletions types/coin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -751,6 +751,7 @@ func (s *coinTestSuite) TestParseCoins() {
{"10atom10", true, sdk.Coins{{"atom10", sdk.NewInt(10)}}},
{"200transfer/channelToA/uatom", true, sdk.Coins{{"transfer/channelToA/uatom", sdk.NewInt(200)}}},
{"50ibc/7F1D3FCF4AE79E1554D670D1AD949A9BA4E4A3C76C63093E17E446A46061A7A2", true, sdk.Coins{{"ibc/7F1D3FCF4AE79E1554D670D1AD949A9BA4E4A3C76C63093E17E446A46061A7A2", sdk.NewInt(50)}}},
{"120000000000000000000000000000000000000000000000000000000000000000000000000000btc", false, nil},
}

for tcIndex, tc := range cases {
Expand Down
11 changes: 8 additions & 3 deletions types/decimal.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,16 @@ const (
// number of decimal places
Precision = 18

// bytes required to represent the above precision
// Ceiling[Log2[999 999 999 999 999 999]]
// bits required to represent the above precision
// Ceiling[Log2[10^Precision - 1]]
DecimalPrecisionBits = 60

maxDecBitLen = maxBitLen + DecimalPrecisionBits
// decimalTruncateBits is the minimum number of bits removed
// by a truncate operation. It is equal to
// Floor[Log2[10^Precision - 1]].
decimalTruncateBits = DecimalPrecisionBits - 1

maxDecBitLen = maxBitLen + decimalTruncateBits

// max number of iterations in ApproxRoot function
maxApproxRootIterations = 100
Expand Down
35 changes: 23 additions & 12 deletions types/decimal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"math/big"
"strings"
"testing"

"github.com/stretchr/testify/suite"
Expand Down Expand Up @@ -33,10 +34,10 @@ func (s *decimalTestSuite) TestNewDecFromStr() {
largeBigInt, ok := new(big.Int).SetString("3144605511029693144278234343371835", 10)
s.Require().True(ok)

largerBigInt, ok := new(big.Int).SetString("88888888888888888888888888888888888888888888888888888888888888888888844444440", 10)
largerBigInt, ok := new(big.Int).SetString("8888888888888888888888888888888888888888888888888888888888888888888844444440", 10)
s.Require().True(ok)

largestBigInt, ok := new(big.Int).SetString("133499189745056880149688856635597007162669032647290798121690100488888732861290034376435130433535", 10)
largestBigInt, ok := new(big.Int).SetString("33499189745056880149688856635597007162669032647290798121690100488888732861290034376435130433535", 10)
s.Require().True(ok)

tests := []struct {
Expand All @@ -63,8 +64,8 @@ func (s *decimalTestSuite) TestNewDecFromStr() {
{"foobar", true, sdk.Dec{}},
{"0.foobar", true, sdk.Dec{}},
{"0.foobar.", true, sdk.Dec{}},
{"88888888888888888888888888888888888888888888888888888888888888888888844444440", false, sdk.NewDecFromBigInt(largerBigInt)},
{"133499189745056880149688856635597007162669032647290798121690100488888732861290.034376435130433535", false, sdk.NewDecFromBigIntWithPrec(largestBigInt, 18)},
{"8888888888888888888888888888888888888888888888888888888888888888888844444440", false, sdk.NewDecFromBigInt(largerBigInt)},
{"33499189745056880149688856635597007162669032647290798121690100488888732861290.034376435130433535", false, sdk.NewDecFromBigIntWithPrec(largestBigInt, 18)},
{"133499189745056880149688856635597007162669032647290798121690100488888732861291", true, sdk.Dec{}},
}

Expand Down Expand Up @@ -449,10 +450,14 @@ func (s *decimalTestSuite) TestDecSortableBytes() {
}

func (s *decimalTestSuite) TestDecEncoding() {
largestBigInt, ok := new(big.Int).SetString("133499189745056880149688856635597007162669032647290798121690100488888732861290034376435130433535", 10)
largestBigInt, ok := new(big.Int).SetString("33499189745056880149688856635597007162669032647290798121690100488888732861290034376435130433535", 10)
s.Require().True(ok)

smallestBigInt, ok := new(big.Int).SetString("-133499189745056880149688856635597007162669032647290798121690100488888732861290034376435130433535", 10)
smallestBigInt, ok := new(big.Int).SetString("-33499189745056880149688856635597007162669032647290798121690100488888732861290034376435130433535", 10)
s.Require().True(ok)

const maxDecBitLen = 315
maxInt, ok := new(big.Int).SetString(strings.Repeat("1", maxDecBitLen), 2)
s.Require().True(ok)

testCases := []struct {
Expand Down Expand Up @@ -492,15 +497,21 @@ func (s *decimalTestSuite) TestDecEncoding() {
},
{
sdk.NewDecFromBigIntWithPrec(largestBigInt, 18),
"313333343939313839373435303536383830313439363838383536363335353937303037313632363639303332363437323930373938313231363930313030343838383838373332383631323930303334333736343335313330343333353335",
"\"133499189745056880149688856635597007162669032647290798121690100488888732861290.034376435130433535\"",
"\"133499189745056880149688856635597007162669032647290798121690100488888732861290.034376435130433535\"\n",
"3333343939313839373435303536383830313439363838383536363335353937303037313632363639303332363437323930373938313231363930313030343838383838373332383631323930303334333736343335313330343333353335",
"\"33499189745056880149688856635597007162669032647290798121690100488888732861290.034376435130433535\"",
"\"33499189745056880149688856635597007162669032647290798121690100488888732861290.034376435130433535\"\n",
},
{
sdk.NewDecFromBigIntWithPrec(smallestBigInt, 18),
"2D313333343939313839373435303536383830313439363838383536363335353937303037313632363639303332363437323930373938313231363930313030343838383838373332383631323930303334333736343335313330343333353335",
"\"-133499189745056880149688856635597007162669032647290798121690100488888732861290.034376435130433535\"",
"\"-133499189745056880149688856635597007162669032647290798121690100488888732861290.034376435130433535\"\n",
"2D3333343939313839373435303536383830313439363838383536363335353937303037313632363639303332363437323930373938313231363930313030343838383838373332383631323930303334333736343335313330343333353335",
"\"-33499189745056880149688856635597007162669032647290798121690100488888732861290.034376435130433535\"",
"\"-33499189745056880149688856635597007162669032647290798121690100488888732861290.034376435130433535\"\n",
},
{
sdk.NewDecFromBigIntWithPrec(maxInt, 18),
"3636373439353934383732353238343430303734383434343238333137373938353033353831333334353136333233363435333939303630383435303530323434343434333636343330363435303137313838323137353635323136373637",
"\"66749594872528440074844428317798503581334516323645399060845050244444366430645.017188217565216767\"",
"\"66749594872528440074844428317798503581334516323645399060845050244444366430645.017188217565216767\"\n",
},
}

Expand Down

0 comments on commit 9b05b53

Please sign in to comment.