Detect backsteps correctly in base path detection

Avoid false positives with atomic writer ..<timestamp> directories
This commit is contained in:
Jordan Liggitt
2018-03-13 00:59:40 -04:00
parent a7d6340ad2
commit 3fafdb7001
5 changed files with 20 additions and 16 deletions

View File

@@ -19,8 +19,6 @@ package util
import (
"fmt"
"net/url"
"path/filepath"
"strings"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
@@ -47,14 +45,3 @@ func parseEndpoint(endpoint string) (string, string, error) {
return u.Scheme, "", fmt.Errorf("protocol %q not supported", u.Scheme)
}
}
func pathWithinBase(fullPath, basePath string) bool {
rel, err := filepath.Rel(basePath, fullPath)
if err != nil {
return false
}
if strings.HasPrefix(rel, "..") {
return false
}
return true
}

View File

@@ -325,9 +325,15 @@ func pathWithinBase(fullPath, basePath string) bool {
if err != nil {
return false
}
if strings.HasPrefix(rel, "..") {
if startsWithBackstep(rel) {
// Needed to escape the base path
return false
}
return true
}
// startsWithBackstep checks if the given path starts with a backstep segment
func startsWithBackstep(rel string) bool {
// normalize to / and check for ../
return rel == ".." || strings.HasPrefix(filepath.ToSlash(rel), "../")
}

View File

@@ -402,6 +402,12 @@ func TestPathWithinBase(t *testing.T) {
basePath: "/a",
expected: false,
},
{
name: "configmap subpath",
fullPath: "/var/lib/kubelet/pods/uuid/volumes/kubernetes.io~configmap/config/..timestamp/file.txt",
basePath: "/var/lib/kubelet/pods/uuid/volumes/kubernetes.io~configmap/config",
expected: true,
},
}
for _, test := range tests {
if pathWithinBase(test.fullPath, test.basePath) != test.expected {

View File

@@ -291,7 +291,7 @@ func lockAndCheckSubPathWithoutSymlink(volumePath, subPath string) ([]uintptr, e
if err != nil {
return []uintptr{}, fmt.Errorf("Rel(%s, %s) error: %v", volumePath, subPath, err)
}
if strings.HasPrefix(relSubPath, "..") {
if startsWithBackstep(relSubPath) {
return []uintptr{}, fmt.Errorf("SubPath %q not within volume path %q", subPath, volumePath)
}
@@ -552,7 +552,7 @@ func findExistingPrefix(base, pathname string) (string, []string, error) {
return base, nil, err
}
if strings.HasPrefix(rel, "..") {
if startsWithBackstep(rel) {
return base, nil, fmt.Errorf("pathname(%s) is not within base(%s)", pathname, base)
}

View File

@@ -538,6 +538,11 @@ func TestPathWithinBase(t *testing.T) {
basePath: `c:\tmp\a\b\c`,
expectedResult: false,
},
{
fullPath: `c:\kubelet\pods\uuid\volumes\kubernetes.io~configmap\config\..timestamp\file.txt`,
basePath: `c:\kubelet\pods\uuid\volumes\kubernetes.io~configmap\config`,
expectedResult: true,
},
}
for _, test := range tests {