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

fix a variety of Copy() problems #1518

Merged
merged 1 commit into from
Jul 22, 2024
Merged

fix a variety of Copy() problems #1518

merged 1 commit into from
Jul 22, 2024

Conversation

lmb
Copy link
Collaborator

@lmb lmb commented Jul 18, 2024

The are multiple Copy() methods in the code base which are used to create deep copies of a struct. Any bugs in them can manifest as data races in concurrent code.

Add a quicktest checker which ensures that two variables are a deep copy of each other: values match, but all locations in memory differ.

Fix a variety of problems with the existing Copy() implementations. They all allow copying a nil struct and copy all elements.

There are exceptions to the deep copy rule:

  • MapSpec.Contents is not deep copied because we can't easily make copies of interface values. This is documented already.
  • MapSpec.Extra is an immutable bytes.Reader and therefore only needs a shallow copy.
  • ProgramSpec.AttachTarget is a Program, which is (currently) safe for concurrent use.

Fixes #1517

@lmb lmb marked this pull request as ready for review July 18, 2024 12:41
@lmb lmb requested review from dylandreimerink and a team as code owners July 18, 2024 12:41
Copy link
Member

@dylandreimerink dylandreimerink left a comment

Choose a reason for hiding this comment

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

This looks good to me. I was wondering why you decided to roll your own deep equal instead of the std reflect function? Is this better in some way?

The are multiple Copy() methods in the code base which are used to
create deep copies of a struct. Any bugs in them can manifest as
data races in concurrent code.

Add a quicktest checker which ensures that two variables are a
deep copy of each other: values match, but all locations in memory
differ.

Fix a variety of problems with the existing Copy() implementations.
They all allow copying a nil struct and copy all elements.

There are exceptions to the deep copy rule:

- MapSpec.Contents is not deep copied because we can't easily make
  copies of interface values. This is documented already.
- MapSpec.Extra is an immutable bytes.Reader and therefore only
  needs a shallow copy.
- ProgramSpec.AttachTarget is a Program, which is (currently) safe
  for concurrent use.

Fixes cilium#1517

Signed-off-by: Lorenz Bauer <[email protected]>
@lmb
Copy link
Collaborator Author

lmb commented Jul 22, 2024

I added the following comment:

// This is different from [reflect.DeepEqual] which will accept equal pointer values.
// That is, reflect.DeepEqual(a, a) is true, while IsDeepCopy(a, a) is false.

Does that make it clearer?

@dylandreimerink
Copy link
Member

Yep, much better. I figured it would be something like that. 👍

@lmb lmb merged commit a61222d into cilium:main Jul 22, 2024
17 checks passed
@lmb lmb deleted the copy-fixes branch July 22, 2024 09:29
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.

DATA RACE: github.com/cilium/ebpf.(*MapSpec).createMap
2 participants