-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Revert "[SBOM] Fix inUse false positives on container image SBOM" #48699
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -121,72 +121,56 @@ func (p *processor) processContainerImagesEvents(evBundle workloadmeta.EventBund | |
|
|
||
| log.Tracef("Processing %d events", len(evBundle.Events)) | ||
|
|
||
| // Separate events by kind and type so we can process them in an order that | ||
| // keeps imageUsers accurate when SBOMs are computed. | ||
| var ( | ||
| imageSetEvents []workloadmeta.Event | ||
| imageUnsetEvents []workloadmeta.Event | ||
| containerSetEvents []workloadmeta.Event | ||
| containerUnsetEvents []workloadmeta.Event | ||
| ) | ||
| // Separate events into images and containers | ||
| var imageEvents []workloadmeta.Event | ||
| var containerEvents []workloadmeta.Event | ||
|
|
||
| for _, event := range evBundle.Events { | ||
| switch event.Entity.GetID().Kind { | ||
| entityID := event.Entity.GetID() | ||
| switch entityID.Kind { | ||
| case workloadmeta.KindContainerImageMetadata: | ||
| if event.Type == workloadmeta.EventTypeSet { | ||
| imageSetEvents = append(imageSetEvents, event) | ||
| } else { | ||
| imageUnsetEvents = append(imageUnsetEvents, event) | ||
| } | ||
| imageEvents = append(imageEvents, event) | ||
| case workloadmeta.KindContainer: | ||
| if event.Type == workloadmeta.EventTypeSet { | ||
| containerSetEvents = append(containerSetEvents, event) | ||
| } else { | ||
| containerUnsetEvents = append(containerUnsetEvents, event) | ||
| } | ||
| containerEvents = append(containerEvents, event) | ||
| } | ||
| } | ||
|
|
||
| // 1. Unregister removed containers first so imageUsers is up to date before | ||
| // we compute inUse below. Processing image Set events before these removals | ||
| // would cause false-positive inUse=true on the emitted SBOM. | ||
| for _, event := range containerUnsetEvents { | ||
| p.unregisterContainer(event.Entity.(*workloadmeta.Container)) | ||
| } | ||
|
|
||
| // 2. Unregister removed images. | ||
| for _, event := range imageUnsetEvents { | ||
| p.unregisterImage(event.Entity.(*workloadmeta.ContainerImageMetadata)) | ||
| // Let the SBOM expire on back-end side | ||
| } | ||
| // Process all image events first | ||
| for _, event := range imageEvents { | ||
| switch event.Type { | ||
| case workloadmeta.EventTypeSet: | ||
| filterableContainerImage := workloadfilter.CreateContainerImage(event.Entity.(*workloadmeta.ContainerImageMetadata).Name) | ||
| if p.containerFilter.IsExcluded(filterableContainerImage) { | ||
| continue | ||
| } | ||
|
|
||
| // 3. Register updated images and emit SBOMs; inUse now reflects the | ||
| // current set of running containers. | ||
| for _, event := range imageSetEvents { | ||
| filterableContainerImage := workloadfilter.CreateContainerImage(event.Entity.(*workloadmeta.ContainerImageMetadata).Name) | ||
| if p.containerFilter.IsExcluded(filterableContainerImage) { | ||
| continue | ||
| p.registerImage(event.Entity.(*workloadmeta.ContainerImageMetadata)) | ||
| p.processImageSBOM(event.Entity.(*workloadmeta.ContainerImageMetadata)) | ||
| case workloadmeta.EventTypeUnset: | ||
| p.unregisterImage(event.Entity.(*workloadmeta.ContainerImageMetadata)) | ||
| // Let the SBOM expire on back-end side | ||
| } | ||
|
|
||
| p.registerImage(event.Entity.(*workloadmeta.ContainerImageMetadata)) | ||
| p.processImageSBOM(event.Entity.(*workloadmeta.ContainerImageMetadata)) | ||
| } | ||
|
|
||
| // 4. Register new/updated containers. registerContainer may emit a second | ||
| // SBOM for an image that just gained its first running container. | ||
| for _, event := range containerSetEvents { | ||
| container := event.Entity.(*workloadmeta.Container) | ||
| p.registerContainer(container) | ||
| // Process all container events after images | ||
| for _, event := range containerEvents { | ||
| switch event.Type { | ||
| case workloadmeta.EventTypeSet: | ||
| container := event.Entity.(*workloadmeta.Container) | ||
| p.registerContainer(container) | ||
|
|
||
| filterableContainer := workloadmetafilter.CreateContainer(container, nil) | ||
| if p.containerFilter.IsExcluded(filterableContainer) { | ||
| continue | ||
| } | ||
| filterableContainer := workloadmetafilter.CreateContainer(container, nil) | ||
| if p.containerFilter.IsExcluded(filterableContainer) { | ||
| continue | ||
| } | ||
|
|
||
| if p.procfsSBOM { | ||
| if ok, err := procfs.IsAgentContainer(container.ID); !ok && err == nil { | ||
| p.triggerProcfsScan(container) | ||
| if p.procfsSBOM { | ||
| if ok, err := procfs.IsAgentContainer(container.ID); !ok && err == nil { | ||
| p.triggerProcfsScan(container) | ||
| } | ||
| } | ||
| case workloadmeta.EventTypeUnset: | ||
| p.unregisterContainer(event.Entity.(*workloadmeta.Container)) | ||
| } | ||
| } | ||
| } | ||
|
|
@@ -211,10 +195,6 @@ func (p *processor) registerContainer(ctr *workloadmeta.Container) { | |
| ctrID := ctr.ID | ||
|
|
||
| if !ctr.State.Running { | ||
| // Container is no longer running. Remove it from imageUsers so that a | ||
| // subsequent SBOM computation does not incorrectly set inUse=true for | ||
| // an image that has no running containers. | ||
| p.unregisterContainer(ctr) | ||
| return | ||
| } | ||
|
Comment on lines
197
to
199
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Returning immediately when Useful? React with 👍 / 👎. |
||
|
|
||
|
|
@@ -401,11 +381,6 @@ func (p *processor) processImageSBOM(img *workloadmeta.ContainerImageMetadata) { | |
| break | ||
| } | ||
| } | ||
| // Fallback for runtimes (e.g. containerd) where ctr.Image.ID is the image | ||
| // config digest rather than a repo digest, so imageUsers is keyed by img.ID. | ||
| if !inUse { | ||
| _, inUse = p.imageUsers[img.ID] | ||
| } | ||
|
|
||
| cyclosbom, err := sbomutil.UncompressSBOM(img.SBOM) | ||
| if err != nil { | ||
|
|
@@ -439,6 +414,10 @@ func (p *processor) processImageSBOM(img *workloadmeta.ContainerImageMetadata) { | |
| continue | ||
| } | ||
|
|
||
| if !inUse { | ||
| _, inUse = p.imageUsers[img.ID] | ||
|
Comment on lines
+417
to
+418
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The Useful? React with 👍 / 👎. |
||
| } | ||
|
|
||
| log.Infof("The image %s has no repo digest for repo %s", img.Name, repo) | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Handling all image events before container events means
processImageSBOMreadsimageUsersbefore same-bundleEventTypeUnsetcontainer removals are applied, so the emitted SBOM can reportInUse=truefor an image whose last running container was removed in that bundle. This is a data-accuracy regression whenever workloadmeta coalesces image refresh and container teardown together.Useful? React with 👍 / 👎.