MM-30319: Fix race in ensureAsymmetricSigningKey (#16354)

A cluster changed listener always runs in a separate goroutine.
This causes a race condition when a new member gets added in the cluster.

We fix it by accessing the value atomically.

I tried to write a test for this, but it wasn't triggering at all.
The best way is to just start the server with cluster enabled in race mode,
and verify that the race doesn't happen.

https://mattermost.atlassian.net/browse/MM-30319

```release-notes
NONE
```
Этот коммит содержится в:
Agniva De Sarker
2020-11-23 19:18:24 +05:30
коммит произвёл GitHub
родитель d28e7ec870
Коммит d9e8402dc2
2 изменённых файлов: 11 добавлений и 9 удалений

Просмотреть файл

@@ -164,7 +164,7 @@ func (s *Server) ensurePostActionCookieSecret() error {
// ensureAsymmetricSigningKey ensures that an asymmetric signing key exists and future calls to
// AsymmetricSigningKey will always return a valid signing key.
func (s *Server) ensureAsymmetricSigningKey() error {
if s.asymmetricSigningKey != nil {
if s.AsymmetricSigningKey() != nil {
return nil
}
@@ -227,14 +227,14 @@ func (s *Server) ensureAsymmetricSigningKey() error {
default:
return fmt.Errorf("unknown curve: " + key.ECDSAKey.Curve)
}
s.asymmetricSigningKey = &ecdsa.PrivateKey{
s.asymmetricSigningKey.Store(&ecdsa.PrivateKey{
PublicKey: ecdsa.PublicKey{
Curve: curve,
X: key.ECDSAKey.X,
Y: key.ECDSAKey.Y,
},
D: key.ECDSAKey.D,
}
})
s.regenerateClientConfig()
return nil
}
@@ -279,7 +279,10 @@ func (s *Server) ensureFirstServerRunTimestamp() error {
// AsymmetricSigningKey will return a private key that can be used for asymmetric signing.
func (s *Server) AsymmetricSigningKey() *ecdsa.PrivateKey {
return s.asymmetricSigningKey
if key := s.asymmetricSigningKey.Load(); key != nil {
return key.(*ecdsa.PrivateKey)
}
return nil
}
func (a *App) AsymmetricSigningKey() *ecdsa.PrivateKey {