docker/patch/0044-plugin-Fix-plugin-security-bug-caused-by-unch.patch

100 lines
3.3 KiB
Diff
Raw Normal View History

2019-09-30 10:37:25 -04:00
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