mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-09-14 21:53:52 +00:00
Detect backsteps correctly in base path detection
Avoid false positives with atomic writer ..<timestamp> directories
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
@@ -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), "../")
|
||||
}
|
||||
|
@@ -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 {
|
||||
|
@@ -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)
|
||||
}
|
||||
|
||||
|
@@ -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 {
|
||||
|
Reference in New Issue
Block a user