Skip to content

Attribute content-item registration is an unguarded find-then-insert #1899

Description

@lubomirw

Description

AttributeEngine.registerAttributeContentItems resolves each content item with findByJsonAndAttributeDefinitionUuid and inserts when the lookup returns null, with nothing guarding the gap between the two. This is the same check-then-insert shape as the discovery-import defect fixed in #1897, one layer down.

It is reachable concurrently: discovery post-processing runs several certificate imports in parallel, each applying per-row metadata through the attribute engine, so two of them can register the same not-yet-registered content item at once. The window is narrow because the discovery download phase pre-registers most content items, but it is not closed.

The outcome depends on whether the table carries a unique constraint on (json, attribute_definition_uuid):

Confirming which applies is the first step.

This is pre-existing rather than introduced by #1897; that work only made the pattern easier to see.

Severity

Minor

Steps to Reproduce

  1. Run a discovery whose certificates carry a metadata attribute value not yet registered for its definition.
  2. Ensure several discovered certificates share that value, so parallel imports register it concurrently.
  3. Observe either a duplicate attribute_content_item row for one definition, or a discovery certificate rolled back with a generic transaction-rollback reason.

Expected

Concurrent registration of the same content item resolves to one row, and no caller's transaction is poisoned by losing the race.

Actual

The gap between the lookup and the insert is unguarded, so concurrent callers either duplicate the row or one of them poisons its own transaction.

Environment

Reachable from discovery post-processing on any release carrying the parallel import path.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugBug fix

    Type

    Projects

    Status
    Planning

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions