Skip to content

Commit

Permalink
Merge pull request #47236 from dixudx/not_allow_backsteps_in_local_vo…
Browse files Browse the repository at this point in the history
…lume

Automatic merge from submit-queue (batch tested with PRs 34515, 47236, 46694, 47819, 47792)

not allow backsteps in local volume plugin

**Which issue this PR fixes** : fixes #47207

**Special notes for your reviewer**:
cc @msau42 @ddysher
Just follow @liggitt [commented](#47107 (comment)).

**Release note**:
```release-note
NONE
```
  • Loading branch information
Kubernetes Submit Queue committed Jun 21, 2017
2 parents 0a6d307 + aa23ed5 commit 1184ce8
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 8 deletions.
3 changes: 3 additions & 0 deletions pkg/api/validation/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -1133,7 +1133,10 @@ func validateLocalVolumeSource(ls *api.LocalVolumeSource, fldPath *field.Path) f
allErrs := field.ErrorList{}
if ls.Path == "" {
allErrs = append(allErrs, field.Required(fldPath.Child("path"), ""))
return allErrs
}

allErrs = append(allErrs, validatePathNoBacksteps(ls.Path, fldPath.Child("path"))...)
return allErrs
}

Expand Down
15 changes: 15 additions & 0 deletions pkg/api/validation/validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,21 @@ func TestValidatePersistentVolumes(t *testing.T) {
StorageClassName: "backstep-hostpath",
}),
},
"bad-local-volume-backsteps": {
isExpectedFailure: true,
volume: testVolume("foo", "", api.PersistentVolumeSpec{
Capacity: api.ResourceList{
api.ResourceName(api.ResourceStorage): resource.MustParse("10G"),
},
AccessModes: []api.PersistentVolumeAccessMode{api.ReadWriteOnce},
PersistentVolumeSource: api.PersistentVolumeSource{
Local: &api.LocalVolumeSource{
Path: "/foo/..",
},
},
StorageClassName: "backstep-local",
}),
},
}

for name, scenario := range scenarios {
Expand Down
1 change: 1 addition & 0 deletions pkg/volume/local/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ go_library(
"//pkg/util/strings:go_default_library",
"//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library",
"//pkg/volume/validation:go_default_library",
"//vendor/github.com/golang/glog:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
Expand Down
6 changes: 6 additions & 0 deletions pkg/volume/local/local.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"k8s.io/kubernetes/pkg/util/strings"
"k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util"
"k8s.io/kubernetes/pkg/volume/validation"
)

// This is the primary entrypoint for volume plugins.
Expand Down Expand Up @@ -192,6 +193,11 @@ func (m *localVolumeMounter) SetUpAt(dir string, fsGroup *types.UnixGroupID) err
return err
}

err := validation.ValidatePathNoBacksteps(m.globalPath)
if err != nil {
return fmt.Errorf("invalid path: %s %v", m.globalPath, err)
}

notMnt, err := m.mounter.IsLikelyNotMountPoint(dir)
glog.V(4).Infof("LocalVolume mount setup: PodDir(%s) VolDir(%s) Mounted(%t) Error(%v), ReadOnly(%t)", dir, m.globalPath, !notMnt, err, m.readOnly)
if err != nil && !os.IsNotExist(err) {
Expand Down
33 changes: 25 additions & 8 deletions pkg/volume/local/local_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,15 @@ func getPersistentPlugin(t *testing.T) (string, volume.PersistentVolumePlugin) {
return tmpDir, plug
}

func getTestVolume(readOnly bool) *volume.Spec {
func getTestVolume(readOnly bool, path string) *volume.Spec {
pv := &v1.PersistentVolume{
ObjectMeta: metav1.ObjectMeta{
Name: testPVName,
},
Spec: v1.PersistentVolumeSpec{
PersistentVolumeSource: v1.PersistentVolumeSource{
Local: &v1.LocalVolumeSource{
Path: "/test-vol",
Path: path,
},
},
},
Expand All @@ -104,7 +104,7 @@ func TestCanSupport(t *testing.T) {
tmpDir, plug := getPlugin(t)
defer os.RemoveAll(tmpDir)

if !plug.CanSupport(getTestVolume(false)) {
if !plug.CanSupport(getTestVolume(false, "/test-vol")) {
t.Errorf("Expected true")
}
}
Expand All @@ -130,7 +130,7 @@ func TestGetVolumeName(t *testing.T) {
tmpDir, plug := getPersistentPlugin(t)
defer os.RemoveAll(tmpDir)

volName, err := plug.GetVolumeName(getTestVolume(false))
volName, err := plug.GetVolumeName(getTestVolume(false, "/test-vol"))
if err != nil {
t.Errorf("Failed to get volume name: %v", err)
}
Expand All @@ -139,12 +139,29 @@ func TestGetVolumeName(t *testing.T) {
}
}

func TestInvalidLocalPath(t *testing.T) {
tmpDir, plug := getPlugin(t)
defer os.RemoveAll(tmpDir)

pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{UID: types.UID("poduid")}}
mounter, err := plug.NewMounter(getTestVolume(false, "/no/backsteps/allowed/.."), pod, volume.VolumeOptions{})
if err != nil {
t.Fatal(err)
}

err = mounter.SetUp(nil)
expectedMsg := "invalid path: /no/backsteps/allowed/.. must not contain '..'"
if err.Error() != expectedMsg {
t.Fatalf("expected error `%s` but got `%s`", expectedMsg, err)
}
}

func TestMountUnmount(t *testing.T) {
tmpDir, plug := getPlugin(t)
defer os.RemoveAll(tmpDir)

pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{UID: types.UID("poduid")}}
mounter, err := plug.NewMounter(getTestVolume(false), pod, volume.VolumeOptions{})
mounter, err := plug.NewMounter(getTestVolume(false, "/test-vol"), pod, volume.VolumeOptions{})
if err != nil {
t.Errorf("Failed to make a new Mounter: %v", err)
}
Expand Down Expand Up @@ -226,7 +243,7 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) {

// Read only == true
pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{UID: types.UID("poduid")}}
mounter, err := plug.NewMounter(getTestVolume(true), pod, volume.VolumeOptions{})
mounter, err := plug.NewMounter(getTestVolume(true, "/test-vol"), pod, volume.VolumeOptions{})
if err != nil {
t.Errorf("Failed to make a new Mounter: %v", err)
}
Expand All @@ -238,7 +255,7 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) {
}

// Read only == false
mounter, err = plug.NewMounter(getTestVolume(false), pod, volume.VolumeOptions{})
mounter, err = plug.NewMounter(getTestVolume(false, "/test-vol"), pod, volume.VolumeOptions{})
if err != nil {
t.Errorf("Failed to make a new Mounter: %v", err)
}
Expand All @@ -259,7 +276,7 @@ func TestUnsupportedPlugins(t *testing.T) {

plugMgr := volume.VolumePluginMgr{}
plugMgr.InitPlugins(ProbeVolumePlugins(), volumetest.NewFakeVolumeHost(tmpDir, nil, nil))
spec := getTestVolume(false)
spec := getTestVolume(false, "/test-vol")

recyclePlug, err := plugMgr.FindRecyclablePluginBySpec(spec)
if err == nil && recyclePlug != nil {
Expand Down

0 comments on commit 1184ce8

Please sign in to comment.