From b1ad99edbfa1830a3e99a166a5a6cc16eb09b4ad Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Thu, 16 Jan 2020 01:35:30 -0800 Subject: [PATCH] fix: avoid crash copy map before reading (#8825) code of this form is always racy, when the map itself is being written to as well ``` func (r Map) retMap() map[string]string { .. lock .. return r.internalMap } func (r Map) addMap(k, v string) { .. lock .. r.internalMap[k] = v } ``` Anyone reading from `retMap()` is not protected because of locking and we need to make sure to avoid code in this manner. Always safe to copy the map and return. --- cmd/http-stats.go | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/cmd/http-stats.go b/cmd/http-stats.go index 432e20e7f..c431a9e22 100644 --- a/cmd/http-stats.go +++ b/cmd/http-stats.go @@ -95,7 +95,7 @@ func newConnStats() *ConnStats { // HTTPAPIStats holds statistics information about // a given API in the requests. type HTTPAPIStats struct { - APIStats map[string]int + apiStats map[string]int sync.RWMutex } @@ -106,14 +106,14 @@ func (stats *HTTPAPIStats) Inc(api string) { if stats == nil { return } - if stats.APIStats == nil { - stats.APIStats = make(map[string]int) + if stats.apiStats == nil { + stats.apiStats = make(map[string]int) } - if _, ok := stats.APIStats[api]; ok { - stats.APIStats[api]++ + if _, ok := stats.apiStats[api]; ok { + stats.apiStats[api]++ return } - stats.APIStats[api] = 1 + stats.apiStats[api] = 1 } // Dec increments the api stats counter. @@ -123,8 +123,8 @@ func (stats *HTTPAPIStats) Dec(api string) { if stats == nil { return } - if val, ok := stats.APIStats[api]; ok && val > 0 { - stats.APIStats[api]-- + if val, ok := stats.apiStats[api]; ok && val > 0 { + stats.apiStats[api]-- } } @@ -132,7 +132,11 @@ func (stats *HTTPAPIStats) Dec(api string) { func (stats *HTTPAPIStats) Load() map[string]int { stats.Lock() defer stats.Unlock() - return stats.APIStats + var apiStats = make(map[string]int, len(stats.apiStats)) + for k, v := range stats.apiStats { + apiStats[k] = v + } + return apiStats } // HTTPStats holds statistics information about