serve docker: reject volume names resolving to the base directory itself GHSA-p6vx-hf7p-98j6
An empty or "." volume name joined onto the base directory resolves to the base directory itself. newVolume does not call validate, so such a name would mount a remote over the base directory and shadow every other volume's mountpoint. Require the resolved mountpoint to be a strict descendant of the base directory so these degenerate names are refused.
This commit is contained in:
@@ -245,6 +245,16 @@ func TestDockerPluginVolumeNameConfined(t *testing.T) {
|
||||
// The volume must not have been registered.
|
||||
_, err = drv.Get(&docker.GetRequest{Name: escape})
|
||||
assert.Error(t, err)
|
||||
|
||||
// A name that resolves to the base directory itself (empty or ".")
|
||||
// must also be rejected, since mounting there would shadow every
|
||||
// other volume.
|
||||
for _, name := range []string{"", ".", filepath.Join("a", "..")} {
|
||||
volReq.Name = name
|
||||
err = drv.Create(volReq)
|
||||
assertErrorContains(t, err, "resolves outside the base directory",
|
||||
"name %q should be rejected", name)
|
||||
}
|
||||
}
|
||||
|
||||
// TestDockerPluginRestoreStateConfined checks that a persisted state file
|
||||
|
||||
@@ -56,16 +56,18 @@ type VolInfo struct {
|
||||
}
|
||||
|
||||
// volumeMountPath returns the mountpoint for a volume called name below
|
||||
// root, together with whether that path stays confined within root.
|
||||
// root, together with whether that path is a strict descendant of root.
|
||||
//
|
||||
// filepath.Join cleans its result, collapsing any ".." components in the
|
||||
// volume name, so a crafted name could otherwise resolve to an arbitrary
|
||||
// host path outside root. Callers must reject names for which confined is
|
||||
// false rather than creating a directory and mounting there.
|
||||
// host path outside root, or to root itself (for an empty or "." name)
|
||||
// where a mount would shadow every other volume. Callers must reject names
|
||||
// for which confined is false rather than creating a directory and mounting
|
||||
// there.
|
||||
func volumeMountPath(root, name string) (path string, confined bool) {
|
||||
path = filepath.Join(root, name)
|
||||
root = filepath.Clean(root)
|
||||
return path, path == root || strings.HasPrefix(path, root+string(filepath.Separator))
|
||||
return path, strings.HasPrefix(path, root+string(filepath.Separator))
|
||||
}
|
||||
|
||||
func newVolume(ctx context.Context, name string, volOpt VolOpts, drv *Driver) (*Volume, error) {
|
||||
|
||||
Reference in New Issue
Block a user