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

Harry/9 #12

Merged
merged 4 commits into from
Feb 23, 2021
Merged

Harry/9 #12

merged 4 commits into from
Feb 23, 2021

Conversation

hwh33
Copy link
Contributor

@hwh33 hwh33 commented Feb 18, 2021

Fixes a couple of bugs related to the newly introduced server signals.

  • [ x ] Do the tests pass? Consistently?
  • [ x ] Did this change improve test coverage?
  • Has it been reviewed/approved by relevant teammates?
  • [ x ] Can it be QA’d in staging or something like staging?
  • [ x ] Is the code in question being linted? If not, consider adding a linter step to CI. If yes, make sure the linter is happy.
  • [ x ] Do we know how we’re going to deploy this?
  • [ x ] Are we clear on what the support and maintenance impact is?
  • [ x ] Did you create new documentation? Is it accessible and in the right place?
  • [ x ] Has existing documentation been updated?
  • [ x ] Have you logged tickets for related technical debt with the label “techdebt”?

@hwh33 hwh33 mentioned this pull request Feb 18, 2021
1 task
ptlshs/signal.go Outdated
// The server signal is made to look like the response. The maximum payload size for supported
// cipher suites is in the range of 1151 to 1187 bytes. We cap the server signal below this
// range to avoid complications from split records.
minSignalLenServer, maxSignalLenServer = 250, 1150
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was the source of one of the bugs. When server signals were > 1150 bytes, they were sometimes split into multiple records. The client code assumes server signals will arrive in a single record. We could implement a length header into the server signal and piece it together from multiple records, but this was a simpler fix and seems acceptable to me.

ptlshs/signal.go Outdated
actualMinSignalLenServer = rand.Intn(maxSignalLenServer - minSignalLenServer - serverSignalLenSpread)
rand.Seed(time.Now().UnixNano())
randSpread := maxSignalLenServer - minSignalLenServer - serverSignalLenSpread
actualMinSignalLenServer = rand.Intn(randSpread) + minSignalLenServer
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was an arithmetic mistake and the source of the second bug. We were allowing server signals less than minSignalLenServer which confused clients. This bug was masked in tests because math/rand is deterministic when not seeded - which I didn't realize!

The determinism in math/rand actually defeated the randomization of server signal lengths across runtimes, effectively a third bug. We are now properly seeding. This will also help in testing as we have a few tests in ptlshs which fuzz data using math/rand.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, good catch! I think it's a general practice to use crypto/rand instead of math/rand for stuff that's even remotely security related, so maybe worth switching to that?

Copy link
Contributor Author

@hwh33 hwh33 Feb 19, 2021

Choose a reason for hiding this comment

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

math/rand is only used here to randomize lengths (and crypto/rand doesn't have API for random integers anyway). In testing, it's also used just to randomize lengths. The only case in this package which actually uses random data is in the nonce, which indeed uses crypto/rand.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh btw, rand.Seed is global, and some other code might change the seed (or maybe even clear it?). To be safe, you should probably make a new local random.

https://golang.org/pkg/math/rand/#New

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right - will change, thanks

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@oxtoacart I realized that creating a new local random for all uses of math/rand would be a bit cumbersome. A shared, package-internal one would need to be protected against concurrent access (the underlying rand.Source would not be directly safe for concurrent access).

I also did some more reading about using math/rand for generating simple integers like this. This thread was particularly insightful. There were quite a few comments which echoed your point that we should just always use crypto/rand, even for simple integer generation (for example, this comment).

So I am convinced, and I will switch over to crypto/rand for everything in this repo. Thanks for the pointer and the great conversation on Slack. Sorry it took me so long to come around!

Copy link
Contributor Author

@hwh33 hwh33 Feb 19, 2021

Choose a reason for hiding this comment

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

As an aside, that thread I linked also has some great discussion on some of the math/rand design decisions which you and I talked about.

This thread is only tangentially related, but also interesting!

Copy link
Contributor Author

@hwh33 hwh33 Feb 19, 2021

Choose a reason for hiding this comment

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

@hwh33 hwh33 requested a review from oxtoacart February 18, 2021 07:07
@@ -15,7 +15,7 @@ jobs:
name: Test
# We have a lot of concurrency and synchronization in this library. Test with -race and
# -count=1000 to expose any timing related bugs.
command: go test -race -count=1000 ./...
command: go test -race -count=1000 -v ./...
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@hwh33
Copy link
Contributor Author

hwh33 commented Feb 23, 2021

Thanks @oxtoacart!

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.

2 participants