Skip to content

DPTP-5102: Fix hostNetwork pod port ownership leak by scoping process cache per pod - #86

Open
richardsonnick wants to merge 1 commit into
openshift:mainfrom
richardsonnick:fix/hostnetwork-port-ownership-leak
Open

DPTP-5102: Fix hostNetwork pod port ownership leak by scoping process cache per pod#86
richardsonnick wants to merge 1 commit into
openshift:mainfrom
richardsonnick:fix/hostnetwork-port-ownership-leak

Conversation

@richardsonnick

Copy link
Copy Markdown
Contributor

Previously process ownership was keyed by IP, so hostNetwork pods sharing a node IP could inherit ports resolved from unrelated pods (e.g. ovnkube-node). Add a podOwnedPorts cache keyed by namespace/name and Client.GetOwnedPorts to return only ports whose listening process was resolved in that pod's own PID namespace. Update the scanner's filterByProcessPorts to use the per-pod owned set instead of an IP-based process map.

@openshift-ci
openshift-ci Bot requested review from rhmdnd and smith-xyz July 28, 2026 17:54
@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jul 28, 2026
@qodo-for-rh-openshift

qodo-for-rh-openshift Bot commented Jul 28, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 10 rules

Grey Divider


Action required

1. Empty ownership bypasses filtering ✓ Resolved 🐞 Bug ≡ Correctness
Description
GetOwnedPorts returns nil when no listener inode resolves in the pod, causing DiscoverTargets
to skip filtering despite successful /proc discovery. For a hostNetwork pod with non-empty
procPorts, every listener from the shared host network namespace is retained, including ports
owned by unrelated pods or host processes.
Code

internal/scanner/scanner.go[101]

+				if pod.Pod.Spec.HostNetwork && ownedPorts != nil && len(procPorts) > 0 {
Relevance

●●● Strong

PRs #69 and #65 accepted fixes preventing hostNetwork port misattribution, directly matching this
ownership-filter bypass.

PR-#69
PR-#65

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
cacheProcListenInfo creates a per-pod ownership map even if no inode resolves, but GetOwnedPorts
converts that known-empty map to nil. /proc/net/tcp exposes the pod's shared network namespace
while inode resolution is limited to the selected container's PID namespace; the new `ownedPorts !=
nil` condition therefore skips filtering exactly when socket listeners exist but none can be
attributed to that pod, and the unfiltered procPorts become openPorts.

internal/k8s/process.go[7-10]
internal/k8s/process.go[61-63]
internal/k8s/discovery.go[79-84]
internal/scanner/scanner.go[101-116]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
HostNetwork port filtering is conditional on `ownedPorts != nil`, but `GetOwnedPorts` returns `nil` for a successfully populated yet empty ownership set. Consequently, non-empty `/proc` results with zero inode matches bypass filtering and retain unrelated host listeners.

## Issue Context
An empty ownership set is a valid discovery result, not evidence that `/proc` discovery was unavailable. Filtering should still run and preserve only secondary-container spec ports, if any.

## Fix Focus Areas
- internal/scanner/scanner.go[92-106]
- internal/k8s/process.go[57-69]
- internal/scanner/scanner_test.go[744-801]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

  • Author self-review: I have reviewed the code review findings, and addressed the relevant ones.

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Jul 28, 2026
@openshift-ci

openshift-ci Bot commented Jul 28, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: richardsonnick, smith-xyz

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:
  • OWNERS [richardsonnick,smith-xyz]

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@smith-xyz

Copy link
Copy Markdown
Contributor

/hold

@openshift-ci openshift-ci Bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jul 28, 2026
@smith-xyz

Copy link
Copy Markdown
Contributor

@richardsonnick can you check what qodo is complaining about there? Not sure if there is another area this could fail at.

Previously process ownership was keyed by IP, so hostNetwork pods sharing a
node IP could inherit ports resolved from unrelated pods (e.g. ovnkube-node).
Add a podOwnedPorts cache keyed by namespace/name and Client.GetOwnedPorts
to return only ports whose listening process was resolved in that pod's own
PID namespace. Update the scanner's filterByProcessPorts to use the per-pod
owned set instead of an IP-based process map.

Co-authored-by: Cursor <cursoragent@cursor.com>
@richardsonnick
richardsonnick force-pushed the fix/hostnetwork-port-ownership-leak branch from e358362 to 96fe851 Compare July 29, 2026 14:50
@openshift-ci openshift-ci Bot removed the lgtm Indicates that a PR is ready to be merged. label Jul 29, 2026
@openshift-ci

openshift-ci Bot commented Jul 29, 2026

Copy link
Copy Markdown

New changes are detected. LGTM label has been removed.

@richardsonnick richardsonnick changed the title Fix hostNetwork pod port ownership leak by scoping process cache per pod DPTP-5102: Fix hostNetwork pod port ownership leak by scoping process cache per pod Jul 29, 2026
@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jul 29, 2026
@openshift-ci-robot

openshift-ci-robot commented Jul 29, 2026

Copy link
Copy Markdown

@richardsonnick: This pull request references DPTP-5102 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the bug to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Previously process ownership was keyed by IP, so hostNetwork pods sharing a node IP could inherit ports resolved from unrelated pods (e.g. ovnkube-node). Add a podOwnedPorts cache keyed by namespace/name and Client.GetOwnedPorts to return only ports whose listening process was resolved in that pod's own PID namespace. Update the scanner's filterByProcessPorts to use the per-pod owned set instead of an IP-based process map.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci

openshift-ci Bot commented Jul 29, 2026

Copy link
Copy Markdown

@richardsonnick: all tests passed!

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants