Skip to content

Simultaneous calls to add a finalizer and delete can race #77988

@liggitt

Description

@liggitt

Store#Delete begins by looking up the existing object:

// Delete removes the item from storage.
func (e *Store) Delete(ctx context.Context, name string, options *metav1.DeleteOptions) (runtime.Object, bool, error) {
key, err := e.KeyFunc(ctx, name)
if err != nil {
return nil, false, err
}
obj := e.NewFunc()
qualifiedResource := e.qualifiedResourceFromContext(ctx)
if err := e.Storage.Get(ctx, key, "", obj, false); err != nil {
return nil, false, storeerr.InterpretDeleteError(err, qualifiedResource, name)
}

If that object has no pending finalizers, and that type does not do graceful deletion, and the incoming deletion options do not specify preconditions (uid or resourceVersion) or GC-related finalizers (like orphan or foreground deletion), then the object is deleted unconditionally:

// delete immediately, or no graceful deletion supported
klog.V(6).Infof("going to delete %s from registry: ", name)
out = e.NewFunc()
if err := e.Storage.Delete(ctx, key, out, &preconditions, dryrun.IsDryRun(options.DryRun)); err != nil {

In between the initial get and the unconditional delete, an update adding finalizers could have been made and succeeded.

/kind bug
/sig api-machinery
/priority important-soon
/cc @caesarxuchao

Metadata

Metadata

Assignees

Labels

kind/bugCategorizes issue or PR as related to a bug.lifecycle/frozenIndicates that an issue or PR should not be auto-closed due to staleness.priority/important-soonMust be staffed and worked on either currently, or very soon, ideally in time for the next release.sig/api-machineryCategorizes an issue or PR as relevant to SIG API Machinery.

Type

No type

Projects

Status

No status

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions