From 71eb9f3e761c81c57c3f17cd4075b19318670e7b Mon Sep 17 00:00:00 2001 From: Calvin Leung Huang Date: Mon, 9 Dec 2019 11:21:24 -0800 Subject: [PATCH 1/3] plugin: fix panic on router.MatchingSystemView if backend is nil --- vault/logical_system_integ_test.go | 56 ++++++++++++++++++++++++++++++ vault/router.go | 2 +- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/vault/logical_system_integ_test.go b/vault/logical_system_integ_test.go index 2b3d8c863620..261bad0a278b 100644 --- a/vault/logical_system_integ_test.go +++ b/vault/logical_system_integ_test.go @@ -5,6 +5,7 @@ import ( "io/ioutil" "os" "path/filepath" + "strings" "testing" "time" @@ -102,6 +103,61 @@ func TestSystemBackend_Plugin_auth(t *testing.T) { } } +func TestSystemBackend_Plugin_MissingBinary(t *testing.T) { + cluster := testSystemBackendMock(t, 1, 1, logical.TypeLogical) + defer cluster.Cleanup() + + core := cluster.Cores[0] + + // Make a request to lazy load the plugin + req := logical.TestRequest(t, logical.ReadOperation, "mock-0/internal") + req.ClientToken = core.Client.Token() + resp, err := core.HandleRequest(namespace.RootContext(nil), req) + if err != nil { + t.Fatalf("err: %v", err) + } + if resp == nil { + t.Fatalf("bad: response should not be nil") + } + + files, err := ioutil.ReadDir(cluster.TempDir) + if err != nil { + t.Fatal(err) + } + + // Seal the cluster + cluster.EnsureCoresSealed(t) + + // Simulate removal of the plugin binary + var pluginBinFile string + for _, file := range files { + if strings.Contains(file.Name(), t.Name()) { + pluginBinFile = file.Name() + break + } + } + + if pluginBinFile == "" { + t.Fatal("unable to find plugin binary in the plugin directory") + } + + err = os.Remove(filepath.Join(cluster.TempDir, pluginBinFile)) + if err != nil { + t.Fatal(err) + } + + // Unseal the cluster + cluster.UnsealCores(t) + + // Make a request against on tune after it is removed + req = logical.TestRequest(t, logical.ReadOperation, "sys/mounts/mock-0/tune") + req.ClientToken = core.Client.Token() + resp, err = core.HandleRequest(namespace.RootContext(nil), req) + if err == nil { + t.Fatalf("expected error") + } +} + func TestSystemBackend_Plugin_MismatchType(t *testing.T) { cluster := testSystemBackendMock(t, 1, 1, logical.TypeLogical) defer cluster.Cleanup() diff --git a/vault/router.go b/vault/router.go index eb42bc5cf609..2666c0071d66 100644 --- a/vault/router.go +++ b/vault/router.go @@ -416,7 +416,7 @@ func (r *Router) MatchingSystemView(ctx context.Context, path string) logical.Sy r.l.RLock() _, raw, ok := r.root.LongestPrefix(path) r.l.RUnlock() - if !ok { + if !ok || raw.(*routeEntry).backend == nil { return nil } return raw.(*routeEntry).backend.System() From 1a8e1318c5a7dacbd99f9e0114f37d5b44bda26d Mon Sep 17 00:00:00 2001 From: Calvin Leung Huang Date: Mon, 9 Dec 2019 15:53:19 -0800 Subject: [PATCH 2/3] correctly determine the plugin binary file in the directory --- vault/logical_system_integ_test.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/vault/logical_system_integ_test.go b/vault/logical_system_integ_test.go index 261bad0a278b..f09bc6d4f8ba 100644 --- a/vault/logical_system_integ_test.go +++ b/vault/logical_system_integ_test.go @@ -5,7 +5,6 @@ import ( "io/ioutil" "os" "path/filepath" - "strings" "testing" "time" @@ -120,18 +119,19 @@ func TestSystemBackend_Plugin_MissingBinary(t *testing.T) { t.Fatalf("bad: response should not be nil") } - files, err := ioutil.ReadDir(cluster.TempDir) - if err != nil { - t.Fatal(err) - } - // Seal the cluster cluster.EnsureCoresSealed(t) // Simulate removal of the plugin binary + files, err := ioutil.ReadDir(cluster.TempDir) + if err != nil { + t.Fatal(err) + } var pluginBinFile string for _, file := range files { - if strings.Contains(file.Name(), t.Name()) { + // We cannot determine the exact file name since it depends how the test + // is ran, so we use file stats to filter out what we want. + if !file.IsDir() && file.Mode().Perm() == os.FileMode(0755) { pluginBinFile = file.Name() break } From 416cc9405b2b3fcb1a89b9f9158ff2cbf3769711 Mon Sep 17 00:00:00 2001 From: Calvin Leung Huang Date: Mon, 9 Dec 2019 16:54:50 -0800 Subject: [PATCH 3/3] docs: simplify plugin file removal --- vault/logical_system_integ_test.go | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/vault/logical_system_integ_test.go b/vault/logical_system_integ_test.go index f09bc6d4f8ba..fef2a44ebc6c 100644 --- a/vault/logical_system_integ_test.go +++ b/vault/logical_system_integ_test.go @@ -122,26 +122,11 @@ func TestSystemBackend_Plugin_MissingBinary(t *testing.T) { // Seal the cluster cluster.EnsureCoresSealed(t) - // Simulate removal of the plugin binary - files, err := ioutil.ReadDir(cluster.TempDir) - if err != nil { - t.Fatal(err) - } - var pluginBinFile string - for _, file := range files { - // We cannot determine the exact file name since it depends how the test - // is ran, so we use file stats to filter out what we want. - if !file.IsDir() && file.Mode().Perm() == os.FileMode(0755) { - pluginBinFile = file.Name() - break - } - } - - if pluginBinFile == "" { - t.Fatal("unable to find plugin binary in the plugin directory") - } - - err = os.Remove(filepath.Join(cluster.TempDir, pluginBinFile)) + // Simulate removal of the plugin binary. Use os.Args to determine file name + // since that's how we create the file for catalog registration in the test + // helper. + pluginFileName := filepath.Base(os.Args[0]) + err = os.Remove(filepath.Join(cluster.TempDir, pluginFileName)) if err != nil { t.Fatal(err) }