From 83f77d5a5f198dd97217b46e13082f893727e64e Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Tue, 31 Oct 2017 20:58:45 -0500 Subject: [PATCH 1/5] Fix memory leak when a connection would hit the cluster port and go away (#3513) --- vault/request_forwarding.go | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/vault/request_forwarding.go b/vault/request_forwarding.go index 8635281d0f21..13dbcdeb6970 100644 --- a/vault/request_forwarding.go +++ b/vault/request_forwarding.go @@ -122,11 +122,10 @@ func (c *Core) startForwarding() error { // Accept the connection conn, err := tlsLn.Accept() - if conn != nil { - // Always defer although it may be closed ahead of time - defer conn.Close() - } - if err != nil { + if err != nil || conn == nil { + if conn != nil { + conn.Close() + } continue } @@ -138,9 +137,7 @@ func (c *Core) startForwarding() error { if c.logger.IsDebug() { c.logger.Debug("core: error handshaking cluster connection", "error", err) } - if conn != nil { - conn.Close() - } + conn.Close() continue } @@ -153,10 +150,14 @@ func (c *Core) startForwarding() error { c.logger.Trace("core: got request forwarding connection") c.clusterParamsLock.RLock() - go fws.ServeConn(conn, &http2.ServeConnOpts{ - Handler: c.rpcServer, - }) + rpcServer := c.rpcServer c.clusterParamsLock.RUnlock() + go func() { + defer conn.Close() + fws.ServeConn(conn, &http2.ServeConnOpts{ + Handler: rpcServer, + }) + }() default: c.logger.Debug("core: unknown negotiated protocol on cluster port") From c9f01963c369d5748603baec08bfafdc99814b08 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Tue, 31 Oct 2017 21:59:33 -0400 Subject: [PATCH 2/5] changelog++ --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5268699864f..d6501097b87b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,8 @@ BUG FIXES: * api: Fix panic when setting a custom HTTP client but with a nil transport [GH-3437] * auth/radius: Fix logging in in some situations [GH-3461] + * core: Fix memleak when a connection would connect to the cluster port and + then go away [GH-3513] * physical/etcd3: Fix some listing issues due to how etcd3 does prefix matching [GH-3406] * physical/file: Fix listing when underscores are the first component of a From 6d3eb3f814886aa26a5c6e50aa1016babbcc5fc2 Mon Sep 17 00:00:00 2001 From: Vishal Nayak Date: Wed, 1 Nov 2017 14:14:21 -0400 Subject: [PATCH 3/5] fix deadlock while loading groups (#3515) --- vault/identity_store_util.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/vault/identity_store_util.go b/vault/identity_store_util.go index c9ea1eb06e96..0444bf6f8a50 100644 --- a/vault/identity_store_util.go +++ b/vault/identity_store_util.go @@ -60,6 +60,9 @@ func (i *IdentityStore) loadGroups() error { } i.logger.Debug("identity: groups collected", "num_existing", len(existing)) + i.groupLock.Lock() + defer i.groupLock.Unlock() + for _, key := range existing { bucket, err := i.groupPacker.GetBucket(i.groupPacker.BucketPath(key)) if err != nil { @@ -83,14 +86,11 @@ func (i *IdentityStore) loadGroups() error { i.logger.Trace("loading group", "name", group.Name, "id", group.ID) } - i.groupLock.Lock() - defer i.groupLock.Unlock() - txn := i.db.Txn(true) - defer txn.Abort() err = i.upsertGroupInTxn(txn, group, false) if err != nil { + txn.Abort() return fmt.Errorf("failed to update group in memdb: %v", err) } From 972834a61088c2363c1369dfaf5d34778aff3a88 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Wed, 1 Nov 2017 15:52:59 -0400 Subject: [PATCH 4/5] Use an atomic store in expiration loading test to fix race detector --- vault/token_store_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vault/token_store_test.go b/vault/token_store_test.go index efdefbbad9ea..1dd1e916c406 100644 --- a/vault/token_store_test.go +++ b/vault/token_store_test.go @@ -8,6 +8,7 @@ import ( "sort" "strings" "sync" + "sync/atomic" "testing" "time" @@ -567,7 +568,7 @@ func TestTokenStore_CreateLookup_ExpirationInRestoreMode(t *testing.T) { // Reset expiration manager to restore mode ts.expiration.restoreModeLock.Lock() - ts.expiration.restoreMode = 1 + atomic.StoreInt32(&ts.expiration.restoreMode, 1) ts.expiration.restoreLocks = locksutil.CreateLocks() ts.expiration.restoreModeLock.Unlock() From 962ef74cb26bc5128801279b80181243bb3d1ca0 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Wed, 1 Nov 2017 21:00:41 -0500 Subject: [PATCH 5/5] Add seal type to seal-status output. (#3516) --- api/sys_seal.go | 1 + command/status.go | 4 +++- http/sys_seal.go | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/api/sys_seal.go b/api/sys_seal.go index 97a49aeb4401..72fe06e8ed31 100644 --- a/api/sys_seal.go +++ b/api/sys_seal.go @@ -49,6 +49,7 @@ func sealStatusRequest(c *Sys, r *Request) (*SealStatusResponse, error) { } type SealStatusResponse struct { + Type string `json:"type"` Sealed bool `json:"sealed"` T int `json:"t"` N int `json:"n"` diff --git a/command/status.go b/command/status.go index 7b6cce348f3c..6b2f3a0a76a6 100644 --- a/command/status.go +++ b/command/status.go @@ -36,12 +36,14 @@ func (c *StatusCommand) Run(args []string) int { } outStr := fmt.Sprintf( - "Sealed: %v\n"+ + "Type: %s\n"+ + "Sealed: %v\n"+ "Key Shares: %d\n"+ "Key Threshold: %d\n"+ "Unseal Progress: %d\n"+ "Unseal Nonce: %v\n"+ "Version: %s", + sealStatus.Type, sealStatus.Sealed, sealStatus.N, sealStatus.T, diff --git a/http/sys_seal.go b/http/sys_seal.go index ef2430495ae8..4805e36de505 100644 --- a/http/sys_seal.go +++ b/http/sys_seal.go @@ -190,6 +190,7 @@ func handleSysSealStatusRaw(core *vault.Core, w http.ResponseWriter, r *http.Req progress, nonce := core.SecretProgress() respondOk(w, &SealStatusResponse{ + Type: sealConfig.Type, Sealed: sealed, T: sealConfig.SecretThreshold, N: sealConfig.SecretShares, @@ -202,6 +203,7 @@ func handleSysSealStatusRaw(core *vault.Core, w http.ResponseWriter, r *http.Req } type SealStatusResponse struct { + Type string `json:"type"` Sealed bool `json:"sealed"` T int `json:"t"` N int `json:"n"`