Skip to content

Commit

Permalink
Fix remount for mounts with spaces in the name (#19585)
Browse files Browse the repository at this point in the history
* Fix remount for mounts with spaces in the name

* Git mishap

* Git mishap

* Changelog

* Godocs for tests
  • Loading branch information
VioletHynes authored Mar 16, 2023
1 parent 3559dd2 commit b48e826
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 10 deletions.
3 changes: 3 additions & 0 deletions changelog/19585.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
core: Fixed issue with remounting mounts that have a non-trailing space in the 'to' or 'from' paths.
```
66 changes: 66 additions & 0 deletions http/sys_mount_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,72 @@ func TestSysMount_put(t *testing.T) {
// for more info.
}

// TestSysRemountSpacesFrom ensure we succeed in a remount where the 'from' mount has spaces in the name
func TestSysRemountSpacesFrom(t *testing.T) {
core, _, token := vault.TestCoreUnsealed(t)
ln, addr := TestServer(t, core)
defer ln.Close()
TestServerAuth(t, addr, token)

resp := testHttpPost(t, token, addr+"/v1/sys/mounts/foo%20bar", map[string]interface{}{
"type": "kv",
"description": "foo",
})
testResponseStatus(t, resp, 204)

resp = testHttpPost(t, token, addr+"/v1/sys/remount", map[string]interface{}{
"from": "foo bar",
"to": "baz",
})
testResponseStatus(t, resp, 200)
}

// TestSysRemountSpacesTo ensure we succeed in a remount where the 'to' mount has spaces in the name
func TestSysRemountSpacesTo(t *testing.T) {
core, _, token := vault.TestCoreUnsealed(t)
ln, addr := TestServer(t, core)
defer ln.Close()
TestServerAuth(t, addr, token)

resp := testHttpPost(t, token, addr+"/v1/sys/mounts/foo%20bar", map[string]interface{}{
"type": "kv",
"description": "foo",
})
testResponseStatus(t, resp, 204)

resp = testHttpPost(t, token, addr+"/v1/sys/remount", map[string]interface{}{
"from": "foo bar",
"to": "bar baz",
})
testResponseStatus(t, resp, 200)
}

// TestSysRemountTrailingSpaces ensures we fail on trailing spaces
func TestSysRemountTrailingSpaces(t *testing.T) {
core, _, token := vault.TestCoreUnsealed(t)
ln, addr := TestServer(t, core)
defer ln.Close()
TestServerAuth(t, addr, token)

resp := testHttpPost(t, token, addr+"/v1/sys/mounts/foo%20bar", map[string]interface{}{
"type": "kv",
"description": "foo",
})
testResponseStatus(t, resp, 204)

resp = testHttpPost(t, token, addr+"/v1/sys/remount", map[string]interface{}{
"from": "foo bar",
"to": " baz ",
})
testResponseStatus(t, resp, 400)

resp = testHttpPost(t, token, addr+"/v1/sys/remount", map[string]interface{}{
"from": " foo bar ",
"to": "baz",
})
testResponseStatus(t, resp, 400)
}

func TestSysRemount(t *testing.T) {
core, _, token := vault.TestCoreUnsealed(t)
ln, addr := TestServer(t, core)
Expand Down
8 changes: 4 additions & 4 deletions vault/logical_system.go
Original file line number Diff line number Diff line change
Expand Up @@ -1384,11 +1384,11 @@ func (b *SystemBackend) handleRemount(ctx context.Context, req *logical.Request,
logical.ErrInvalidRequest
}

if strings.Contains(fromPath, " ") {
return logical.ErrorResponse("'from' path cannot contain whitespace"), logical.ErrInvalidRequest
if strings.HasPrefix(fromPath, " ") || strings.HasSuffix(fromPath, " ") {
return logical.ErrorResponse("'from' path cannot contain trailing whitespace"), logical.ErrInvalidRequest
}
if strings.Contains(toPath, " ") {
return logical.ErrorResponse("'to' path cannot contain whitespace"), logical.ErrInvalidRequest
if strings.HasPrefix(toPath, " ") || strings.HasSuffix(toPath, " ") {
return logical.ErrorResponse("'to' path cannot contain trailing whitespace"), logical.ErrInvalidRequest
}

fromPathDetails := b.Core.splitNamespaceAndMountFromPath(ns.Path, fromPath)
Expand Down
16 changes: 10 additions & 6 deletions vault/logical_system_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1137,34 +1137,38 @@ func TestSystemBackend_remount_nonPrintable(t *testing.T) {
}
}

func TestSystemBackend_remount_spacesInFromPath(t *testing.T) {
// TestSystemBackend_remount_trailingSpacesInFromPath ensures we error when
// there are trailing spaces in the 'from' path during a remount.
func TestSystemBackend_remount_trailingSpacesInFromPath(t *testing.T) {
b := testSystemBackend(t)

req := logical.TestRequest(t, logical.UpdateOperation, "remount")
req.Data["from"] = " foo / "
req.Data["from"] = " foo/ "
req.Data["to"] = "bar"
req.Data["config"] = structs.Map(MountConfig{})
resp, err := b.HandleRequest(namespace.RootContext(nil), req)
if err != logical.ErrInvalidRequest {
t.Fatalf("err: %v", err)
}
if resp.Data["error"] != `'from' path cannot contain whitespace` {
if resp.Data["error"] != `'from' path cannot contain trailing whitespace` {
t.Fatalf("bad: %v", resp)
}
}

func TestSystemBackend_remount_spacesInToPath(t *testing.T) {
// TestSystemBackend_remount_trailingSpacesInToPath ensures we error when
// there are trailing spaces in the 'to' path during a remount.
func TestSystemBackend_remount_trailingSpacesInToPath(t *testing.T) {
b := testSystemBackend(t)

req := logical.TestRequest(t, logical.UpdateOperation, "remount")
req.Data["from"] = "foo"
req.Data["to"] = " bar / "
req.Data["to"] = " bar/ "
req.Data["config"] = structs.Map(MountConfig{})
resp, err := b.HandleRequest(namespace.RootContext(nil), req)
if err != logical.ErrInvalidRequest {
t.Fatalf("err: %v", err)
}
if resp.Data["error"] != `'to' path cannot contain whitespace` {
if resp.Data["error"] != `'to' path cannot contain trailing whitespace` {
t.Fatalf("bad: %v", resp)
}
}
Expand Down

0 comments on commit b48e826

Please sign in to comment.