Skip to content

Commit b689d28

Browse files
committed
btf: fix panic when copying nil Type
Copying a nil Type panics since we unconditionally invoke Type.copy(). Fix this and adjust the tests. Signed-off-by: Lorenz Bauer <[email protected]>
1 parent 218b9f9 commit b689d28

File tree

3 files changed

+28
-31
lines changed

3 files changed

+28
-31
lines changed

btf/types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,10 @@ func Copy(typ Type) Type {
682682
}
683683

684684
func copyType(typ Type, ids map[Type]TypeID, copies map[Type]Type, copiedIDs map[Type]TypeID) Type {
685+
if typ == nil {
686+
return nil
687+
}
688+
685689
cpy, ok := copies[typ]
686690
if ok {
687691
// This has been copied previously, no need to continue.

btf/types_test.go

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"reflect"
99
"testing"
1010

11+
"github.com/cilium/ebpf/internal/testutils"
1112
"github.com/go-quicktest/qt"
1213
"github.com/google/go-cmp/cmp"
1314
)
@@ -39,33 +40,31 @@ func TestSizeof(t *testing.T) {
3940
}
4041

4142
func TestCopy(t *testing.T) {
42-
_ = Copy((*Void)(nil))
43+
i := &Int{Size: 4}
4344

44-
in := &Int{Size: 4}
45-
out := Copy(in)
46-
47-
in.Size = 8
48-
if size := out.(*Int).Size; size != 4 {
49-
t.Error("Copy doesn't make a copy, expected size 4, got", size)
50-
}
51-
52-
t.Run("cyclical", func(t *testing.T) {
53-
_ = Copy(newCyclicalType(2))
45+
got := Copy(&Struct{
46+
Members: []Member{
47+
{Name: "a", Type: i},
48+
{Name: "b", Type: i},
49+
},
5450
})
51+
members := got.(*Struct).Members
52+
qt.Check(t, qt.Equals(members[0].Type.(*Int), members[1].Type.(*Int)), qt.Commentf("identity should be preserved"))
5553

56-
t.Run("identity", func(t *testing.T) {
57-
u16 := &Int{Size: 2}
58-
59-
out := Copy(&Struct{
60-
Members: []Member{
61-
{Name: "a", Type: u16},
62-
{Name: "b", Type: u16},
63-
},
54+
for _, test := range []struct {
55+
name string
56+
typ Type
57+
}{
58+
{"nil", nil},
59+
{"void", (*Void)(nil)},
60+
{"int", i},
61+
{"cyclical", newCyclicalType(2)},
62+
} {
63+
t.Run(test.name, func(t *testing.T) {
64+
cpy := Copy(test.typ)
65+
qt.Assert(t, testutils.IsDeepCopy(cpy, test.typ))
6466
})
65-
66-
outStruct := out.(*Struct)
67-
qt.Assert(t, qt.Equals(outStruct.Members[0].Type, outStruct.Members[1].Type))
68-
})
67+
}
6968
}
7069

7170
func TestAs(t *testing.T) {

map.go

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ func (ms *MapSpec) Copy() *MapSpec {
102102

103103
cpy := *ms
104104
cpy.Contents = slices.Clone(cpy.Contents)
105+
cpy.Key = btf.Copy(cpy.Key)
106+
cpy.Value = btf.Copy(cpy.Value)
105107

106108
if cpy.InnerMap == ms {
107109
cpy.InnerMap = &cpy
@@ -114,14 +116,6 @@ func (ms *MapSpec) Copy() *MapSpec {
114116
cpy.Extra = &extra
115117
}
116118

117-
if cpy.Key != nil {
118-
cpy.Key = btf.Copy(cpy.Key)
119-
}
120-
121-
if cpy.Value != nil {
122-
cpy.Value = btf.Copy(cpy.Value)
123-
}
124-
125119
return &cpy
126120
}
127121

0 commit comments

Comments
 (0)