bpf/restart: use Update instead of Restart when versions match#1606
bpf/restart: use Update instead of Restart when versions match#1606Eeshu-Yadav wants to merge 1 commit intokmesh-net:mainfrom
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request resolves a bug where the system would perform a full Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Changelog
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Versions may align, But maps can still diverge, Update sets things right. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request changes the start type from "Restart" to "Update" when the binary version matches the previous version, aiming to improve the robustness of the restart process by ensuring BPF maps are reconciled. However, this change introduces a critical nil pointer dereference vulnerability in the UpdateMapHandler function, which can lead to a daemon panic and denial of service if the BPF map state on disk is inconsistent. Additionally, a potential refactoring is needed to address duplicated logic introduced by this change. It is recommended to fix the error handling in UpdateMapHandler before merging.
| log.Infof("kmesh start with Update") | ||
| SetStartType(Update) |
There was a problem hiding this comment.
The change on line 104, which sets the start type to Update when versions match, introduces a critical denial-of-service vulnerability. This causes the daemon to execute UpdateMapHandler during startup, where a nil pointer dereference can occur. Specifically, the error from ebpf.LoadPinnedMap is ignored, meaning oldMap could be nil, leading to a panic when oldMap.Unpin() is called. This can crash the Kmesh daemon if the BPF map state is inconsistent. To remediate this, ensure proper error handling for ebpf.LoadPinnedMap in pkg/bpf/restart/bpf_update.go before accessing oldMap. Additionally, this change introduces code duplication, as the logic in this if block is now identical to the else block on lines 109-112. Consider refactoring the conditional logic to remove this duplication for better maintainability.
There was a problem hiding this comment.
Pull request overview
This PR fixes incorrect startup mode selection for BPF state handling by switching the “same GitVersion” path in SetStartStatus from Restart (blind reuse) to Update (reconcile pinned map state via UpdateMapHandler), aligning behavior with the fact that BPF maps can change independently of the binary version.
Changes:
- Change
SetStartStatusto set start type toUpdate(notRestart) whenGitVersion == oldGitVersion. - Update log message for the “versions match” startup path accordingly.
Comments suppressed due to low confidence (1)
pkg/bpf/restart/bpf_restart.go:112
GitVersion == oldGitVersionno longer affects control flow: both the==branch and the finalelsesetUpdate. This makes the version comparison (and related branching) redundant and potentially confusing for future changes. Consider simplifying to a singleif oldGitVersion == 0 { Normal } else { Update }(while keeping any desired logging) so the intent is explicit.
if GitVersion == oldGitVersion {
log.Infof("kmesh start with Update")
SetStartType(Update)
} else if oldGitVersion == 0 {
// version not found, it is a fresh start
log.Infof("kmesh start with Normal")
SetStartType(Normal)
} else {
log.Infof("kmesh start with Update")
SetStartType(Update)
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if GitVersion == oldGitVersion { | ||
| log.Infof("kmesh start with Restart, load bpf maps and prog from last") | ||
| SetStartType(Restart) | ||
| log.Infof("kmesh start with Update") | ||
| SetStartType(Update) | ||
| } else if oldGitVersion == 0 { |
There was a problem hiding this comment.
With this change, SetStartStatus will never set StartType to Restart when a version map exists (it will be Update for any non-zero oldGitVersion). Downstream code has a case restart.Restart path (e.g., NewVersionMap returns early for Restart), and the existing unit test TestRestart in pkg/bpf/bpf_test.go asserts GetStartType() == restart.Restart on the second start; that will now fail. If the new semantics are intended, please update/remove the Restart start path and adjust tests accordingly (or introduce a different condition that still legitimately yields Restart).
e8c5241 to
2b51151
Compare
2b51151 to
ad62761
Compare
ad62761 to
8b09b57
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
pkg/bpf/workload/sendmsg.go:104
- With SetStartStatus now setting StartType=Update for version matches, this branch will run on common restarts. If the old pinned program at pinPath doesn't exist (e.g., partial/failed previous pin state), LoadPinnedProgram will return an error and abort startup even though there is nothing to unpin. Consider treating a not-exist error as non-fatal (log and continue), so Update can reconcile partial pin state instead of failing hard.
if restart.GetStartType() == restart.Restart || restart.GetStartType() == restart.Update {
pinPath := filepath.Join(sm.Info.BpfFsPath, "sendmsg_prog")
oldSkMsg, err := ebpf.LoadPinnedProgram(pinPath, nil)
if err != nil {
log.Errorf("LoadPinnedProgram failed: %v", err)
return nil, err
}
pkg/bpf/restart/bpf_restart.go:112
- SetStartStatus now sets StartType=Update when the git version matches. Several call sites still gate “restart” behavior on StartType==Restart only (e.g., restoring endpoint keys and preloading cached xDS resources), so those paths will no longer run on version-match restarts. Please audit and either (a) treat Update as restart-like in those checks (e.g.,
Restart || Update), or (b) rework the start-type semantics so Update triggers the same initialization that previously relied on Restart while still running UpdateMapHandler for map reconciliation.
if GitVersion == oldGitVersion {
log.Infof("kmesh start with Update")
SetStartType(Update)
} else if oldGitVersion == 0 {
// version not found, it is a fresh start
log.Infof("kmesh start with Normal")
SetStartType(Normal)
} else {
log.Infof("kmesh start with Update")
SetStartType(Update)
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
Codecov Report❌ Patch coverage is
❌ Your patch check has failed because the patch coverage (0.00%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the target coverage.
... and 2 files with indirect coverage changes Continue to review full report in Codecov by Sentry.
🚀 New features to boost your workflow:
|
8b09b57 to
c88151e
Compare
The version hash only tracks the binary version, not BPF map state. Maps can change independently at runtime, so equal versions do not guarantee maps are unchanged. Use Update which reconciles partial state rather than Restart which blindly reuses everything. Also fix a nil pointer dereference in UpdateMapHandler where LoadPinnedMap error was discarded but oldMap was used unconditionally for Unpin/Close. Signed-off-by: Eeshu-Yadav <eeshuyadav123@gmail.com>
c88151e to
96669db
Compare
What type of PR is this?
/kind bug
What this PR does / why we need it:
SetStartStatusincorrectly sets the start type toRestartwhenGitVersion == oldGitVersion. The version hash only tracks the binary version, not BPF map state — maps can change independently at runtime. Equal versions don't prove maps are unchanged.Changed to
Updatewhich reconciles partial state viaUpdateMapHandler, rather thanRestartwhich blindly reuses everything.Which issue(s) this PR fixes:
Fixes #794