Skip to content

Commit b4e38d4

Browse files
committed
bugfix: Use the same selector maps in kprobe-multi
The previous commit shows a test that we have a bug in the case of kprobe-multi, that uses matchArgs where both of these use maps to do equals/prefix/postfix operations. The problem is due to overriding string maps after processing each kprobe. To fix that we use shared maps for all selectors for all attach points in te case of kprobe-multi. Non kprobe-multi cases and tracepoints/uprobes work exactly as before. Signed-off-by: Anastasios Papagiannis <tasos.papagiannnis@gmail.com>
1 parent d385a1b commit b4e38d4

File tree

6 files changed

+45
-31
lines changed

6 files changed

+45
-31
lines changed

pkg/selectors/kernel.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -1258,16 +1258,16 @@ func parseSelector(
12581258
//
12591259
// For some examples, see kernel_test.go
12601260
func InitKernelSelectors(selectors []v1alpha1.KProbeSelector, args []v1alpha1.KProbeArg, actionArgTable *idtable.Table) ([4096]byte, error) {
1261-
kernelSelectors, err := InitKernelSelectorState(selectors, args, actionArgTable, nil)
1261+
kernelSelectors, err := InitKernelSelectorState(selectors, args, actionArgTable, nil, nil)
12621262
if err != nil {
12631263
return [4096]byte{}, err
12641264
}
12651265
return kernelSelectors.e, nil
12661266
}
12671267

12681268
func InitKernelSelectorState(selectors []v1alpha1.KProbeSelector, args []v1alpha1.KProbeArg,
1269-
actionArgTable *idtable.Table, listReader ValueReader) (*KernelSelectorState, error) {
1270-
kernelSelectors := NewKernelSelectorState(listReader)
1269+
actionArgTable *idtable.Table, listReader ValueReader, maps *KernelSelectorMaps) (*KernelSelectorState, error) {
1270+
kernelSelectors := NewKernelSelectorState(listReader, maps)
12711271

12721272
WriteSelectorUint32(kernelSelectors, uint32(len(selectors)))
12731273
soff := make([]uint32, len(selectors))

pkg/selectors/kernel_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ func TestParseMatchArg(t *testing.T) {
221221
}
222222

223223
arg1 := &v1alpha1.ArgSelector{Index: 1, Operator: "Equal", Values: []string{"foobar"}}
224-
k := &KernelSelectorState{off: 0}
224+
k := NewKernelSelectorState(nil, nil)
225225
expected1 := []byte{
226226
0x01, 0x00, 0x00, 0x00, // Index == 1
227227
0x03, 0x00, 0x00, 0x00, // operator == equal
@@ -318,7 +318,7 @@ func TestParseMatchArg(t *testing.T) {
318318
expected3 := append(length, expected1[:]...)
319319
expected3 = append(expected3, expected2[:]...)
320320
arg12 := []v1alpha1.ArgSelector{*arg1, *arg2}
321-
ks := &KernelSelectorState{off: 0}
321+
ks := NewKernelSelectorState(nil, nil)
322322
if err := ParseMatchArgs(ks, arg12, sig); err != nil || bytes.Equal(expected3, ks.e[0:ks.off]) == false {
323323
t.Errorf("parseMatchArgs: error %v expected:\n%v\nbytes:\n%v\nparsing %v\n", err, expected3, ks.e[0:k.off], arg3)
324324
}

pkg/selectors/selectors.go

+29-21
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,15 @@ type KernelLPMTrieStringPostfix struct {
7575
data [StringPostfixMaxLength]byte
7676
}
7777

78+
type KernelSelectorMaps struct {
79+
// stringMaps are used to populate string and char buf matches
80+
stringMaps StringMapLists
81+
// stringPrefixMaps are used to populate string and char buf prefix matches
82+
stringPrefixMaps []map[KernelLPMTrieStringPrefix]struct{}
83+
// stringPostfixMaps are used to populate string and char buf postfix matches
84+
stringPostfixMaps []map[KernelLPMTrieStringPostfix]struct{}
85+
}
86+
7887
type KernelSelectorState struct {
7988
off uint32 // offset into encoding
8089
e [4096]byte // kernel encoding of selectors
@@ -92,20 +101,19 @@ type KernelSelectorState struct {
92101
newBinVals map[uint32]string // these should be added in the names_map
93102

94103
listReader ValueReader
95-
// stringMaps are used to populate string and char buf matches
96-
stringMaps StringMapLists
97104

98-
// stringPrefixMaps are used to populate string and char buf prefix matches
99-
stringPrefixMaps []map[KernelLPMTrieStringPrefix]struct{}
100-
// stringPostfixMaps are used to populate string and char buf postfix matches
101-
stringPostfixMaps []map[KernelLPMTrieStringPostfix]struct{}
105+
maps *KernelSelectorMaps
102106
}
103107

104-
func NewKernelSelectorState(listReader ValueReader) *KernelSelectorState {
108+
func NewKernelSelectorState(listReader ValueReader, maps *KernelSelectorMaps) *KernelSelectorState {
109+
if maps == nil {
110+
maps = &KernelSelectorMaps{}
111+
}
105112
return &KernelSelectorState{
106113
matchBinaries: make(map[int]*MatchBinariesMappings),
107114
newBinVals: make(map[uint32]string),
108115
listReader: listReader,
116+
maps: maps,
109117
}
110118
}
111119

@@ -165,15 +173,15 @@ func (k *KernelSelectorState) Addr6Maps() []map[KernelLPMTrie6]struct{} {
165173
}
166174

167175
func (k *KernelSelectorState) StringMaps(subMap int) []map[[MaxStringMapsSize]byte]struct{} {
168-
return k.stringMaps[subMap]
176+
return k.maps.stringMaps[subMap]
169177
}
170178

171179
func (k *KernelSelectorState) StringPrefixMaps() []map[KernelLPMTrieStringPrefix]struct{} {
172-
return k.stringPrefixMaps
180+
return k.maps.stringPrefixMaps
173181
}
174182

175183
func (k *KernelSelectorState) StringPostfixMaps() []map[KernelLPMTrieStringPostfix]struct{} {
176-
return k.stringPostfixMaps
184+
return k.maps.stringPostfixMaps
177185
}
178186

179187
// ValueMapsMaxEntries returns the maximum entries over all maps
@@ -212,7 +220,7 @@ func (k *KernelSelectorState) Addr6MapsMaxEntries() int {
212220
// StringMapsMaxEntries returns the maximum entries over all maps inside a particular map of map
213221
func (k *KernelSelectorState) StringMapsMaxEntries(subMap int) int {
214222
maxEntries := 1
215-
for _, vm := range k.stringMaps[subMap] {
223+
for _, vm := range k.maps.stringMaps[subMap] {
216224
if l := len(vm); l > maxEntries {
217225
maxEntries = l
218226
}
@@ -223,7 +231,7 @@ func (k *KernelSelectorState) StringMapsMaxEntries(subMap int) int {
223231
// StringPrefixMapsMaxEntries returns the maximum entries over all maps
224232
func (k *KernelSelectorState) StringPrefixMapsMaxEntries() int {
225233
maxEntries := 1
226-
for _, vm := range k.stringPrefixMaps {
234+
for _, vm := range k.maps.stringPrefixMaps {
227235
if l := len(vm); l > maxEntries {
228236
maxEntries = l
229237
}
@@ -234,7 +242,7 @@ func (k *KernelSelectorState) StringPrefixMapsMaxEntries() int {
234242
// StringPostfixMapsMaxEntries returns the maximum entries over all maps
235243
func (k *KernelSelectorState) StringPostfixMapsMaxEntries() int {
236244
maxEntries := 1
237-
for _, vm := range k.stringPostfixMaps {
245+
for _, vm := range k.maps.stringPostfixMaps {
238246
if l := len(vm); l > maxEntries {
239247
maxEntries = l
240248
}
@@ -402,8 +410,8 @@ func (k *KernelSelectorState) insertStringMaps(stringMaps SelectorStringMaps) [S
402410

403411
for subMap := 0; subMap < StringMapsNumSubMaps; subMap++ {
404412
if len(stringMaps[subMap]) > 0 {
405-
mapid = uint32(len(k.stringMaps[subMap]))
406-
k.stringMaps[subMap] = append(k.stringMaps[subMap], stringMaps[subMap])
413+
mapid = uint32(len(k.maps.stringMaps[subMap]))
414+
k.maps.stringMaps[subMap] = append(k.maps.stringMaps[subMap], stringMaps[subMap])
407415
} else {
408416
mapid = 0xffffffff
409417
}
@@ -414,13 +422,13 @@ func (k *KernelSelectorState) insertStringMaps(stringMaps SelectorStringMaps) [S
414422
}
415423

416424
func (k *KernelSelectorState) newStringPrefixMap() (uint32, map[KernelLPMTrieStringPrefix]struct{}) {
417-
mapid := len(k.stringPrefixMaps)
418-
k.stringPrefixMaps = append(k.stringPrefixMaps, map[KernelLPMTrieStringPrefix]struct{}{})
419-
return uint32(mapid), k.stringPrefixMaps[mapid]
425+
mapid := len(k.maps.stringPrefixMaps)
426+
k.maps.stringPrefixMaps = append(k.maps.stringPrefixMaps, map[KernelLPMTrieStringPrefix]struct{}{})
427+
return uint32(mapid), k.maps.stringPrefixMaps[mapid]
420428
}
421429

422430
func (k *KernelSelectorState) newStringPostfixMap() (uint32, map[KernelLPMTrieStringPostfix]struct{}) {
423-
mapid := len(k.stringPostfixMaps)
424-
k.stringPostfixMaps = append(k.stringPostfixMaps, map[KernelLPMTrieStringPostfix]struct{}{})
425-
return uint32(mapid), k.stringPostfixMaps[mapid]
431+
mapid := len(k.maps.stringPostfixMaps)
432+
k.maps.stringPostfixMaps = append(k.maps.stringPostfixMaps, map[KernelLPMTrieStringPostfix]struct{}{})
433+
return uint32(mapid), k.maps.stringPostfixMaps[mapid]
426434
}

pkg/sensors/tracing/generickprobe.go

+9-3
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,7 @@ func createGenericKprobeSensor(
518518
}
519519

520520
addedKprobeIndices := []int{}
521+
selMaps := &selectors.KernelSelectorMaps{}
521522
for i := range kprobes {
522523
syms, syscall, err := getKprobeSymbols(kprobes[i].Call, kprobes[i].Syscall, lists)
523524
if err != nil {
@@ -528,7 +529,12 @@ func createGenericKprobeSensor(
528529
kprobes[i].Syscall = syscall
529530

530531
for idx := range syms {
531-
out, err := addKprobe(syms[idx], &kprobes[i], &in)
532+
// if we use kprobe-multi, we need to share the maps.
533+
// Otherwise, we create new ones.
534+
if !useMulti {
535+
selMaps = &selectors.KernelSelectorMaps{}
536+
}
537+
out, err := addKprobe(syms[idx], &kprobes[i], &in, selMaps)
532538
if err != nil {
533539
return nil, err
534540
}
@@ -581,7 +587,7 @@ func createGenericKprobeSensor(
581587
// addKprobe will, amongst other things, create a generic kprobe entry and add
582588
// it to the genericKprobeTable. The caller should make sure that this entry is
583589
// properly removed on kprobe unload.
584-
func addKprobe(funcName string, f *v1alpha1.KProbeSpec, in *addKprobeIn) (out *addKprobeOut, err error) {
590+
func addKprobe(funcName string, f *v1alpha1.KProbeSpec, in *addKprobeIn, selMaps *selectors.KernelSelectorMaps) (out *addKprobeOut, err error) {
585591
var argSigPrinters []argPrinters
586592
var argReturnPrinters []argPrinters
587593
var setRetprobe bool
@@ -747,7 +753,7 @@ func addKprobe(funcName string, f *v1alpha1.KProbeSpec, in *addKprobeIn) (out *a
747753
}
748754

749755
// Parse Filters into kernel filter logic
750-
kprobeEntry.loadArgs.selectors, err = selectors.InitKernelSelectorState(f.Selectors, f.Args, &kprobeEntry.actionArgs, nil)
756+
kprobeEntry.loadArgs.selectors, err = selectors.InitKernelSelectorState(f.Selectors, f.Args, &kprobeEntry.actionArgs, nil, selMaps)
751757
if err != nil {
752758
return nil, err
753759
}

pkg/sensors/tracing/generictracepoint.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,7 @@ func (tp *genericTracepoint) InitKernelSelectors(lists []v1alpha1.ListSpec) erro
508508
}
509509
}
510510

511-
selectors, err := selectors.InitKernelSelectorState(selSelectors, selArgs, &tp.actionArgs, &listReader{lists})
511+
selectors, err := selectors.InitKernelSelectorState(selSelectors, selArgs, &tp.actionArgs, &listReader{lists}, nil)
512512
if err != nil {
513513
return err
514514
}

pkg/sensors/tracing/genericuprobe.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ func createGenericUprobeSensor(
200200
}
201201

202202
// Parse Filters into kernel filter logic
203-
uprobeSelectorState, err := selectors.InitKernelSelectorState(spec.Selectors, args, nil, nil)
203+
uprobeSelectorState, err := selectors.InitKernelSelectorState(spec.Selectors, args, nil, nil, nil)
204204
if err != nil {
205205
return nil, err
206206
}

0 commit comments

Comments
 (0)