Skip to content
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

policy: Fix potential nil pointer deref in selectorManager.GetSelections #27805

Merged

Conversation

learnitall
Copy link
Contributor

Please ensure your pull request adheres to the following guidelines:

  • For first time contributors, read Submitting a pull request
  • All code is covered by unit and/or runtime tests where feasible.
  • All commits contain a well written commit description including a title,
    description and a Fixes: #XXX line if the commit addresses a particular
    GitHub issue.
  • If your commit description contains a Fixes: <commit-id> tag, then
    please add the commit author[s] as reviewer[s] to this issue.
  • All commits are signed off. See the section Developer’s Certificate of Origin
  • Provide a title or release-note blurb suitable for the release notes.
  • Are you a user of Cilium? Please add yourself to the Users doc
  • Thanks for contributing!

This commit address the case in which selectorManager.GetSelections is called before selectorManager.updateSelections is called, which can cause a panic due to a nil pointer dereference in case the internal selectorManager.selections field is nil. To address this case, if the selectorManager has a nil value for its internal field selections, then emptySelection is returned.

The reason GetSelections cannot modify the internal selections field if it sees that it is nil is because selectorManager.setSelections requires the managing SelectorCache.mutex to be locked. This cannot be guaranteed inside a call to selectorManager.GetSelections, which does not require locking.

This needs to be backported to 1.14, 1.1,3 and 1.12, please. Versions 1.13 and 1.12 will have a merge conflict due to changes made in commit 9397655, which adjusted how the atomic pointer is loaded. The needed change for these versions should look something like this:

