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

Guard against race conditions in RegisterAlgorithm #62

Merged
merged 4 commits into from May 4, 2022

Conversation

qmuntal
Copy link
Contributor

@qmuntal qmuntal commented May 3, 2022

NCC Group reported a race condition in RegisterAlgorithm:

The registration is performed through a global map. There is no mutex protection:
concurrent accesses from several distinct threads (“goroutines”) may lead to adverse
effects, including multiple registration of an algorithm, apparent removal of an existing
registration, or a panic due to an out-of-bounds memory access
is expected to apply its own locking to ensure that no other thread may access the
library (including for merely verifying a signature) while any thread is performing a
registration; however, this aspect is entirely undocumented

This PR fix the race condition.

@SteveLasker @shizhMSFT

@SteveLasker
Copy link
Contributor

@qmuntal, can you fix the merge conflict from the other pr that just merged?

Copy link
Contributor

@thomas-fossati thomas-fossati left a comment

Choose a reason for hiding this comment

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

👍

Signed-off-by: qmuntal <qmuntaldiaz@microsoft.com>
Signed-off-by: qmuntal <qmuntaldiaz@microsoft.com>
Signed-off-by: qmuntal <qmuntaldiaz@microsoft.com>
Signed-off-by: qmuntal <qmuntaldiaz@microsoft.com>
@qmuntal
Copy link
Contributor Author

qmuntal commented May 4, 2022

@qmuntal, can you fix the merge conflict from the other pr that just merged?

Done!

@@ -161,10 +169,13 @@ func (a Algorithm) computeHash(data []byte) ([]byte, error) {
// set to 0, no hash is used for this algorithm.
// The parameter `hashFunc` is preferred in the case that the hash algorithm is not
// supported by the golang built-in crypto hashes.
// It is safe for concurrent use by multiple goroutines.
Copy link
Contributor

Choose a reason for hiding this comment

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

Changes looks good! Just a side question.

Should we not allow user to De-Register an External Algorithm and add a new one. I do not see any API like that?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure if we should allow deregistering algorithms. I would rather wait until someone ask for it, so we understand which is the use case.

Copy link
Contributor

@yogeshbdeshpande yogeshbdeshpande left a comment

Choose a reason for hiding this comment

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

LGTM!

@SteveLasker SteveLasker merged commit c605080 into veraison:main May 4, 2022
Comment on lines +71 to +74
var (
extAlgorithms map[Algorithm]extAlgorithm
extMu sync.RWMutex
)
Copy link
Contributor

Choose a reason for hiding this comment

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

@qmuntal I think sync.Map is a better option than a map with a mutex.

Copy link
Contributor

Choose a reason for hiding this comment

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

can we open another issue to account for this proposal?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@qmuntal I think sync.Map is a better option than a map with a mutex.

I tend to avoid using sync.Map due to this comment in its docs:

The Map type is specialized. Most code should use a plain Go map instead, with separate locking or coordination, for better type safety and to make it easier to maintain other invariants along with the map content.

But I agree that a sync.Map could also be used here and I wouldn't complain.

Copy link
Contributor

Choose a reason for hiding this comment

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

Currently, there is no other invariants along with the map content. Well, it is a trade-off: readability and performance.

Using a plain map with a RWMutex is faster than sync.Map. Let's keep this PR unchanged.

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

5 participants