Browse Source

authz: eliminate race during plugin removal from middleware

Also, this removes the use of a questionable golang range feature which
corrects for mutation of a slice during iteration over that slice. This
makes the filter operation easier to read and reason about.

Signed-off-by: David Sheets <dsheets@docker.com>
David Sheets 8 years ago
parent
commit
7da3986297
2 changed files with 14 additions and 8 deletions
  1. 13 0
      pkg/authorization/middleware.go
  2. 1 8
      plugin/backend_linux.go

+ 13 - 0
pkg/authorization/middleware.go

@@ -46,6 +46,19 @@ func (m *Middleware) SetPlugins(names []string) {
 	m.mu.Unlock()
 }
 
+// RemovePlugin removes a single plugin from this authz middleware chain
+func (m *Middleware) RemovePlugin(name string) {
+	m.mu.Lock()
+	defer m.mu.Unlock()
+	plugins := m.plugins[:0]
+	for _, authPlugin := range m.plugins {
+		if authPlugin.Name() != name {
+			plugins = append(plugins, authPlugin)
+		}
+	}
+	m.plugins = plugins
+}
+
 // WrapHandler returns a new handler function wrapping the previous one in the request chain.
 func (m *Middleware) WrapHandler(handler func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error) func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
 	return func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {

+ 1 - 8
plugin/backend_linux.go

@@ -60,14 +60,7 @@ func (pm *Manager) Disable(refOrID string, config *types.PluginDisableConfig) er
 
 	for _, typ := range p.GetTypes() {
 		if typ.Capability == authorization.AuthZApiImplements {
-			authzList := pm.config.AuthzMiddleware.GetAuthzPlugins()
-			for i, authPlugin := range authzList {
-				if authPlugin.Name() == p.Name() {
-					// Remove plugin from authzmiddleware chain
-					authzList = append(authzList[:i], authzList[i+1:]...)
-					pm.config.AuthzMiddleware.SetAuthzPlugins(authzList)
-				}
-			}
+			pm.config.AuthzMiddleware.RemovePlugin(p.Name())
 		}
 	}