diff --git a/pkg/policy/selectorcache.go b/pkg/policy/selectorcache.go
index afcccc054b..a478519cf9 100644
--- a/pkg/policy/selectorcache.go
+++ b/pkg/policy/selectorcache.go
@@ -337,7 +337,12 @@ func (s *selectorManager) Equal(b *selectorManager) bool {
 // of the selections. If the old version is returned, the user is
 // guaranteed to receive a notification including the update.
 func (s *selectorManager) GetSelections() []identity.NumericIdentity {
-       return *(*[]identity.NumericIdentity)(atomic.LoadPointer(&s.selections))
+       selections := (*[]identity.NumericIdentity)(atomic.LoadPointer(&s.selections))
+       if selections == nil {
+               return emptySelection
+       }
+
+       return *selections
 }
 
 // Selects return 'true' if the CachedSelector selects the given
diff --git a/pkg/policy/selectorcache_test.go b/pkg/policy/selectorcache_test.go
index bc2fe04620..8fb47141db 100644
--- a/pkg/policy/selectorcache_test.go
+++ b/pkg/policy/selectorcache_test.go
@@ -610,6 +610,21 @@ func (ds *SelectorCacheTestSuite) TestIdentityUpdatesMultipleUsers(c *C) {
        c.Assert(len(sc.selectors), Equals, 0)
 }
 
+func (ds *SelectorCacheTestSuite) TestSelectorManagerCanGetBeforeSet(c *C) {
+       defer func() {
+               r := recover()
+               c.Assert(r, Equals, nil)
+       }()
+
+       selectorManager := selectorManager{
+               key:              "test",
+               users:            make(map[CachedSelectionUser]struct{}),
+       }
+       selections := selectorManager.GetSelections()
+       c.Assert(selections, Not(Equals), nil)
+       c.Assert(len(selections), Equals, 0)
+}
+
 func testNewSelectorCache(ids cache.IdentityCache) *SelectorCache {
        sc := NewSelectorCache(testidentity.NewMockIdentityAllocator(ids), ids)
        sc.SetLocalIdentityNotifier(testidentity.NewDummyIdentityNotifier())
Fix potential nil pointer dereference in SelectorManager implementation

@maintainer-s-little-helper maintainer-s-little-helper bot added the dont-merge/needs-release-note-label The author needs to describe the release impact of these changes. label Aug 29, 2023
@learnitall learnitall added the release-note/misc This PR makes changes that have no direct user impact. label Aug 29, 2023
@maintainer-s-little-helper maintainer-s-little-helper bot removed the dont-merge/needs-release-note-label The author needs to describe the release impact of these changes. label Aug 29, 2023
@learnitall learnitall added kind/bug This is a bug in the Cilium logic. dont-merge/needs-release-note-label The author needs to describe the release impact of these changes. labels Aug 29, 2023
@maintainer-s-little-helper maintainer-s-little-helper bot removed dont-merge/needs-release-note-label The author needs to describe the release impact of these changes. labels Aug 29, 2023
@learnitall learnitall added dont-merge/needs-release-note-label The author needs to describe the release impact of these changes. affects/v1.12 This issue affects v1.12 branch affects/v1.13 This issue affects v1.13 branch affects/v1.14 This issue affects v1.14 branch labels Aug 29, 2023
@maintainer-s-little-helper maintainer-s-little-helper bot removed the dont-merge/needs-release-note-label The author needs to describe the release impact of these changes. label Aug 29, 2023
@learnitall learnitall added dont-merge/needs-release-note-label The author needs to describe the release impact of these changes. needs-backport/1.12 needs-backport/1.13 This PR / issue needs backporting to the v1.13 branch needs-backport/1.14 This PR / issue needs backporting to the v1.14 branch and removed dont-merge/needs-release-note-label The author needs to describe the release impact of these changes. labels Aug 29, 2023
@maintainer-s-little-helper maintainer-s-little-helper bot added this to Needs backport from main in 1.13.7 Aug 29, 2023
@maintainer-s-little-helper maintainer-s-little-helper bot added this to Needs backport from main in 1.12.14 Aug 29, 2023
@maintainer-s-little-helper maintainer-s-little-helper bot added this to Needs backport from main in 1.14.2 Aug 29, 2023
@learnitall learnitall force-pushed the pr/learnitall/fix-selectorcache-nil-deref branch from 6d5b5c8 to d58943c Compare August 29, 2023 22:36
@learnitall learnitall marked this pull request as ready for review August 30, 2023 14:42
@learnitall learnitall requested a review from a team as a code owner August 30, 2023 14:42
@learnitall learnitall force-pushed the pr/learnitall/fix-selectorcache-nil-deref branch from d58943c to 6c9a536 Compare August 30, 2023 14:42
@learnitall
Copy link
Contributor Author

/test

This commit address the case in which `selectorManager.GetSelections` is
called before `selectorManager.updateSelections` is called, which can
cause a panic due to a nil pointer dereference in case the internal
`selectorManager.selections` field is nil. To address this case, if the
`selectorManager` has a nil value for its internal field `selections`,
then `emptySelection` is returned.

The reason `GetSelections` cannot modify the internal `selections` field
if it sees that it is nil is because `selectorManager.setSelections`
requires the managing `SelectorCache.mutex` to be locked. This cannot be
guaranteed inside a call to `selectorManager.GetSelections`, which does
not require locking.

Signed-off-by: Ryan Drew <ryan.drew@isovalent.com>
@learnitall learnitall force-pushed the pr/learnitall/fix-selectorcache-nil-deref branch from 6c9a536 to 364130c Compare September 7, 2023 16:00
@learnitall
Copy link
Contributor Author

/test

@maintainer-s-little-helper maintainer-s-little-helper bot added the ready-to-merge This PR has passed all tests and received consensus from code owners to merge. label Sep 7, 2023
@youngnick youngnick merged commit 86a6ab9 into cilium:main Sep 8, 2023
61 checks passed
@michi-covalent michi-covalent added this to Needs backport from main in 1.14.3 Sep 9, 2023
@michi-covalent michi-covalent removed this from Needs backport from main in 1.14.2 Sep 9, 2023
@michi-covalent michi-covalent added this to Needs backport from main in 1.13.8 Sep 9, 2023
@michi-covalent michi-covalent removed this from Needs backport from main in 1.13.7 Sep 9, 2023
@michi-covalent michi-covalent added this to Needs backport from main in 1.12.15 Sep 9, 2023
@michi-covalent michi-covalent removed this from Needs backport from main in 1.12.14 Sep 9, 2023
@gandro gandro mentioned this pull request Sep 12, 2023
15 tasks
@gandro gandro added backport-pending/1.14 The backport for Cilium 1.14.x for this PR is in progress. and removed needs-backport/1.14 This PR / issue needs backporting to the v1.14 branch labels Sep 12, 2023
@gandro gandro mentioned this pull request Sep 12, 2023
6 tasks
@gandro gandro added backport-pending/1.13 The backport for Cilium 1.13.x for this PR is in progress. and removed needs-backport/1.13 This PR / issue needs backporting to the v1.13 branch labels Sep 12, 2023
@gandro gandro mentioned this pull request Sep 12, 2023
3 tasks
@julianwiedmann julianwiedmann added backport-done/1.13 The backport for Cilium 1.13.x for this PR is done. backport-done/1.12 The backport for Cilium 1.12.x for this PR is done. and removed backport-pending/1.13 The backport for Cilium 1.13.x for this PR is in progress. backport-pending/1.12 labels Sep 14, 2023
@gandro gandro added backport-done/1.14 The backport for Cilium 1.14.x for this PR is done. and removed backport-pending/1.14 The backport for Cilium 1.14.x for this PR is in progress. labels Sep 25, 2023
@jrajahalme jrajahalme moved this from Needs backport from main to Backport done to v1.13 in 1.13.8 Oct 17, 2023
@jrajahalme jrajahalme removed this from Needs backport from main in 1.12.15 Oct 17, 2023
@jrajahalme jrajahalme removed this from Needs backport from main in 1.14.3 Oct 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
affects/v1.12 This issue affects v1.12 branch affects/v1.13 This issue affects v1.13 branch affects/v1.14 This issue affects v1.14 branch backport-done/1.12 The backport for Cilium 1.12.x for this PR is done. backport-done/1.13 The backport for Cilium 1.13.x for this PR is done. backport-done/1.14 The backport for Cilium 1.14.x for this PR is done. kind/bug This is a bug in the Cilium logic. ready-to-merge This PR has passed all tests and received consensus from code owners to merge. release-note/misc This PR makes changes that have no direct user impact.
Projects
No open projects
1.13.8
Backport done to v1.13
Development

Successfully merging this pull request may close these issues.

None yet

5 participants