From 6e0f168db07abe3ed7ca5a206b65087415708153 Mon Sep 17 00:00:00 2001 From: Irbe Krumina Date: Wed, 11 Dec 2024 15:30:43 +0000 Subject: [PATCH] cmd/containerboot: fix nil pointer exception (cherry-pick of #14357, #14358) (#14359) * cmd/containerboot: guard kubeClient against nil dereference (#14357) A method on kc was called unconditionally, even if was not initialized, leading to a nil pointer dereference when TS_SERVE_CONFIG was set outside Kubernetes. Add a guard symmetric with other uses of the kubeClient. Signed-off-by: Bjorn Neergaard (cherry picked from commit 8b1d01161bbca8a26c2a50208444087c9fa2b3f1) * cmd/containerboot: don't attempt to write kube Secret in non-kube environments (#14358) Signed-off-by: Irbe Krumina (cherry picked from commit 0cc071f15409071f2649c3e142eceaf7cabff560) * cmd/containerboot: don't attempt to patch a Secret field without permissions (#14365) Signed-off-by: Irbe Krumina (cherry picked from commit 6e552f66a0289f6309477fb024019b62a251da16) Updates tailscale/tailscale#14354 --- cmd/containerboot/kube.go | 1 + cmd/containerboot/main.go | 6 ++++-- cmd/containerboot/serve.go | 6 ++++-- cmd/containerboot/settings.go | 1 + 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/cmd/containerboot/kube.go b/cmd/containerboot/kube.go index 643eef385..4d00687ee 100644 --- a/cmd/containerboot/kube.go +++ b/cmd/containerboot/kube.go @@ -24,6 +24,7 @@ import ( type kubeClient struct { kubeclient.Client stateSecret string + canPatch bool // whether the client has permissions to patch Kubernetes Secrets } func newKubeClient(root string, stateSecret string) (*kubeClient, error) { diff --git a/cmd/containerboot/main.go b/cmd/containerboot/main.go index ad1c0db20..7411ea949 100644 --- a/cmd/containerboot/main.go +++ b/cmd/containerboot/main.go @@ -331,8 +331,10 @@ authLoop: if err := client.SetServeConfig(ctx, new(ipn.ServeConfig)); err != nil { log.Fatalf("failed to unset serve config: %v", err) } - if err := kc.storeHTTPSEndpoint(ctx, ""); err != nil { - log.Fatalf("failed to update HTTPS endpoint in tailscale state: %v", err) + if hasKubeStateStore(cfg) { + if err := kc.storeHTTPSEndpoint(ctx, ""); err != nil { + log.Fatalf("failed to update HTTPS endpoint in tailscale state: %v", err) + } } } diff --git a/cmd/containerboot/serve.go b/cmd/containerboot/serve.go index 29ee7347f..14c7f00d7 100644 --- a/cmd/containerboot/serve.go +++ b/cmd/containerboot/serve.go @@ -72,8 +72,10 @@ func watchServeConfigChanges(ctx context.Context, path string, cdChanged <-chan if err := updateServeConfig(ctx, sc, certDomain, lc); err != nil { log.Fatalf("serve proxy: error updating serve config: %v", err) } - if err := kc.storeHTTPSEndpoint(ctx, certDomain); err != nil { - log.Fatalf("serve proxy: error storing HTTPS endpoint: %v", err) + if kc != nil && kc.canPatch { + if err := kc.storeHTTPSEndpoint(ctx, certDomain); err != nil { + log.Fatalf("serve proxy: error storing HTTPS endpoint: %v", err) + } } prevServeConfig = sc } diff --git a/cmd/containerboot/settings.go b/cmd/containerboot/settings.go index 4fae58584..cc8641909 100644 --- a/cmd/containerboot/settings.go +++ b/cmd/containerboot/settings.go @@ -214,6 +214,7 @@ func (cfg *settings) setupKube(ctx context.Context, kc *kubeClient) error { return fmt.Errorf("some Kubernetes permissions are missing, please check your RBAC configuration: %v", err) } cfg.KubernetesCanPatch = canPatch + kc.canPatch = canPatch s, err := kc.GetSecret(ctx, cfg.KubeSecret) if err != nil {