From 99e4d5c2833f76839997ea8184e880505bd9793f Mon Sep 17 00:00:00 2001 From: hc-github-team-secure-vault-core <82990506+hc-github-team-secure-vault-core@users.noreply.github.com> Date: Thu, 16 Mar 2023 15:54:14 -0400 Subject: [PATCH] backport of commit b48e826d261e4f6166f4f5e0d112851b582a149f (#19590) Co-authored-by: Violet Hynes --- changelog/19585.txt | 3 ++ http/sys_mount_test.go | 66 ++++++++++++++++++++++++++++++++++++ vault/logical_system.go | 8 ++--- vault/logical_system_test.go | 16 +++++---- 4 files changed, 83 insertions(+), 10 deletions(-) create mode 100644 changelog/19585.txt diff --git a/changelog/19585.txt b/changelog/19585.txt new file mode 100644 index 000000000000..f68c0dc6f603 --- /dev/null +++ b/changelog/19585.txt @@ -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. +``` diff --git a/http/sys_mount_test.go b/http/sys_mount_test.go index ae33a258164b..5675cce5e305 100644 --- a/http/sys_mount_test.go +++ b/http/sys_mount_test.go @@ -416,6 +416,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) diff --git a/vault/logical_system.go b/vault/logical_system.go index 87b540919197..1007637f541f 100644 --- a/vault/logical_system.go +++ b/vault/logical_system.go @@ -1381,11 +1381,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) diff --git a/vault/logical_system_test.go b/vault/logical_system_test.go index 033beefdaf8b..4521ef767142 100644 --- a/vault/logical_system_test.go +++ b/vault/logical_system_test.go @@ -1026,34 +1026,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) } }