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

Stricter jörmungandr binary encoders regarding integer overflow #487

Merged
merged 3 commits into from
Jul 2, 2019

Conversation

Anviking
Copy link
Collaborator

@Anviking Anviking commented Jun 27, 2019

Issue Number

#219

Overview

  • I have replaced a few fromIntegral with toEnum where it might overflow.
  • I have adapted and slightly expanded the integration tests (separate commit)

Comments

  • Not all failures are covered by integration tests. They are all covered by the roundtrips in Jörmungandr binary roundtrips #476 though.
  • We could maybe introduce types prohibiting this, but 🤷‍♂ (that might be a rabbit hole and this is a first step in that case)

@Anviking Anviking self-assigned this Jun 27, 2019
@Anviking Anviking force-pushed the anviking/219/stricter-encoders branch 2 times, most recently from b71a503 to 91da4fb Compare June 27, 2019 09:35
@Anviking Anviking force-pushed the anviking/219/stricter-encoders branch from 91da4fb to d2f8138 Compare June 27, 2019 10:06
Copy link
Member

@KtorZ KtorZ left a comment

Choose a reason for hiding this comment

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

The original idea is good, but its implementation needs revisions:

It will be sufficient and give us the same level of guarantees as this PR to use toEnum instead of fromIntegral for unsafe conversions. Conversions is unsafe when the codomain is smaller than the domain.

lib/jormungandr/src/Cardano/Wallet/Jormungandr/Binary.hs Outdated Show resolved Hide resolved
unless (length inputs < 256) $
fail "number of inputs must be lower than 256"
unless (length outputs < 256) $
fail "number of outputs must be lower than 256"
Copy link
Member

Choose a reason for hiding this comment

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

Instead of magic number, it'd be better to use maxBound @Word8 to show where this 256 comes from.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done:

    unless (length inputs <= fromIntegral (maxBound :: Word8)) $
        fail "number of inputs cannot be greater than 255"
  • maxBound :: Word8 is 255 so I've used 255] instead of 256) as bound
  • Preserved the 255 in the message despite the risk of going out of sync
  • Avoided to state the entire allowed range, e.g. number of inputs must be within the range [0,255], since I believe the 0 is a grey-zone.

lib/jormungandr/src/Cardano/Wallet/Jormungandr/Binary.hs Outdated Show resolved Hide resolved
lib/jormungandr/src/Cardano/Wallet/Jormungandr/Binary.hs Outdated Show resolved Hide resolved
lib/jormungandr/src/Cardano/Wallet/Jormungandr/Binary.hs Outdated Show resolved Hide resolved
putWord8 $ fromIntegral $ length inputs
putWord8 $ fromIntegral $ length outputs
putWord8 $ overflowSafeCoerce $ length inputs
putWord8 $ overflowSafeCoerce $ length outputs
Copy link
Member

Choose a reason for hiding this comment

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

We should either check the length with unless or with overflowSafeCoerce. Doing both is overkill.

lib/jormungandr/src/Cardano/Wallet/Jormungandr/Binary.hs Outdated Show resolved Hide resolved
lib/jormungandr/src/Cardano/Wallet/Jormungandr/Binary.hs Outdated Show resolved Hide resolved
@Anviking Anviking removed the request for review from jonathanknowles June 27, 2019 14:26
Copy link
Contributor

@rvl rvl left a comment

Choose a reason for hiding this comment

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

Integer type promotions in the deserialisation (Get) shouldn't be too much of a problem. (Unless there are values which cause us to allocate an excessively large amount of memory).

But it's good to add checks in the serialisation (Put) before squeezing values into 8 bits - as you have done.

I am wondering what we should do about the error handling here. Should transactions with >= 255 inputs or outputs be rejected at the API level, or should we wait for serialisation to fail and return that error? I think the latter is OK, as long as it's clear to the user why the error happens.

lib/jormungandr/src/Cardano/Wallet/Jormungandr/Binary.hs Outdated Show resolved Hide resolved
@KtorZ
Copy link
Member

KtorZ commented Jul 1, 2019

I am wondering what we should do about the error handling here. Should transactions with >= 255 inputs or outputs be rejected at the API level, or should we wait for serialisation to fail and return that error? I think the latter is OK, as long as it's clear to the user why the error happens.

We will most likely never create a transaction with more than 255 inputs, because of the way our CS work. So it's unlikely that such transaction would make it to being serialized. Having said that, I'd be more inclined to catch the erroneous transaction much earlier and avoid creating it in a first place. Failures in the Binary module should really be our last-resort / safety net; being the sign that something went wrong in the upper layers.

@Anviking Anviking force-pushed the anviking/219/stricter-encoders branch 5 times, most recently from c1ecfd0 to aa8851a Compare July 1, 2019 15:05
@Anviking
Copy link
Collaborator Author

Anviking commented Jul 1, 2019

New approach:

  • Default to using fromIntegral as before where we deem it safe.
  • Only otherwise use toEnum

@Anviking Anviking requested a review from KtorZ July 1, 2019 15:22
- Particulary in encoders (putX)
- Somewhat for decoders (getX)
and add a test case for unbalanced transactions
@Anviking Anviking force-pushed the anviking/219/stricter-encoders branch from aa8851a to b399323 Compare July 1, 2019 16:16
@KtorZ KtorZ merged commit 5d67169 into master Jul 2, 2019
@Anviking Anviking deleted the anviking/219/stricter-encoders branch July 2, 2019 13:12
@KtorZ KtorZ mentioned this pull request Jul 3, 2019
12 tasks
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.

None yet

3 participants