100 lines
3.3 KiB
Diff
100 lines
3.3 KiB
Diff
From 75d53c469ea6115db0386155262565a8aa15556d Mon Sep 17 00:00:00 2001
|
|
From: jingrui <jingrui@huawei.com>
|
|
Date: Thu, 3 Jan 2019 16:04:37 +0800
|
|
Subject: [PATCH 044/111] plugin: Fix plugin security bug caused by
|
|
unchecked plugin name
|
|
|
|
reason: cherry-pick commits to docker-18.09
|
|
|
|
cherry-pick from 48c9622f82 | * plugin,bugfix: Fix plugin security bug
|
|
caused by unchecked plugin name
|
|
|
|
Docker may activate plugins outside plugin directory if plugin name
|
|
contains string like "../../". This patch fix this bug by checking the
|
|
combined plugin path before use it.
|
|
|
|
fix issue docker/docker#268
|
|
|
|
Change-Id: Icff8b24e50fc92721149267bc8c29a8652046d8a
|
|
Signed-off-by: majiuyue <majiuyue@huawei.com>
|
|
Signed-off-by: jingrui <jingrui@huawei.com>
|
|
---
|
|
components/engine/pkg/plugins/discovery.go | 27 ++++++++++++++++------
|
|
components/engine/pkg/plugins/plugins.go | 2 +-
|
|
2 files changed, 21 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/components/engine/pkg/plugins/discovery.go b/components/engine/pkg/plugins/discovery.go
|
|
index 4b79bd29ad..51f1d8ebea 100644
|
|
--- a/components/engine/pkg/plugins/discovery.go
|
|
+++ b/components/engine/pkg/plugins/discovery.go
|
|
@@ -14,6 +14,8 @@ import (
|
|
)
|
|
|
|
var (
|
|
+ // ErrForbidden plugin sock/spec outside allowed location
|
|
+ ErrForbidden = errors.New("plugin outside allowed location")
|
|
// ErrNotFound plugin not found
|
|
ErrNotFound = errors.New("plugin not found")
|
|
socketsPath = "/run/docker/plugins"
|
|
@@ -82,7 +84,10 @@ func Scan() ([]string, error) {
|
|
|
|
// Plugin returns the plugin registered with the given name (or returns an error).
|
|
func (l *localRegistry) Plugin(name string) (*Plugin, error) {
|
|
- socketpaths := pluginPaths(socketsPath, name, ".sock")
|
|
+ socketpaths, err := pluginPaths(socketsPath, name, ".sock")
|
|
+ if err != nil {
|
|
+ return nil, ErrForbidden
|
|
+ }
|
|
|
|
for _, p := range socketpaths {
|
|
if fi, err := os.Stat(p); err == nil && fi.Mode()&os.ModeSocket != 0 {
|
|
@@ -92,8 +97,10 @@ func (l *localRegistry) Plugin(name string) (*Plugin, error) {
|
|
|
|
var txtspecpaths []string
|
|
for _, p := range specsPaths {
|
|
- txtspecpaths = append(txtspecpaths, pluginPaths(p, name, ".spec")...)
|
|
- txtspecpaths = append(txtspecpaths, pluginPaths(p, name, ".json")...)
|
|
+ for _, ext := range []string{".spec", ".json"} {
|
|
+ paths, _ := pluginPaths(p, name, ext)
|
|
+ txtspecpaths = append(txtspecpaths, paths...)
|
|
+ }
|
|
}
|
|
|
|
for _, p := range txtspecpaths {
|
|
@@ -146,9 +153,15 @@ func readPluginJSONInfo(name, path string) (*Plugin, error) {
|
|
return &p, nil
|
|
}
|
|
|
|
-func pluginPaths(base, name, ext string) []string {
|
|
- return []string{
|
|
- filepath.Join(base, name+ext),
|
|
- filepath.Join(base, name, name+ext),
|
|
+func pluginPaths(base, name, ext string) ([]string, error) {
|
|
+ paths := []string{
|
|
+ filepath.Clean(filepath.Join(base, name+ext)),
|
|
+ filepath.Clean(filepath.Join(base, name, name+ext)),
|
|
+ }
|
|
+ for _, p := range paths {
|
|
+ if !strings.HasPrefix(p, base) {
|
|
+ return nil, ErrForbidden
|
|
+ }
|
|
}
|
|
+ return paths, nil
|
|
}
|
|
diff --git a/components/engine/pkg/plugins/plugins.go b/components/engine/pkg/plugins/plugins.go
|
|
index 6962079df9..8a6fbeda29 100644
|
|
--- a/components/engine/pkg/plugins/plugins.go
|
|
+++ b/components/engine/pkg/plugins/plugins.go
|
|
@@ -208,7 +208,7 @@ func loadWithRetry(name string, retry bool) (*Plugin, error) {
|
|
for {
|
|
pl, err := registry.Plugin(name)
|
|
if err != nil {
|
|
- if !retry {
|
|
+ if !retry || err == ErrForbidden {
|
|
return nil, err
|
|
}
|
|
|
|
--
|
|
2.17.1
|
|
|