Skip to content

fix(link): add missing BPF_F_REPLACE flag for RawAttachProgram#1995

Merged
ti-mo merged 1 commit into
cilium:mainfrom
wucm667:fix/replaceprogram-missing-bpf-f-replace-flag
May 13, 2026
Merged

fix(link): add missing BPF_F_REPLACE flag for RawAttachProgram#1995
ti-mo merged 1 commit into
cilium:mainfrom
wucm667:fix/replaceprogram-missing-bpf-f-replace-flag

Conversation

@wucm667
Copy link
Copy Markdown
Contributor

@wucm667 wucm667 commented Apr 30, 2026

Fixes #1994

Summary

When using RawAttachProgram with Anchor: link.ReplaceProgram(oldProg), the BPF_F_REPLACE flag was not being set in AttachFlags. This caused the kernel to silently ignore the replacement and treat the call as a regular append, resulting in two programs being attached instead of one being replaced.

Root Cause

In link/program.go, when flags == sys.BPF_F_REPLACE:

  • attr.ReplaceBpfFd was set correctly
  • But attr.AttachFlags was not updated with sys.BPF_F_REPLACE

Per the Linux kernel (commit 7dd68b3), the kernel requires BPF_F_REPLACE in attach_flags to perform the replacement — without it, replace_bpf_fd is ignored.

Fix

Add attr.AttachFlags |= sys.BPF_F_REPLACE in the BPF_F_REPLACE branch of RawAttachProgram, ensuring the kernel actually performs the replacement operation.

@wucm667 wucm667 requested a review from mmat11 as a code owner April 30, 2026 00:15
@wucm667 wucm667 force-pushed the fix/replaceprogram-missing-bpf-f-replace-flag branch from 39d5f8a to 321a33e Compare April 30, 2026 00:52
Copy link
Copy Markdown

@michalskrivanek michalskrivanek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the quick fix!
I can confirm the patch fixes the problem.

Comment thread link/program.go Outdated
@wucm667
Copy link
Copy Markdown
Contributor Author

wucm667 commented May 5, 2026

@michalskrivanek Good catch — you're right, that comment was misleading. Updated it to clarify that the kernel requires BPF_F_REPLACE in attach_flags for the replace operation to take effect, not just on old kernels.

@wucm667
Copy link
Copy Markdown
Contributor Author

wucm667 commented May 5, 2026

@michalskrivanek @mmat11 Heads up on the CI — the Build and Lint failures (3 govet inline warnings in and ) are pre-existing and unrelated to my change in .

They appear to be triggered by a new inline check in the latest golangci-lint version. Happy to help fix those if needed, or we can handle them separately.

Comment thread link/program.go Outdated
@mmat11
Copy link
Copy Markdown
Contributor

mmat11 commented May 5, 2026

would it be possible to add a test that exercises this code path?

@wucm667
Copy link
Copy Markdown
Contributor Author

wucm667 commented May 5, 2026

@mmat11 Done both:

  1. Refactored AttachFlags assignment — set attr.AttachFlags |= flags unconditionally before the if/else, which now only routes fdOrID to ReplaceBpfFd or RelativeFdOrId.
  2. Added TestRawAttachProgramReplace — attaches progA, replaces it with progB using ReplaceProgram(progA), then queries attached programs to verify only progB remains (not both).

All changes compile cleanly and go vet passes. Runtime tests require CAP_BPF so they'll run in CI.

@wucm667 wucm667 force-pushed the fix/replaceprogram-missing-bpf-f-replace-flag branch from e77ae9b to 4130ac2 Compare May 5, 2026 09:59
Copy link
Copy Markdown
Contributor

@ti-mo ti-mo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! This needs a rebase to pass CI, and detach errors shouldn't be ignored. Please squash this into a single commit.

Also, for awareness, our GenAI policy is about to be finalized and will go into effect soon: cilium/community#408. I'm calling this out because your replies feel very generated, and this won't be allowed under the new policy. Please don't be afraid of making mistakes! Most of us aren't native speakers either. We'd rather talk to a real human, we have agents too, just like everyone else. :)

Comment thread link/program_test.go Outdated
@wucm667 wucm667 force-pushed the fix/replaceprogram-missing-bpf-f-replace-flag branch from 9dbaea2 to e56b7a7 Compare May 8, 2026 03:25
@wucm667
Copy link
Copy Markdown
Contributor Author

wucm667 commented May 8, 2026

done, rebased and squashed. moved the detach into t.Cleanup with assert

@ti-mo ti-mo force-pushed the fix/replaceprogram-missing-bpf-f-replace-flag branch from e56b7a7 to 75e0db4 Compare May 13, 2026 14:20
When using ReplaceProgram anchor with RawAttachProgram, the BPF_F_REPLACE
flag was not being set in AttachFlags. The Linux kernel requires this flag
to actually perform the replacement operation - without it, replace_bpf_fd
is ignored and the call is treated as a regular append.

Set AttachFlags unconditionally before the if/else, which now only routes
fdOrID to ReplaceBpfFd or RelativeFdOrId.

Add TestRawAttachProgramReplace that verifies the ReplaceProgram anchor
correctly replaces the attached program (only one program remains after
replace, not two).

Fixes cilium#1994

Signed-off-by: wucm667 <stevenwucongmin@gmail.com>
@ti-mo ti-mo force-pushed the fix/replaceprogram-missing-bpf-f-replace-flag branch from 75e0db4 to 3d3ba3b Compare May 13, 2026 14:40
@ti-mo ti-mo merged commit dd3e0f0 into cilium:main May 13, 2026
21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RawAttachProgram with ReplaceProgram anchor silently fails for BPF_PROG_ATTACH-based cgroup attachment

4 participants