From c65c7342bccae6a1bd82f93bc385337219a0ea1a Mon Sep 17 00:00:00 2001 From: Thomas Jungblut Date: Fri, 2 Jun 2023 13:14:19 +0200 Subject: [PATCH] Early exit auth check on lease puts Mitigates etcd-io#15993 by not checking each key individually for permission when auth is entirely disabled or admin user is calling the method. Signed-off-by: Thomas Jungblut --- client/client_repro_test.go | 51 +++++++++++++++++++++++++++ server/etcdserver/apply/apply_auth.go | 5 +++ 2 files changed, 56 insertions(+) create mode 100644 client/client_repro_test.go diff --git a/client/client_repro_test.go b/client/client_repro_test.go new file mode 100644 index 000000000000..a24179c06d96 --- /dev/null +++ b/client/client_repro_test.go @@ -0,0 +1,51 @@ +package client + +import ( + "context" + "fmt" + "strconv" + "sync" + "testing" + "time" + + client "go.etcd.io/etcd/client/v3" + + "go.etcd.io/etcd/client/v3/concurrency" + "golang.org/x/time/rate" +) + +func TestReproLeases(t *testing.T) { + c, err := client.New(client.Config{Endpoints: []string{"localhost:2379"}, DialTimeout: 5 * time.Second}) + fmt.Println("Opening session") + session, err := concurrency.NewSession(c, concurrency.WithTTL(int(30))) + if err != nil { + return + } + + limiter := rate.NewLimiter(1000, 20) + maxDuration := time.Duration(0) + mu := sync.Mutex{} + + fmt.Println("Starting writes") + for i := 0; i <= 10000000; i++ { + i := i + limiter.Wait(context.Background()) + key := "asdasdasdasdasd" + strconv.Itoa(i) + go func() { + leaseID := session.Lease() + start := time.Now() + c.Put(context.Background(), key, key, client.WithLease(leaseID)) + duration := time.Since(start) + + mu.Lock() + defer mu.Unlock() + if duration > maxDuration { + fmt.Printf("MAX latency: %v, entries: %d\n", duration, i) + maxDuration = duration + } + if i%1000 == 0 { + fmt.Printf("latency: %v, entries: %d\n", duration, i) + } + }() + } +} diff --git a/server/etcdserver/apply/apply_auth.go b/server/etcdserver/apply/apply_auth.go index 61f9f8892d2c..244bbe2fc3f3 100644 --- a/server/etcdserver/apply/apply_auth.go +++ b/server/etcdserver/apply/apply_auth.go @@ -125,6 +125,11 @@ func (aa *authApplierV3) LeaseRevoke(lc *pb.LeaseRevokeRequest) (*pb.LeaseRevoke func (aa *authApplierV3) checkLeasePuts(leaseID lease.LeaseID) error { l := aa.lessor.Lookup(leaseID) if l != nil { + // early return for most-common scenario of either disabled auth or admin user + if aa.as.IsAdminPermitted(&aa.authInfo) != nil { + return nil + } + for _, key := range l.Keys() { if err := aa.as.IsPutPermitted(&aa.authInfo, []byte(key)); err != nil { return err