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

OCPBUGS-1428: Fix service account token secret reference #2862

Merged
merged 1 commit into from
Sep 21, 2022

Conversation

awgreene
Copy link
Member

Problem: The filterSecretsBySAName function attempts to identify all service account token secrets related to a serviceAccount. To do so, the filterSecretsBySAName function uses a range-for loop to iterate over entries in the secrets argument. If a valid service account token secret is found, a pointer to the range-for loop's value variable is added to a map of results. Unfortunately, if a valid entry is found in the middle of the list of secrets, the value returned by the range-for loop is updated, causes the entry in the map to change.

Solution: Add a pointer to the actual secret instead of the range-for loop's value variable.

Signed-off-by: Alexander Greene [email protected]

@openshift-ci
Copy link

openshift-ci bot commented Sep 15, 2022

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: awgreene

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

The pull request process is described here

Needs approval from an approver in each of these files:

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

@openshift-ci openshift-ci bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Sep 15, 2022
annotations := ref.GetAnnotations()
value := annotations[corev1.ServiceAccountNameKey]
if value == saName {
secretMap[ref.Name] = &ref
secretMap[ref.Name] = &secrets.Items[i]
Copy link
Member Author

Choose a reason for hiding this comment

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

We could use a deepCopy here:

  • Pro: Object in the client cache isn't returned. As it is, users should never edit the secrets returned by this function for risk of concurrent map writes. Also prevents changes to these secrets if updated on cluster.
  • Con: Memory footprint.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'd vote for DeepCopy here since we potentially leave ourselves open to race conditions in the future where the secrets list gets changed on cluster in the middle of this operation. In that case, we could output a reference that is invalid. How big of an extra memory footprint are we thinking here?

Copy link
Member

Choose a reason for hiding this comment

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

The canonical solution I've seen (and typically use) for this is:

for _, ref := range secrets.Items {
	ref := ref
	...
}

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm for this.

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated per @joelanford's suggestion, but moved it inside the if statement.

Comment on lines 84 to 96
for i, ref := range secrets.Items {
annotations := ref.GetAnnotations()
value := annotations[corev1.ServiceAccountNameKey]
if value == saName {
secretMap[ref.Name] = &ref
secretMap[ref.Name] = &secrets.Items[i]
}
}
Copy link
Member Author

Choose a reason for hiding this comment

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

I created this go playground code to showcase the issue.

@awgreene awgreene force-pushed the zsecret branch 3 times, most recently from 1dc817b to 51b5854 Compare September 15, 2022 13:56
@tylerslaton
Copy link
Contributor

Looks like we need to rebase. Then I'll LGTM.

Copy link
Member

@timflannagan timflannagan left a comment

Choose a reason for hiding this comment

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

Is there an issue link tracking this bug or was this discovered naturally?

@tylerslaton
Copy link
Contributor

@timflannagan Yes, it is 2094303 in BZ and that produced a new bug in Jira with an ID of 1428.

Problem: The filterSecretsBySAName function attempts to identify all
service account token secrets related to a serviceAccount. To do so,
the filterSecretsBySAName function uses a range-for loop to iterate
over entries in the secrets argument. If a valid service account token
secret is found, a pointer to the range-for loop's value variable is
added to a map of results. Unfortunately, if a valid entry is found in
the middle of the list of secrets, the value returned by the range-for
loop is updated, causes the entry in the map to change.

Solution: Add a pointer to the actual secret instead of the range-for
loop's value variable.

Signed-off-by: Alexander Greene <[email protected]>
@awgreene awgreene changed the title (bug) Fix service account token secret reference OCPBUGS-1428: Fix service account token secret reference Sep 21, 2022
@openshift-ci-robot openshift-ci-robot added the jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. label Sep 21, 2022
@openshift-ci-robot
Copy link
Collaborator

@awgreene: This pull request references Jira Issue OCPBUGS-1428, which is invalid:

  • expected the bug to target the "4.12.0" version, but no target version was set

Comment /jira refresh to re-evaluate validity if changes to the Jira bug are made, or edit the title of this pull request to link to a different bug.

The bug has been updated to refer to the pull request using the external bug tracker.

In response to this:

Problem: The filterSecretsBySAName function attempts to identify all service account token secrets related to a serviceAccount. To do so, the filterSecretsBySAName function uses a range-for loop to iterate over entries in the secrets argument. If a valid service account token secret is found, a pointer to the range-for loop's value variable is added to a map of results. Unfortunately, if a valid entry is found in the middle of the list of secrets, the value returned by the range-for loop is updated, causes the entry in the map to change.

Solution: Add a pointer to the actual secret instead of the range-for loop's value variable.

Signed-off-by: Alexander Greene [email protected]

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/test-infra repository.

@awgreene
Copy link
Member Author

/jira refresh

@openshift-ci-robot openshift-ci-robot added jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. bugzilla/valid-bug Indicates that a referenced Bugzilla bug is valid for the branch this PR is targeting. labels Sep 21, 2022
@openshift-ci-robot
Copy link
Collaborator

@awgreene: This pull request references Jira Issue OCPBUGS-1428, which is valid. The bug has been moved to the POST state.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target version (4.12.0) matches configured target version for branch (4.12.0)
  • bug is in the state New, which is one of the valid states (NEW, ASSIGNED, POST)

Requesting review from QA contact:
/cc @Xia-Zhao-rh

In response to this:

/jira refresh

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/test-infra repository.

@openshift-ci-robot openshift-ci-robot removed the jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. label Sep 21, 2022
@openshift-ci
Copy link

openshift-ci bot commented Sep 21, 2022

@openshift-ci-robot: GitHub didn't allow me to request PR reviews from the following users: Xia-Zhao-rh.

Note that only operator-framework members and repo collaborators can review this PR, and authors cannot review their own PRs.

In response to this:

@awgreene: This pull request references Jira Issue OCPBUGS-1428, which is valid. The bug has been moved to the POST state.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target version (4.12.0) matches configured target version for branch (4.12.0)
  • bug is in the state New, which is one of the valid states (NEW, ASSIGNED, POST)

Requesting review from QA contact:
/cc @Xia-Zhao-rh

In response to this:

/jira refresh

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/test-infra repository.

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/test-infra repository.

@awgreene
Copy link
Member Author

/retest

// the secret stored in the map will change if there are more
// entries in the list of secrets that the range-for loop is
// iterating over.
ref := ref
Copy link
Contributor

Choose a reason for hiding this comment

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

I really prefer not forcing unintuitive inner/outer variable collisions to avoid this.
I'll LGTM, but IMHO the better approach is to use a non-colliding loop-scoped variable with a note.
I concede that this yields a better code delta, but if it requires a substantial comment like the one provided, is it really an improvement?

Copy link
Member Author

Choose a reason for hiding this comment

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

This has already merged, but I 100% agree with the sentiment.

In this case, @joelanford pointed out that this is the canonical solution that he usually sees to address this intuitive problem. As you said, we could create our own way of avoiding the issue and forego the comment, but I would rather:

  • Adhere to standards found in multiple go projects.
  • Not "hide" the problem by coming up with our own solution.
  • Document the reason for the approach with a comment so our team is aware of this pattern and can apply it when writing/reviewing code later.

Again, I don't know that I would have supported this approach had I been there when the pattern was created, but now that it is established I will respect it.

@grokspawn
Copy link
Contributor

/lgtm

@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Sep 21, 2022
@openshift-merge-robot openshift-merge-robot merged commit caab6c5 into operator-framework:master Sep 21, 2022
@openshift-ci-robot
Copy link
Collaborator

@awgreene: All pull requests linked via external trackers have merged:

Jira Issue OCPBUGS-1428 has been moved to the MODIFIED state.

In response to this:

Problem: The filterSecretsBySAName function attempts to identify all service account token secrets related to a serviceAccount. To do so, the filterSecretsBySAName function uses a range-for loop to iterate over entries in the secrets argument. If a valid service account token secret is found, a pointer to the range-for loop's value variable is added to a map of results. Unfortunately, if a valid entry is found in the middle of the list of secrets, the value returned by the range-for loop is updated, causes the entry in the map to change.

Solution: Add a pointer to the actual secret instead of the range-for loop's value variable.

Signed-off-by: Alexander Greene [email protected]

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/test-infra repository.

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. bugzilla/valid-bug Indicates that a referenced Bugzilla bug is valid for the branch this PR is targeting. jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. lgtm Indicates that a PR is ready to be merged.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants