Skip to content

Commit 0043375

Browse files
committed
resources: support PVC sub paths deeper than one level
There does not seem to be a technical limitation for doing this, other than complexity involving path validation. This uses a defense-in-depth approach with an (admittedly somewhat complex) regex to prevent path escapes, coupled with a manual bounds check if the CR is applied without validation.
1 parent 6628483 commit 0043375

2 files changed

Lines changed: 12 additions & 4 deletions

File tree

api/v1alpha1/smbshare_types.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ type SmbSharePvcSpec struct {
101101
Spec *corev1.PersistentVolumeClaimSpec `json:"spec,omitempty"`
102102

103103
// Path within the PVC which should be exported.
104-
// +kubebuilder:validation:Pattern=`^[^\/]+$`
104+
// Must be a relative path. Path traversal ("..") is not allowed.
105+
// +kubebuilder:validation:Pattern=`^(?:(?!\.\.)(?!\.$)[^/]+)(?:/(?!\.\.)(?!\.$)[^/]+)*$`
105106
// +optional
106107
Path string `json:"path,omitempty"`
107108
}

internal/planner/paths.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package planner
1818
import (
1919
"fmt"
2020
"path"
21+
"strings"
2122
)
2223

2324
// Paths for relevant files and dirs within the containers.
@@ -44,10 +45,16 @@ func (p *Paths) ShareMountPath() string {
4445
// Share path.
4546
func (p *Paths) Share() string {
4647
sharepath := p.planner.SmbShare.Spec.Storage.Pvc.Path
47-
if sharepath != "" {
48-
return path.Join(p.ShareMountPath(), "/", sharepath)
48+
if sharepath == "" {
49+
return p.ShareMountPath()
4950
}
50-
return p.ShareMountPath()
51+
mountPath := p.ShareMountPath()
52+
joined := path.Join(mountPath, sharepath)
53+
// Ensure the resolved path stays within the mount path
54+
if !strings.HasPrefix(joined, mountPath+"/") && joined != mountPath {
55+
return mountPath
56+
}
57+
return joined
5158
}
5259

5360
// ContainerConfigs returns a slice containing all configuration

0 commit comments

Comments
 (0)