Skip to content

Comments

fix a variety of Copy() problems#1518

Merged
lmb merged 1 commit intocilium:mainfrom
lmb:copy-fixes
Jul 22, 2024
Merged

fix a variety of Copy() problems#1518
lmb merged 1 commit intocilium:mainfrom
lmb:copy-fixes

Conversation

@lmb
Copy link
Contributor

@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 a team and dylandreimerink 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
Contributor 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
@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