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

fix: add a limit of number of bytes while scale decoding a slice #3733

Merged
merged 8 commits into from
Feb 12, 2024

Conversation

kishansagathiya
Copy link
Contributor

While scale decoding we first read the length of bytes to decode and then we decode that many bytes.

Someone could ask us to decode some malicious bytes such that the read length is unreasonably big. In such case, we would have to create a byte slice as big as the length. So, we would either panic because of makeslice: len out of range or because the asked length would be more than the memory we have available in our machine.

Both of these are the situations we don't want. Hence, I have put a limit on decodable bytes (maxDecodableBytes), 16MB. I have kept it 16MB because for the usecase of polkadot specs, we would never need to decode a bigger set of bytes.

Changes

Tests

go test -tags integration github.com/ChainSafe/gossamer

Issues

Fixes #3476

Primary Reviewer

@timwu20 @EclesioMeloJunior

While scale decoding we first read the length of bytes to decode and
then we decode that many bytes.

Someone could ask us to decode some malicious bytes such that the read
length is unreasonably big. In such case, we would have to create a byte
slice as big as the length. So, we would either panic because
of `makeslice: len out of range` or because the asked length would be
more than the memory we have available in our machine.

Both of these are the situations we don't want. Hence, I have put a
limit on decodable bytes (maxDecodableBytes), 16MB. I have kept it 16MB
because for the usecase of polkadot specs, we would never need to decode
a bigger set of bytes.
Copy link
Member

@EclesioMeloJunior EclesioMeloJunior left a comment

Choose a reason for hiding this comment

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

LGTM!

pkg/scale/decode.go Outdated Show resolved Hide resolved
pkg/scale/decode.go Outdated Show resolved Hide resolved
@kishansagathiya kishansagathiya merged commit 5edbf89 into development Feb 12, 2024
23 checks passed
@kishansagathiya kishansagathiya deleted the kishan/fix/panic-unmarshalling branch February 12, 2024 14:13
github-actions bot pushed a commit that referenced this pull request Mar 1, 2024
# [0.9.0](v0.8.0...v0.9.0) (2024-3-1)

### Bug Fixes

* add a limit of number of bytes while scale decoding a slice ([#3733](#3733)) ([5edbf89](5edbf89))
* **docs:** Fixing link to polkadot runtime fundamentals to the right one ([#3763](#3763)) ([a785d32](a785d32))
* don't panic if we fail to convert hex to bytes ([#3734](#3734)) ([12234de](12234de))
* **dot/sync:** execute p2p handshake when there is no target ([#3695](#3695)) ([a9db0ec](a9db0ec))
* fix index out of range undeterministic error in rpc test ([#3718](#3718)) ([d099384](d099384))
* fix non deterministic  panic during TestStableNetworkRPC integration test ([#3756](#3756)) ([ee3d243](ee3d243))
* **lib/trie:** use `MustBeHashed` for V1 trie nodes with larger storage values ([#3739](#3739)) ([f5e48a9](f5e48a9))
* **mocks:** Set fixed version for uber mockgen in CI ([#3656](#3656)) ([ea9877e](ea9877e))
* **runtime/storage:** support nested storage transactions ([#3670](#3670)) ([3e99f6d](3e99f6d))
* segfault on node restart ([#3736](#3736)) ([d1ca7aa](d1ca7aa))
* **state-version:** should be uint8 instead of uint32 ([#3779](#3779)) ([c8fdb14](c8fdb14))
* update paseo chain spec ([#3770](#3770)) ([6a54f28](6a54f28))
* use last finalized block on startup ([#3737](#3737)) ([c262642](c262642))

### Features

* **config:** dynamically set version based on environment ([#3693](#3693)) ([5c534c9](5c534c9))
* **staging:** Expose RPC on Westend Staging Node ([#3687](#3687)) ([c374eaa](c374eaa))
* **tests/scripts:** create script to retrieve trie state via rpc ([#3714](#3714)) ([5ccea40](5ccea40))
Copy link

github-actions bot commented Mar 1, 2024

🎉 This PR is included in version 0.9.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

timwu20 pushed a commit that referenced this pull request Apr 18, 2024
While scale decoding we first read the length of bytes to decode and
then we decode that many bytes.

Someone could ask us to decode some malicious bytes such that the read
length is unreasonably big. In such case, we would have to create a byte
slice as big as the length. The length in byte slice is an encoded as `Compact<u32>`. 

Current we are just reading length as uint and not checking if it goes beyond the bounds of uint32.
So, we would either panic because of `makeslice: len out of range` or because the asked length would be
more than the memory we have available in our machine.

We are going to put a check to makes sure that this length is less than max of uint32.
timwu20 pushed a commit that referenced this pull request Apr 19, 2024
While scale decoding we first read the length of bytes to decode and
then we decode that many bytes.

Someone could ask us to decode some malicious bytes such that the read
length is unreasonably big. In such case, we would have to create a byte
slice as big as the length. The length in byte slice is an encoded as `Compact<u32>`. 

Current we are just reading length as uint and not checking if it goes beyond the bounds of uint32.
So, we would either panic because of `makeslice: len out of range` or because the asked length would be
more than the memory we have available in our machine.

We are going to put a check to makes sure that this length is less than max of uint32.
timwu20 pushed a commit that referenced this pull request Apr 19, 2024
# [0.9.0](v0.8.0...v0.9.0) (2024-3-1)

### Bug Fixes

* add a limit of number of bytes while scale decoding a slice ([#3733](#3733)) ([5edbf89](5edbf89))
* **docs:** Fixing link to polkadot runtime fundamentals to the right one ([#3763](#3763)) ([a785d32](a785d32))
* don't panic if we fail to convert hex to bytes ([#3734](#3734)) ([12234de](12234de))
* **dot/sync:** execute p2p handshake when there is no target ([#3695](#3695)) ([a9db0ec](a9db0ec))
* fix index out of range undeterministic error in rpc test ([#3718](#3718)) ([d099384](d099384))
* fix non deterministic  panic during TestStableNetworkRPC integration test ([#3756](#3756)) ([ee3d243](ee3d243))
* **lib/trie:** use `MustBeHashed` for V1 trie nodes with larger storage values ([#3739](#3739)) ([f5e48a9](f5e48a9))
* **mocks:** Set fixed version for uber mockgen in CI ([#3656](#3656)) ([ea9877e](ea9877e))
* **runtime/storage:** support nested storage transactions ([#3670](#3670)) ([3e99f6d](3e99f6d))
* segfault on node restart ([#3736](#3736)) ([d1ca7aa](d1ca7aa))
* **state-version:** should be uint8 instead of uint32 ([#3779](#3779)) ([c8fdb14](c8fdb14))
* update paseo chain spec ([#3770](#3770)) ([6a54f28](6a54f28))
* use last finalized block on startup ([#3737](#3737)) ([c262642](c262642))

### Features

* **config:** dynamically set version based on environment ([#3693](#3693)) ([5c534c9](5c534c9))
* **staging:** Expose RPC on Westend Staging Node ([#3687](#3687)) ([c374eaa](c374eaa))
* **tests/scripts:** create script to retrieve trie state via rpc ([#3714](#3714)) ([5ccea40](5ccea40))
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.

Panic “len out of range” while Unmarshaling Scale leading to a denial of service (DoS)
4 participants