Skip to content

Commit

Permalink
Expand /../ for mounts (#73)
Browse files Browse the repository at this point in the history
Signed-off-by: Scott Williams <[email protected]>
Co-authored-by: Scott Williams <[email protected]>
  • Loading branch information
scottrw93 and Scott Williams authored Aug 18, 2023
1 parent 8aaf017 commit 992b838
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 16 deletions.
20 changes: 11 additions & 9 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,17 @@ func listBindMounts(body map[string]interface{}) []BindMount {
}
}

// resolve bind mount paths to symlink targets
// and expand /example/../ to avoid bypassing rules
for idx, bindMount := range result {
resolved, err := filepath.EvalSymlinks(bindMount.Source)
if err == nil {
resolved = filepath.Clean(resolved)
result[idx].Resolved = resolved
}

}

return result
}

Expand All @@ -240,15 +251,6 @@ func makeInput(r authorization.Request) (interface{}, error) {

bindMountList := listBindMounts(body)

// resolve bind mount paths to symlink targets
for idx, bindMount := range bindMountList {
resolved, err := filepath.EvalSymlinks(bindMount.Source)
if err == nil {
bindMountList[idx].Resolved = resolved
}

}

input := map[string]interface{}{
"Headers": r.RequestHeaders,
"Path": r.RequestURI,
Expand Down
35 changes: 28 additions & 7 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package main

import (
"encoding/json"
"fmt"
"os"
"reflect"
"testing"
)
Expand Down Expand Up @@ -50,6 +52,15 @@ func TestNormalizeAllowPath(t *testing.T) {
}

func TestListBindMounts(t *testing.T) {
dotDotPath := fmt.Sprintf("%s/../../../../", t.TempDir())
symlinkSourcePath := t.TempDir()
symlinkTargetPath := fmt.Sprintf("%s/target", t.TempDir())
err := os.Symlink(symlinkSourcePath, symlinkTargetPath)

if err != nil {
t.Fatalf("Failed to symlink '%s' to '%s' - got %v", symlinkSourcePath, symlinkTargetPath, err)
}

tests := []struct {
statement string
input string
Expand All @@ -58,12 +69,22 @@ func TestListBindMounts(t *testing.T) {
{
statement: "parse a simple bind list",
input: `{ "HostConfig": { "Binds" : [ "/var:/home", "volume:/var/lib/app:ro" ] } }`,
expected: []BindMount{{"/var", false, ""}},
expected: []BindMount{{"/var", false, "/var"}},
},
{
statement: "expand ..",
input: fmt.Sprintf(`{ "HostConfig": { "Binds" : [ "%s:/host" ] } }`, dotDotPath),
expected: []BindMount{{dotDotPath, false, "/"}},
},
{
statement: "resolve symlinks",
input: fmt.Sprintf(`{ "HostConfig": { "Binds" : [ "%s:/host" ] } }`, symlinkTargetPath),
expected: []BindMount{{symlinkTargetPath, false, symlinkSourcePath}},
},
{
statement: "parse the readonly attribute",
input: `{ "HostConfig": { "Binds" : [ "/var:/home:ro", "/home/user:/mnt:rw" ] } }`,
expected: []BindMount{{"/var", true, ""}, {"/home/user", false, ""}},
input: `{ "HostConfig": { "Binds" : [ "/var:/home:ro", "/var/lib:/mnt:rw" ] } }`,
expected: []BindMount{{"/var", true, "/var"}, {"/var/lib", false, "/var/lib"}},
},
{
statement: "handle when neither bind nor mounts provided",
Expand All @@ -86,29 +107,29 @@ func TestListBindMounts(t *testing.T) {
{ "Source": "/var", "Target": "/mnt", "Type": "bind" },
{ "Source": "vol", "Target": "/vol", "Type": "volume", "Labels":{"color":"red"} }
] } }`,
expected: []BindMount{{"/var", false, ""}},
expected: []BindMount{{"/var", false, "/var"}},
},
{
statement: "parse a readonly mount list",
input: `{ "HostConfig": { "Mounts" : [
{ "Source": "/var", "Target": "/mnt", "Type": "bind", "ReadOnly": true },
{ "Source": "/home", "Target": "/home", "Type": "bind" }
] } }`,
expected: []BindMount{{"/var", true, ""}, {"/home", false, ""}},
expected: []BindMount{{"/var", true, "/var"}, {"/home", false, "/home"}},
},
{
statement: "ignore an invalid mount list",
input: `{ "HostConfig": { "Mounts" : [
{ "Source": "/var", "Target": "/mnt", "Type": "bind", "ReadOnly": true },
{ "Source1": "/home", "Target": "/home", "Type": "bind" }
] } }`,
expected: []BindMount{{"/var", true, ""}},
expected: []BindMount{{"/var", true, "/var"}},
},
{
statement: "ignore a mount list of the wrong type, whlile reading binds",
input: `{ "HostConfig": { "Binds": ["/var:/mnt/var:ro","/home:/home"],
"Mounts" : null } }`,
expected: []BindMount{{"/var", true, ""}, {"/home", false, ""}},
expected: []BindMount{{"/var", true, "/var"}, {"/home", false, "/home"}},
},
}

Expand Down

0 comments on commit 992b838

Please sign in to comment.