From 3b394df815ef34917043e5409772b06e208a9926 Mon Sep 17 00:00:00 2001 From: Thomas Stromberg Date: Wed, 11 Sep 2019 13:10:21 -0700 Subject: [PATCH] Add mutex around generateCerts to avoid TOCTOU race --- pkg/minikube/bootstrapper/certs.go | 18 +++++++++++++++++- pkg/util/crypto.go | 4 ++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/pkg/minikube/bootstrapper/certs.go b/pkg/minikube/bootstrapper/certs.go index cd7bed704..5a556563c 100644 --- a/pkg/minikube/bootstrapper/certs.go +++ b/pkg/minikube/bootstrapper/certs.go @@ -25,6 +25,7 @@ import ( "path" "path/filepath" "strings" + "time" "github.com/golang/glog" "github.com/pkg/errors" @@ -37,6 +38,9 @@ import ( "k8s.io/minikube/pkg/minikube/constants" "k8s.io/minikube/pkg/minikube/kubeconfig" "k8s.io/minikube/pkg/util" + + "github.com/juju/clock" + "github.com/juju/mutex" ) const ( @@ -122,13 +126,25 @@ func SetupCerts(cmd command.Runner, k8s config.KubernetesConfig) error { } func generateCerts(k8s config.KubernetesConfig) error { + // TODO: Instead of racey manipulation of a shared certificate, use per-profile certs + spec := mutex.Spec{ + Name: "generateCerts", + Clock: clock.WallClock, + Delay: 10 * time.Second, + } + glog.Infof("acquiring lock: %+v", spec) + releaser, err := mutex.Acquire(spec) + if err != nil { + return errors.Wrapf(err, "unable to acquire lock for %+v", spec) + } + defer releaser.Release() + serviceIP, err := util.GetServiceClusterIP(k8s.ServiceCIDR) if err != nil { return errors.Wrap(err, "getting service cluster ip") } localPath := constants.GetMinipath() - caCertPath := filepath.Join(localPath, "ca.crt") caKeyPath := filepath.Join(localPath, "ca.key") diff --git a/pkg/util/crypto.go b/pkg/util/crypto.go index 48031ef97..417417e21 100644 --- a/pkg/util/crypto.go +++ b/pkg/util/crypto.go @@ -30,6 +30,7 @@ import ( "path/filepath" "time" + "github.com/golang/glog" "github.com/pkg/errors" "k8s.io/minikube/pkg/util/lock" ) @@ -65,6 +66,7 @@ func GenerateCACert(certPath, keyPath string, name string) error { // GenerateSignedCert generates a signed certificate and key func GenerateSignedCert(certPath, keyPath, cn string, ips []net.IP, alternateDNS []string, signerCertPath, signerKeyPath string) error { + glog.Infof("Generating cert %s with IP's: %s", certPath, ips) signerCertBytes, err := ioutil.ReadFile(signerCertPath) if err != nil { return errors.Wrap(err, "Error reading file: signerCertPath") @@ -152,6 +154,7 @@ func writeCertsAndKeys(template *x509.Certificate, certPath string, signeeKey *r if err := os.MkdirAll(filepath.Dir(certPath), os.FileMode(0755)); err != nil { return errors.Wrap(err, "Error creating certificate directory") } + glog.Infof("Writing cert to %s ...", certPath) if err := lock.WriteFile(certPath, certBuffer.Bytes(), os.FileMode(0644)); err != nil { return errors.Wrap(err, "Error writing certificate to cert path") } @@ -159,6 +162,7 @@ func writeCertsAndKeys(template *x509.Certificate, certPath string, signeeKey *r if err := os.MkdirAll(filepath.Dir(keyPath), os.FileMode(0755)); err != nil { return errors.Wrap(err, "Error creating key directory") } + glog.Infof("Writing key to %s ...", keyPath) if err := lock.WriteFile(keyPath, keyBuffer.Bytes(), os.FileMode(0600)); err != nil { return errors.Wrap(err, "Error writing key file") } -- GitLab