From b2c0801ac0f2650249a0d9a0754d2596cfb3b948 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 16 Jun 2024 19:59:04 +0000 Subject: [PATCH 01/35] tetragon: Add PinPath to Map object Adding PinPath to Map object to carry path relative to the sysfs bpf root tetragon tree. At the moment we have map's Name as a real (bpf object) name and PinName when we need to pin map under different name. The PinName will be removed once we move to new hierarchy structure, but we still need to keep the relative pinned path of the map. Signed-off-by: Jiri Olsa --- pkg/sensors/load.go | 7 ++++++- pkg/sensors/program/loader.go | 4 ++-- pkg/sensors/program/map.go | 3 ++- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/pkg/sensors/load.go b/pkg/sensors/load.go index 87bb1c7cc56..efdb4651a7a 100644 --- a/pkg/sensors/load.go +++ b/pkg/sensors/load.go @@ -209,6 +209,10 @@ func (s *Sensor) FindPrograms() error { return nil } +func (s *Sensor) setMapPinPath(m *program.Map) { + m.PinPath = m.PinName +} + // loadMaps loads all the BPF maps in the sensor. func (s *Sensor) loadMaps(bpfDir string) error { l := logger.GetLogger() @@ -222,7 +226,8 @@ func (s *Sensor) loadMaps(bpfDir string) error { continue } - pinPath := filepath.Join(bpfDir, m.PinName) + s.setMapPinPath(m) + pinPath := filepath.Join(bpfDir, m.PinPath) spec, err := ebpf.LoadCollectionSpec(m.Prog.Name) if err != nil { diff --git a/pkg/sensors/program/loader.go b/pkg/sensors/program/loader.go index b904f2b1334..a46fb14b9eb 100644 --- a/pkg/sensors/program/loader.go +++ b/pkg/sensors/program/loader.go @@ -732,7 +732,7 @@ func installTailCalls(bpfDir string, spec *ebpf.CollectionSpec, coll *ebpf.Colle } if load.TcMap != nil { - if err := install(load.TcMap.PinName, load.TcPrefix); err != nil { + if err := install(load.TcMap.PinPath, load.TcPrefix); err != nil { return err } } @@ -817,7 +817,7 @@ func doLoadProgram( var err error var mapPath string if pm, ok := load.PinMap[name]; ok { - mapPath = filepath.Join(bpfDir, pm.PinName) + mapPath = filepath.Join(bpfDir, pm.PinPath) } else { mapPath = filepath.Join(bpfDir, name) } diff --git a/pkg/sensors/program/map.go b/pkg/sensors/program/map.go index e7c17bfdcc7..19b941302c6 100644 --- a/pkg/sensors/program/map.go +++ b/pkg/sensors/program/map.go @@ -23,6 +23,7 @@ type MaxEntries struct { type Map struct { Name string PinName string + PinPath string Prog *Program PinState State MapHandle *ebpf.Map @@ -44,7 +45,7 @@ type Map struct { // ... // p.PinMap["mapX"] = &mapX func mapBuilder(name, pin string, lds ...*Program) *Map { - m := &Map{name, pin, lds[0], Idle(), nil, MaxEntries{0, false}, MaxEntries{0, false}} + m := &Map{name, pin, "", lds[0], Idle(), nil, MaxEntries{0, false}, MaxEntries{0, false}} for _, ld := range lds { ld.PinMap[name] = m } From 8cb85c00066e716f7dfe062579c3256a29e40feb Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 24 Feb 2024 19:46:17 +0000 Subject: [PATCH 02/35] tetragon: Use map pin path for MapLoad interface We provide sysfs bpf tetragon root path as pinPathPrefix to the MapLoad's Load function, so we can provide pin path to possible inner maps that get loaded. We are going to introduce new sysfs hierarchy in following changes, where each map can be placed in specific directory, so the sysfs root is no longer enough. Passing map's PinPath through Load's function directly. Signed-off-by: Jiri Olsa --- pkg/sensors/program/loader.go | 6 +++- pkg/sensors/program/program.go | 2 +- pkg/sensors/tracing/generickprobe.go | 6 ++-- pkg/sensors/tracing/genericlsm.go | 4 +-- pkg/sensors/tracing/generictracepoint.go | 4 +-- pkg/sensors/tracing/genericuprobe.go | 8 ++--- pkg/sensors/tracing/selectors.go | 40 ++++++++++++------------ 7 files changed, 37 insertions(+), 33 deletions(-) diff --git a/pkg/sensors/program/loader.go b/pkg/sensors/program/loader.go index a46fb14b9eb..87281d5e9c3 100644 --- a/pkg/sensors/program/loader.go +++ b/pkg/sensors/program/loader.go @@ -869,8 +869,12 @@ func doLoadProgram( } for _, mapLoad := range load.MapLoad { + pinPath := "" + if pm, ok := load.PinMap[mapLoad.Name]; ok { + pinPath = pm.PinPath + } if m, ok := coll.Maps[mapLoad.Name]; ok { - if err := mapLoad.Load(m, mapLoad.Index); err != nil { + if err := mapLoad.Load(m, pinPath, mapLoad.Index); err != nil { return nil, err } } else { diff --git a/pkg/sensors/program/program.go b/pkg/sensors/program/program.go index e52cc796761..e894e8f1804 100644 --- a/pkg/sensors/program/program.go +++ b/pkg/sensors/program/program.go @@ -43,7 +43,7 @@ func GetProgramInfo(l *Program) (program, label, prog string) { type MapLoad struct { Index uint32 Name string - Load func(m *ebpf.Map, index uint32) error + Load func(m *ebpf.Map, pinPathPrefix string, index uint32) error } type MultiKprobeAttachData struct { diff --git a/pkg/sensors/tracing/generickprobe.go b/pkg/sensors/tracing/generickprobe.go index a4c4fbff7b8..b4702905092 100644 --- a/pkg/sensors/tracing/generickprobe.go +++ b/pkg/sensors/tracing/generickprobe.go @@ -1062,7 +1062,7 @@ func getMapLoad(load *program.Program, kprobeEntry *genericKprobe, index uint32) if state == nil { return []*program.MapLoad{} } - return selectorsMaploads(state, kprobeEntry.pinPathPrefix, index) + return selectorsMaploads(state, index) } func loadSingleKprobeSensor(id idtable.EntryID, bpfDir string, load *program.Program, verbose int) error { @@ -1078,7 +1078,7 @@ func loadSingleKprobeSensor(id idtable.EntryID, bpfDir string, load *program.Pro config := &program.MapLoad{ Index: 0, Name: "config_map", - Load: func(m *ebpf.Map, index uint32) error { + Load: func(m *ebpf.Map, _ string, index uint32) error { return m.Update(index, configData.Bytes()[:], ebpf.UpdateAny) }, } @@ -1110,7 +1110,7 @@ func loadMultiKprobeSensor(ids []idtable.EntryID, bpfDir string, load *program.P config := &program.MapLoad{ Index: uint32(index), Name: "config_map", - Load: func(m *ebpf.Map, index uint32) error { + Load: func(m *ebpf.Map, _ string, index uint32) error { return m.Update(index, bin_buf[index].Bytes()[:], ebpf.UpdateAny) }, } diff --git a/pkg/sensors/tracing/genericlsm.go b/pkg/sensors/tracing/genericlsm.go index fff5316cd92..a003ae00965 100644 --- a/pkg/sensors/tracing/genericlsm.go +++ b/pkg/sensors/tracing/genericlsm.go @@ -85,13 +85,13 @@ func (k *observerLsmSensor) LoadProbe(args sensors.LoadProbeArgs) error { if err != nil { return err } - args.Load.MapLoad = append(args.Load.MapLoad, selectorsMaploads(gl.selectors, gl.pinPathPrefix, 0)...) + args.Load.MapLoad = append(args.Load.MapLoad, selectorsMaploads(gl.selectors, 0)...) var configData bytes.Buffer binary.Write(&configData, binary.LittleEndian, gl.config) config := &program.MapLoad{ Index: 0, Name: "config_map", - Load: func(m *ebpf.Map, index uint32) error { + Load: func(m *ebpf.Map, _ string, index uint32) error { return m.Update(index, configData.Bytes()[:], ebpf.UpdateAny) }, } diff --git a/pkg/sensors/tracing/generictracepoint.go b/pkg/sensors/tracing/generictracepoint.go index a81ec1541fd..150a981f81a 100644 --- a/pkg/sensors/tracing/generictracepoint.go +++ b/pkg/sensors/tracing/generictracepoint.go @@ -614,7 +614,7 @@ func LoadGenericTracepointSensor(bpfDir string, load *program.Program, verbose i return fmt.Errorf("Could not find generic tracepoint information for %s: %w", load.Attach, err) } - load.MapLoad = append(load.MapLoad, selectorsMaploads(tp.selectors, tp.pinPathPrefix, 0)...) + load.MapLoad = append(load.MapLoad, selectorsMaploads(tp.selectors, 0)...) config, err := tp.EventConfig() if err != nil { @@ -625,7 +625,7 @@ func LoadGenericTracepointSensor(bpfDir string, load *program.Program, verbose i cfg := &program.MapLoad{ Index: 0, Name: "config_map", - Load: func(m *ebpf.Map, index uint32) error { + Load: func(m *ebpf.Map, _ string, index uint32) error { return m.Update(index, binBuf.Bytes()[:], ebpf.UpdateAny) }, } diff --git a/pkg/sensors/tracing/genericuprobe.go b/pkg/sensors/tracing/genericuprobe.go index e7eca3e7c1e..cdc4db58986 100644 --- a/pkg/sensors/tracing/genericuprobe.go +++ b/pkg/sensors/tracing/genericuprobe.go @@ -129,14 +129,14 @@ func loadSingleUprobeSensor(uprobeEntry *genericUprobe, args sensors.LoadProbeAr { Index: 0, Name: "config_map", - Load: func(m *ebpf.Map, index uint32) error { + Load: func(m *ebpf.Map, _ string, index uint32) error { return m.Update(index, configData.Bytes()[:], ebpf.UpdateAny) }, }, { Index: 0, Name: "filter_map", - Load: func(m *ebpf.Map, index uint32) error { + Load: func(m *ebpf.Map, _ string, index uint32) error { return m.Update(index, selBuff[:], ebpf.UpdateAny) }, }, @@ -175,14 +175,14 @@ func loadMultiUprobeSensor(ids []idtable.EntryID, args sensors.LoadProbeArgs) er { Index: uint32(index), Name: "config_map", - Load: func(m *ebpf.Map, index uint32) error { + Load: func(m *ebpf.Map, _ string, index uint32) error { return m.Update(index, configData.Bytes()[:], ebpf.UpdateAny) }, }, { Index: uint32(index), Name: "filter_map", - Load: func(m *ebpf.Map, index uint32) error { + Load: func(m *ebpf.Map, _ string, index uint32) error { return m.Update(index, selBuff[:], ebpf.UpdateAny) }, }, diff --git a/pkg/sensors/tracing/selectors.go b/pkg/sensors/tracing/selectors.go index 06f432c803a..2236214256d 100644 --- a/pkg/sensors/tracing/selectors.go +++ b/pkg/sensors/tracing/selectors.go @@ -16,103 +16,103 @@ import ( "github.com/cilium/tetragon/pkg/sensors/program" ) -func selectorsMaploads(ks *selectors.KernelSelectorState, pinPathPrefix string, index uint32) []*program.MapLoad { +func selectorsMaploads(ks *selectors.KernelSelectorState, index uint32) []*program.MapLoad { selBuff := ks.Buffer() maps := []*program.MapLoad{ { Index: index, Name: "filter_map", - Load: func(m *ebpf.Map, index uint32) error { + Load: func(m *ebpf.Map, _ string, index uint32) error { return m.Update(index, selBuff[:], ebpf.UpdateAny) }, }, { Index: 0, Name: "argfilter_maps", - Load: func(outerMap *ebpf.Map, _ uint32) error { + Load: func(outerMap *ebpf.Map, pinPathPrefix string, _ uint32) error { return populateArgFilterMaps(ks, pinPathPrefix, outerMap) }, }, { Index: 0, Name: "addr4lpm_maps", - Load: func(outerMap *ebpf.Map, _ uint32) error { + Load: func(outerMap *ebpf.Map, pinPathPrefix string, _ uint32) error { return populateAddr4FilterMaps(ks, pinPathPrefix, outerMap) }, }, { Index: 0, Name: "addr6lpm_maps", - Load: func(outerMap *ebpf.Map, _ uint32) error { + Load: func(outerMap *ebpf.Map, pinPathPrefix string, _ uint32) error { return populateAddr6FilterMaps(ks, pinPathPrefix, outerMap) }, }, { Index: 0, Name: "tg_mb_sel_opts", - Load: func(outerMap *ebpf.Map, _ uint32) error { + Load: func(outerMap *ebpf.Map, _ string, _ uint32) error { return populateMatchBinariesMaps(ks, outerMap) }, }, { Index: 0, Name: "tg_mb_paths", - Load: func(outerMap *ebpf.Map, _ uint32) error { + Load: func(outerMap *ebpf.Map, pinPathPrefix string, _ uint32) error { return populateMatchBinariesPathsMaps(ks, pinPathPrefix, outerMap) }, }, { Index: 0, Name: "string_prefix_maps", - Load: func(outerMap *ebpf.Map, _ uint32) error { + Load: func(outerMap *ebpf.Map, pinPathPrefix string, _ uint32) error { return populateStringPrefixFilterMaps(ks, pinPathPrefix, outerMap) }, }, { Index: 0, Name: "string_postfix_maps", - Load: func(outerMap *ebpf.Map, _ uint32) error { + Load: func(outerMap *ebpf.Map, pinPathPrefix string, _ uint32) error { return populateStringPostfixFilterMaps(ks, pinPathPrefix, outerMap) }, }, { Index: 0, Name: "string_maps_0", - Load: func(outerMap *ebpf.Map, _ uint32) error { + Load: func(outerMap *ebpf.Map, pinPathPrefix string, _ uint32) error { return populateStringFilterMaps(ks, pinPathPrefix, outerMap, 0) }, }, { Index: 0, Name: "string_maps_1", - Load: func(outerMap *ebpf.Map, _ uint32) error { + Load: func(outerMap *ebpf.Map, pinPathPrefix string, _ uint32) error { return populateStringFilterMaps(ks, pinPathPrefix, outerMap, 1) }, }, { Index: 0, Name: "string_maps_2", - Load: func(outerMap *ebpf.Map, _ uint32) error { + Load: func(outerMap *ebpf.Map, pinPathPrefix string, _ uint32) error { return populateStringFilterMaps(ks, pinPathPrefix, outerMap, 2) }, }, { Index: 0, Name: "string_maps_3", - Load: func(outerMap *ebpf.Map, _ uint32) error { + Load: func(outerMap *ebpf.Map, pinPathPrefix string, _ uint32) error { return populateStringFilterMaps(ks, pinPathPrefix, outerMap, 3) }, }, { Index: 0, Name: "string_maps_4", - Load: func(outerMap *ebpf.Map, _ uint32) error { + Load: func(outerMap *ebpf.Map, pinPathPrefix string, _ uint32) error { return populateStringFilterMaps(ks, pinPathPrefix, outerMap, 4) }, }, { Index: 0, Name: "string_maps_5", - Load: func(outerMap *ebpf.Map, _ uint32) error { + Load: func(outerMap *ebpf.Map, pinPathPrefix string, _ uint32) error { return populateStringFilterMaps(ks, pinPathPrefix, outerMap, 5) }, }, { Index: 0, Name: "string_maps_6", - Load: func(outerMap *ebpf.Map, _ uint32) error { + Load: func(outerMap *ebpf.Map, pinPathPrefix string, _ uint32) error { return populateStringFilterMaps(ks, pinPathPrefix, outerMap, 6) }, }, { Index: 0, Name: "string_maps_7", - Load: func(outerMap *ebpf.Map, _ uint32) error { + Load: func(outerMap *ebpf.Map, pinPathPrefix string, _ uint32) error { return populateStringFilterMaps(ks, pinPathPrefix, outerMap, 7) }, }, @@ -122,19 +122,19 @@ func selectorsMaploads(ks *selectors.KernelSelectorState, pinPathPrefix string, { Index: 0, Name: "string_maps_8", - Load: func(outerMap *ebpf.Map, _ uint32) error { + Load: func(outerMap *ebpf.Map, pinPathPrefix string, _ uint32) error { return populateStringFilterMaps(ks, pinPathPrefix, outerMap, 8) }, }, { Index: 0, Name: "string_maps_9", - Load: func(outerMap *ebpf.Map, _ uint32) error { + Load: func(outerMap *ebpf.Map, pinPathPrefix string, _ uint32) error { return populateStringFilterMaps(ks, pinPathPrefix, outerMap, 9) }, }, { Index: 0, Name: "string_maps_10", - Load: func(outerMap *ebpf.Map, _ uint32) error { + Load: func(outerMap *ebpf.Map, pinPathPrefix string, _ uint32) error { return populateStringFilterMaps(ks, pinPathPrefix, outerMap, 10) }, }, From 75f5fa9a2c47c007c9c8e8d6fa690dbbf22c6f73 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 21 Feb 2024 08:26:46 +0000 Subject: [PATCH 03/35] tetragon: Add shared map type fields Adding map type fields that specify how the map is shared and when it's placed in the sysfs hierarchy. MapTypeGlobal - under sysfs root, shared with everyone MapTypePolicy - under policy dir, shared within policy MapTypeSensor - under sensor dir, shared within sensor MapTypeProgram - under program dir, program specific MapTypeGlobal -> /sys/fs/bpf/tetragon/map-1 MapTypePolicy -> /sys/fs/bpf/tetragon/policy-name/map-2 MapTypeSensor -> /sys/fs/bpf/tetragon/policy-name/sensor-1/map-3 MapTypeProgram -> /sys/fs/bpf/tetragon/policy-name/sensor-1/prog-1/map-4 Adding just types at the moment, implementation is coming in following changes. Signed-off-by: Jiri Olsa --- pkg/sensors/program/map.go | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/pkg/sensors/program/map.go b/pkg/sensors/program/map.go index 19b941302c6..95734a6ef24 100644 --- a/pkg/sensors/program/map.go +++ b/pkg/sensors/program/map.go @@ -19,6 +19,15 @@ type MaxEntries struct { Set bool } +type MapType int + +const ( + MapTypeGlobal MapType = iota + MapTypePolicy + MapTypeSensor + MapTypeProgram +) + // Map represents BPF maps. type Map struct { Name string @@ -29,6 +38,7 @@ type Map struct { MapHandle *ebpf.Map Entries MaxEntries InnerEntries MaxEntries + Type MapType } // Map holds pointer to Program object as a source of its ebpf object @@ -44,8 +54,8 @@ type Map struct { // p.PinMap["map2"] = &map2 // ... // p.PinMap["mapX"] = &mapX -func mapBuilder(name, pin string, lds ...*Program) *Map { - m := &Map{name, pin, "", lds[0], Idle(), nil, MaxEntries{0, false}, MaxEntries{0, false}} +func mapBuilder(name, pin string, ty MapType, lds ...*Program) *Map { + m := &Map{name, pin, "", lds[0], Idle(), nil, MaxEntries{0, false}, MaxEntries{0, false}, ty} for _, ld := range lds { ld.PinMap[name] = m } @@ -53,11 +63,31 @@ func mapBuilder(name, pin string, lds ...*Program) *Map { } func MapBuilder(name string, lds ...*Program) *Map { - return mapBuilder(name, name, lds...) + return mapBuilder(name, name, MapTypeGlobal, lds...) } func MapBuilderPin(name, pin string, lds ...*Program) *Map { - return mapBuilder(name, pin, lds...) + return mapBuilder(name, pin, MapTypeGlobal, lds...) +} + +func MapBuilderProgram(name string, lds ...*Program) *Map { + return mapBuilder(name, name, MapTypeProgram, lds...) +} + +func MapBuilderSensor(name string, lds ...*Program) *Map { + return mapBuilder(name, name, MapTypeSensor, lds...) +} + +func MapBuilderPolicy(name string, lds ...*Program) *Map { + return mapBuilder(name, name, MapTypePolicy, lds...) +} + +func MapBuilderType(name string, ty MapType, lds ...*Program) *Map { + return mapBuilder(name, name, ty, lds...) +} + +func PolicyMapPath(mapDir, policy, name string) string { + return filepath.Join(mapDir, policy, name) } func (m *Map) Unload() error { From 77a4f4c98d7161e3a7b4876078f3a5d54e363189 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 23 Feb 2024 17:36:40 +0000 Subject: [PATCH 04/35] tetragon: Create sensor directory hierarchy Creating sensor directory hierarchy on sensor loading. When sensor is loading we: - create directory sysfs hierarchy for each program in the sensor - assign PinPath for each pinned map in the sensor Adding PinName to Program object to hold sysfs program name, at the moment it's initialized same way as the PinPath, but PinPath is changed when the sensor is loaded to be relative program path from sysfs tetragon root. Signed-off-by: Jiri Olsa --- pkg/sensors/load.go | 22 ++++++++++++++++++++-- pkg/sensors/program/loader.go | 4 ++-- pkg/sensors/program/program.go | 7 +++++-- pkg/sensors/sensors.go | 2 ++ 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/pkg/sensors/load.go b/pkg/sensors/load.go index efdb4651a7a..e4d34c6bfb8 100644 --- a/pkg/sensors/load.go +++ b/pkg/sensors/load.go @@ -62,6 +62,15 @@ func LoadConfig(bpfDir string, sens []*Sensor) error { return nil } +func (s *Sensor) setupProgsPinPath(bpfDir string) { + for _, p := range s.Progs { + // setup sensor based program pin path + p.PinPath = filepath.Join(s.Policy, s.Name, p.PinName) + // and make the path + os.MkdirAll(filepath.Join(bpfDir, p.PinPath), os.ModeDir) + } +} + // Load loads the sensor, by loading all the BPF programs and maps. func (s *Sensor) Load(bpfDir string) error { if s == nil { @@ -77,7 +86,7 @@ func (s *Sensor) Load(bpfDir string) error { return fmt.Errorf("tetragon, aborting minimum requirements not met: %w", err) } - os.Mkdir(bpfDir, os.ModeDir) + s.setupProgsPinPath(bpfDir) l := logger.GetLogger() @@ -210,7 +219,16 @@ func (s *Sensor) FindPrograms() error { } func (s *Sensor) setMapPinPath(m *program.Map) { - m.PinPath = m.PinName + switch m.Type { + case program.MapTypeGlobal: + m.PinPath = filepath.Join(m.PinName) + case program.MapTypePolicy: + m.PinPath = filepath.Join(s.Policy, m.PinName) + case program.MapTypeSensor: + m.PinPath = filepath.Join(s.Policy, s.Name, m.PinName) + case program.MapTypeProgram: + m.PinPath = filepath.Join(s.Policy, s.Name, m.Prog.PinName, m.PinName) + } } // loadMaps loads all the BPF maps in the sensor. diff --git a/pkg/sensors/program/loader.go b/pkg/sensors/program/loader.go index 87281d5e9c3..1163d9d4e59 100644 --- a/pkg/sensors/program/loader.go +++ b/pkg/sensors/program/loader.go @@ -229,7 +229,7 @@ func kprobeAttachOverride(load *Program, bpfDir string, return fmt.Errorf("failed to clone generic_kprobe_override program: %w", err) } - pinPath := filepath.Join(bpfDir, fmt.Sprint(load.PinPath, "-override")) + pinPath := filepath.Join(bpfDir, load.PinPath, "prog_override") if err := prog.Pin(pinPath); err != nil { return fmt.Errorf("pinning '%s' to '%s' failed: %w", load.Label, pinPath, err) @@ -887,7 +887,7 @@ func doLoadProgram( return nil, fmt.Errorf("program for section '%s' not found", load.Label) } - pinPath := filepath.Join(bpfDir, load.PinPath) + pinPath := filepath.Join(bpfDir, load.PinPath, "prog") if _, err := os.Stat(pinPath); err == nil { logger.GetLogger().Debugf("Pin file '%s' already exists, repinning", load.PinPath) diff --git a/pkg/sensors/program/program.go b/pkg/sensors/program/program.go index e894e8f1804..c4df3b6e020 100644 --- a/pkg/sensors/program/program.go +++ b/pkg/sensors/program/program.go @@ -13,14 +13,15 @@ import ( ) func Builder( - objFile, attach, label, pinFile string, + objFile, attach, label, pinName string, ty string, ) *Program { return &Program{ Name: objFile, Attach: attach, Label: label, - PinPath: pinFile, + PinPath: "", + PinName: pinName, RetProbe: false, ErrorFatal: true, Override: false, @@ -78,6 +79,8 @@ type Program struct { // PinPath is the pinned path to this program. Note this is a relative path // based on the BPF directory FGS is running under. PinPath string + // PinName + PinName string // RetProbe indicates whether a kprobe is a kretprobe. RetProbe bool diff --git a/pkg/sensors/sensors.go b/pkg/sensors/sensors.go index 4222ae5a691..cd7e4f70757 100644 --- a/pkg/sensors/sensors.go +++ b/pkg/sensors/sensors.go @@ -39,6 +39,8 @@ var ( type Sensor struct { // Name is a human-readbale description. Name string + // Policy name the sensor is part of. + Policy string // Progs are all the BPF programs that exist on the filesystem. Progs []*program.Program // Maps are all the BPF Maps that the progs use. From 04a0d6006cbeb3f99d90d710beef3ce68e08df42 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 23 Feb 2024 19:17:38 +0000 Subject: [PATCH 05/35] tetragon: Move base sensor maps under new hierarchy Moving execve_calls map under execve program directory, because it's specific to the program. The rest of the base sensor maps are kept as global, because they are shared by all the other sensors. Signed-off-by: Jiri Olsa --- pkg/sensors/base/base.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/sensors/base/base.go b/pkg/sensors/base/base.go index 34afc2d48c9..06f9e135a23 100644 --- a/pkg/sensors/base/base.go +++ b/pkg/sensors/base/base.go @@ -67,7 +67,7 @@ var ( TCPMonMap = program.MapBuilder("tcpmon_map", Execve) /* Networking and Process Monitoring maps */ ExecveMap = program.MapBuilder("execve_map", Execve) - ExecveTailCallsMap = program.MapBuilderPin("execve_calls", "execve_calls", Execve) + ExecveTailCallsMap = program.MapBuilderProgram("execve_calls", Execve) ExecveJoinMap = program.MapBuilder("tg_execve_joined_info_map", ExecveBprmCommit) From 232eca9d07c5d14ab9ccbffb15d867ecf3901696 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 23 Feb 2024 17:57:20 +0000 Subject: [PATCH 06/35] tetragon: Move generickprobe sensor maps under new hierarchy Moving generickprobe sensor maps under new hierarchy: per program maps: argfilter_maps addr4lpm_maps addr6lpm_maps string_prefix_maps string_postfix_maps kprobe_calls filter_map tg_mb_sel_opts tg_mb_paths stack_trace_map config_map retkprobe_calls override_tasks per sensor maps: fdinstall_map retprobe_map process_call_heap socktrack_map ratelimit_map Signed-off-by: Jiri Olsa --- pkg/sensors/tracing/generickprobe.go | 97 ++++++++++++++-------------- 1 file changed, 49 insertions(+), 48 deletions(-) diff --git a/pkg/sensors/tracing/generickprobe.go b/pkg/sensors/tracing/generickprobe.go index b4702905092..bcff8c85f61 100644 --- a/pkg/sensors/tracing/generickprobe.go +++ b/pkg/sensors/tracing/generickprobe.go @@ -208,7 +208,7 @@ func filterMaps(load *program.Program, pinPath string, kprobeEntry *genericKprob */ state := getProgramSelector(load, kprobeEntry) - argFilterMaps := program.MapBuilderPin("argfilter_maps", sensors.PathJoin(pinPath, "argfilter_maps"), load) + argFilterMaps := program.MapBuilderProgram("argfilter_maps", load) if state != nil && !kernels.MinKernelVersion("5.9") { // Versions before 5.9 do not allow inner maps to have different sizes. // See: https://lore.kernel.org/bpf/20200828011800.1970018-1-kafai@fb.com/ @@ -217,7 +217,7 @@ func filterMaps(load *program.Program, pinPath string, kprobeEntry *genericKprob } maps = append(maps, argFilterMaps) - addr4FilterMaps := program.MapBuilderPin("addr4lpm_maps", sensors.PathJoin(pinPath, "addr4lpm_maps"), load) + addr4FilterMaps := program.MapBuilderProgram("addr4lpm_maps", load) if state != nil && !kernels.MinKernelVersion("5.9") { // Versions before 5.9 do not allow inner maps to have different sizes. // See: https://lore.kernel.org/bpf/20200828011800.1970018-1-kafai@fb.com/ @@ -226,7 +226,7 @@ func filterMaps(load *program.Program, pinPath string, kprobeEntry *genericKprob } maps = append(maps, addr4FilterMaps) - addr6FilterMaps := program.MapBuilderPin("addr6lpm_maps", sensors.PathJoin(pinPath, "addr6lpm_maps"), load) + addr6FilterMaps := program.MapBuilderProgram("addr6lpm_maps", load) if state != nil && !kernels.MinKernelVersion("5.9") { // Versions before 5.9 do not allow inner maps to have different sizes. // See: https://lore.kernel.org/bpf/20200828011800.1970018-1-kafai@fb.com/ @@ -242,8 +242,7 @@ func filterMaps(load *program.Program, pinPath string, kprobeEntry *genericKprob } for string_map_index := 0; string_map_index < numSubMaps; string_map_index++ { - stringFilterMap[string_map_index] = program.MapBuilderPin(fmt.Sprintf("string_maps_%d", string_map_index), - sensors.PathJoin(pinPath, fmt.Sprintf("string_maps_%d", string_map_index)), load) + stringFilterMap[string_map_index] = program.MapBuilderProgram(fmt.Sprintf("string_maps_%d", string_map_index), load) if state != nil && !kernels.MinKernelVersion("5.9") { // Versions before 5.9 do not allow inner maps to have different sizes. // See: https://lore.kernel.org/bpf/20200828011800.1970018-1-kafai@fb.com/ @@ -253,7 +252,7 @@ func filterMaps(load *program.Program, pinPath string, kprobeEntry *genericKprob maps = append(maps, stringFilterMap[string_map_index]) } - stringPrefixFilterMaps := program.MapBuilderPin("string_prefix_maps", sensors.PathJoin(pinPath, "string_prefix_maps"), load) + stringPrefixFilterMaps := program.MapBuilderProgram("string_prefix_maps", load) if state != nil && !kernels.MinKernelVersion("5.9") { // Versions before 5.9 do not allow inner maps to have different sizes. // See: https://lore.kernel.org/bpf/20200828011800.1970018-1-kafai@fb.com/ @@ -262,7 +261,7 @@ func filterMaps(load *program.Program, pinPath string, kprobeEntry *genericKprob } maps = append(maps, stringPrefixFilterMaps) - stringPostfixFilterMaps := program.MapBuilderPin("string_postfix_maps", sensors.PathJoin(pinPath, "string_postfix_maps"), load) + stringPostfixFilterMaps := program.MapBuilderProgram("string_postfix_maps", load) if state != nil && !kernels.MinKernelVersion("5.9") { // Versions before 5.9 do not allow inner maps to have different sizes. // See: https://lore.kernel.org/bpf/20200828011800.1970018-1-kafai@fb.com/ @@ -318,51 +317,52 @@ func createMultiKprobeSensor(sensorPath, policyName string, multiIDs []idtable.E SetPolicy(policyName) progs = append(progs, load) - fdinstall := program.MapBuilderPin("fdinstall_map", sensors.PathJoin(sensorPath, "fdinstall_map"), load) + fdinstall := program.MapBuilderSensor("fdinstall_map", load) if has.fdInstall { fdinstall.SetMaxEntries(fdInstallMapMaxEntries) } maps = append(maps, fdinstall) - configMap := program.MapBuilderPin("config_map", sensors.PathJoin(pinPath, "config_map"), load) + configMap := program.MapBuilderProgram("config_map", load) maps = append(maps, configMap) - tailCalls := program.MapBuilderPin("kprobe_calls", sensors.PathJoin(pinPath, "kp_calls"), load) + tailCalls := program.MapBuilderProgram("kprobe_calls", load) maps = append(maps, tailCalls) load.SetTailCall("kprobe", tailCalls) - filterMap := program.MapBuilderPin("filter_map", sensors.PathJoin(pinPath, "filter_map"), load) + filterMap := program.MapBuilderProgram("filter_map", load) maps = append(maps, filterMap) maps = append(maps, filterMaps(load, pinPath, nil)...) - retProbe := program.MapBuilderPin("retprobe_map", sensors.PathJoin(pinPath, "retprobe_map"), load) + retProbe := program.MapBuilderSensor("retprobe_map", load) maps = append(maps, retProbe) - callHeap := program.MapBuilderPin("process_call_heap", sensors.PathJoin(pinPath, "process_call_heap"), load) + callHeap := program.MapBuilderSensor("process_call_heap", load) maps = append(maps, callHeap) - selMatchBinariesMap := program.MapBuilderPin("tg_mb_sel_opts", sensors.PathJoin(pinPath, "tg_mb_sel_opts"), load) + selMatchBinariesMap := program.MapBuilderProgram("tg_mb_sel_opts", load) maps = append(maps, selMatchBinariesMap) - matchBinariesPaths := program.MapBuilderPin("tg_mb_paths", sensors.PathJoin(pinPath, "tg_mb_paths"), load) + matchBinariesPaths := program.MapBuilderProgram("tg_mb_paths", load) maps = append(maps, matchBinariesPaths) - stackTraceMap := program.MapBuilderPin("stack_trace_map", sensors.PathJoin(pinPath, "stack_trace_map"), load) + stackTraceMap := program.MapBuilderProgram("stack_trace_map", load) if has.stackTrace { stackTraceMap.SetMaxEntries(stackTraceMapMaxEntries) } + maps = append(maps, stackTraceMap) data.stackTraceMap = stackTraceMap if kernels.EnableLargeProgs() { - socktrack := program.MapBuilderPin("socktrack_map", sensors.PathJoin(sensorPath, "socktrack_map"), load) + socktrack := program.MapBuilderSensor("socktrack_map", load) maps = append(maps, socktrack) } if kernels.EnableLargeProgs() { - ratelimitMap := program.MapBuilderPin("ratelimit_map", sensors.PathJoin(pinPath, "ratelimit_map"), load) + ratelimitMap := program.MapBuilderSensor("ratelimit_map", load) if has.rateLimit { ratelimitMap.SetMaxEntries(ratelimitMapMaxEntries) } @@ -378,7 +378,7 @@ func createMultiKprobeSensor(sensorPath, policyName string, multiIDs []idtable.E filterMap.SetMaxEntries(len(multiIDs)) configMap.SetMaxEntries(len(multiIDs)) - overrideTasksMap := program.MapBuilderPin("override_tasks", sensors.PathJoin(pinPath, "override_tasks"), load) + overrideTasksMap := program.MapBuilderProgram("override_tasks", load) if has.override { overrideTasksMap.SetMaxEntries(overrideMapMaxEntries) } @@ -396,30 +396,30 @@ func createMultiKprobeSensor(sensorPath, policyName string, multiIDs []idtable.E SetPolicy(policyName) progs = append(progs, loadret) - retProbe := program.MapBuilderPin("retprobe_map", sensors.PathJoin(pinPath, "retprobe_map"), loadret) + retProbe := program.MapBuilderSensor("retprobe_map", loadret) maps = append(maps, retProbe) - retConfigMap := program.MapBuilderPin("config_map", sensors.PathJoin(pinPath, "retprobe_config_map"), loadret) + retConfigMap := program.MapBuilderProgram("config_map", loadret) maps = append(maps, retConfigMap) - retFilterMap := program.MapBuilderPin("filter_map", sensors.PathJoin(pinPath, "retprobe_filter_map"), loadret) + retFilterMap := program.MapBuilderProgram("filter_map", loadret) maps = append(maps, retFilterMap) maps = append(maps, filterMaps(loadret, pinPath, nil)...) - callHeap := program.MapBuilderPin("process_call_heap", sensors.PathJoin(pinPath, "process_call_heap"), loadret) + callHeap := program.MapBuilderSensor("process_call_heap", loadret) maps = append(maps, callHeap) - fdinstall := program.MapBuilderPin("fdinstall_map", sensors.PathJoin(sensorPath, "fdinstall_map"), loadret) + fdinstall := program.MapBuilderSensor("fdinstall_map", loadret) if has.fdInstall { fdinstall.SetMaxEntries(fdInstallMapMaxEntries) } maps = append(maps, fdinstall) - socktrack := program.MapBuilderPin("socktrack_map", sensors.PathJoin(sensorPath, "socktrack_map"), loadret) + socktrack := program.MapBuilderSensor("socktrack_map", loadret) maps = append(maps, socktrack) - tailCalls := program.MapBuilderPin("retkprobe_calls", sensors.PathJoin(pinPath, "retprobe-kp_calls"), loadret) + tailCalls := program.MapBuilderSensor("retkprobe_calls", loadret) maps = append(maps, tailCalls) loadret.SetTailCall("kprobe", tailCalls) @@ -659,9 +659,10 @@ func createGenericKprobeSensor( } return &sensors.Sensor{ - Name: name, - Progs: progs, - Maps: maps, + Name: name, + Progs: progs, + Maps: maps, + Policy: policyName, DestroyHook: func() error { var errs error for _, id := range ids { @@ -910,35 +911,35 @@ func createKprobeSensorFromEntry(kprobeEntry *genericKprobe, sensorPath string, } progs = append(progs, load) - fdinstall := program.MapBuilderPin("fdinstall_map", sensors.PathJoin(sensorPath, "fdinstall_map"), load) + fdinstall := program.MapBuilderSensor("fdinstall_map", load) if has.fdInstall { fdinstall.SetMaxEntries(fdInstallMapMaxEntries) } maps = append(maps, fdinstall) - configMap := program.MapBuilderPin("config_map", sensors.PathJoin(pinPath, "config_map"), load) + configMap := program.MapBuilderProgram("config_map", load) maps = append(maps, configMap) - tailCalls := program.MapBuilderPin("kprobe_calls", sensors.PathJoin(pinPath, "kp_calls"), load) + tailCalls := program.MapBuilderProgram("kprobe_calls", load) maps = append(maps, tailCalls) load.SetTailCall("kprobe", tailCalls) - filterMap := program.MapBuilderPin("filter_map", sensors.PathJoin(pinPath, "filter_map"), load) + filterMap := program.MapBuilderProgram("filter_map", load) maps = append(maps, filterMap) maps = append(maps, filterMaps(load, pinPath, kprobeEntry)...) - retProbe := program.MapBuilderPin("retprobe_map", sensors.PathJoin(pinPath, "retprobe_map"), load) + retProbe := program.MapBuilderSensor("retprobe_map", load) maps = append(maps, retProbe) - callHeap := program.MapBuilderPin("process_call_heap", sensors.PathJoin(pinPath, "process_call_heap"), load) + callHeap := program.MapBuilderSensor("process_call_heap", load) maps = append(maps, callHeap) - selMatchBinariesMap := program.MapBuilderPin("tg_mb_sel_opts", sensors.PathJoin(pinPath, "tg_mb_sel_opts"), load) + selMatchBinariesMap := program.MapBuilderProgram("tg_mb_sel_opts", load) maps = append(maps, selMatchBinariesMap) - matchBinariesPaths := program.MapBuilderPin("tg_mb_paths", sensors.PathJoin(pinPath, "tg_mb_paths"), load) + matchBinariesPaths := program.MapBuilderProgram("tg_mb_paths", load) if !kernels.MinKernelVersion("5.9") { // Versions before 5.9 do not allow inner maps to have different sizes. // See: https://lore.kernel.org/bpf/20200828011800.1970018-1-kafai@fb.com/ @@ -949,7 +950,7 @@ func createKprobeSensorFromEntry(kprobeEntry *genericKprobe, sensorPath string, // loading the stack trace map in any case so that it does not end up as an // anonymous map (as it's always used by the BPF prog) and is clearly linked // to tetragon - stackTraceMap := program.MapBuilderPin("stack_trace_map", sensors.PathJoin(pinPath, "stack_trace_map"), load) + stackTraceMap := program.MapBuilderProgram("stack_trace_map", load) if has.stackTrace { // to reduce memory footprint however, the stack map is created with a // max entry of 1, we need to expand that at loading. @@ -959,12 +960,12 @@ func createKprobeSensorFromEntry(kprobeEntry *genericKprobe, sensorPath string, kprobeEntry.data.stackTraceMap = stackTraceMap if kernels.EnableLargeProgs() { - socktrack := program.MapBuilderPin("socktrack_map", sensors.PathJoin(sensorPath, "socktrack_map"), load) + socktrack := program.MapBuilderSensor("socktrack_map", load) maps = append(maps, socktrack) } if kernels.EnableLargeProgs() { - ratelimitMap := program.MapBuilderPin("ratelimit_map", sensors.PathJoin(pinPath, "ratelimit_map"), load) + ratelimitMap := program.MapBuilderSensor("ratelimit_map", load) if has.rateLimit { // similarly as for stacktrace, we expand the max size only if // needed to reduce the memory footprint when unused @@ -979,7 +980,7 @@ func createKprobeSensorFromEntry(kprobeEntry *genericKprobe, sensorPath string, } maps = append(maps, enforcerDataMap) - overrideTasksMap := program.MapBuilderPin("override_tasks", sensors.PathJoin(pinPath, "override_tasks"), load) + overrideTasksMap := program.MapBuilderProgram("override_tasks", load) if has.override { overrideTasksMap.SetMaxEntries(overrideMapMaxEntries) } @@ -998,34 +999,34 @@ func createKprobeSensorFromEntry(kprobeEntry *genericKprobe, sensorPath string, SetPolicy(kprobeEntry.policyName) progs = append(progs, loadret) - retProbe := program.MapBuilderPin("retprobe_map", sensors.PathJoin(pinPath, "retprobe_map"), loadret) + retProbe := program.MapBuilderSensor("retprobe_map", loadret) maps = append(maps, retProbe) - retConfigMap := program.MapBuilderPin("config_map", sensors.PathJoin(pinPath, "retprobe_config_map"), loadret) + retConfigMap := program.MapBuilderProgram("config_map", loadret) maps = append(maps, retConfigMap) - tailCalls := program.MapBuilderPin("retkprobe_calls", sensors.PathJoin(pinPath, "retprobe-kp_calls"), loadret) + tailCalls := program.MapBuilderProgram("retkprobe_calls", loadret) maps = append(maps, tailCalls) loadret.SetTailCall("kprobe", tailCalls) - filterMap := program.MapBuilderPin("filter_map", sensors.PathJoin(pinPath, "retkprobe_filter_map"), loadret) + filterMap := program.MapBuilderProgram("filter_map", loadret) maps = append(maps, filterMap) maps = append(maps, filterMaps(loadret, pinPath, kprobeEntry)...) // add maps with non-default paths (pins) to the retprobe - callHeap := program.MapBuilderPin("process_call_heap", sensors.PathJoin(pinPath, "process_call_heap"), loadret) + callHeap := program.MapBuilderSensor("process_call_heap", loadret) maps = append(maps, callHeap) - fdinstall := program.MapBuilderPin("fdinstall_map", sensors.PathJoin(sensorPath, "fdinstall_map"), loadret) + fdinstall := program.MapBuilderSensor("fdinstall_map", loadret) if has.fdInstall { fdinstall.SetMaxEntries(fdInstallMapMaxEntries) } maps = append(maps, fdinstall) if kernels.EnableLargeProgs() { - socktrack := program.MapBuilderPin("socktrack_map", sensors.PathJoin(sensorPath, "socktrack_map"), loadret) + socktrack := program.MapBuilderSensor("socktrack_map", loadret) maps = append(maps, socktrack) } } From 4af530a7d498ae4dda212c210281845228193a6e Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 25 Feb 2024 08:33:39 +0000 Subject: [PATCH 07/35] tetragon: Move generictracepoint sensor maps under new hierarchy Moving generictracepoint sensor maps under new hierarchy. per program maps: tp_calls filter_map argfilter_maps addr4lpm_maps addr6lpm_maps string_prefix_maps string_postfix_maps tg_mb_paths tg_mb_sel_opts per sensor maps: fdinstall_map Signed-off-by: Jiri Olsa --- pkg/sensors/tracing/generictracepoint.go | 30 ++++++++++++------------ 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/pkg/sensors/tracing/generictracepoint.go b/pkg/sensors/tracing/generictracepoint.go index 150a981f81a..968db4c8ff3 100644 --- a/pkg/sensors/tracing/generictracepoint.go +++ b/pkg/sensors/tracing/generictracepoint.go @@ -415,22 +415,22 @@ func createGenericTracepointSensor( prog0.LoaderData = tp.tableIdx progs = append(progs, prog0) - fdinstall := program.MapBuilderPin("fdinstall_map", sensors.PathJoin(pinPath, "fdinstall_map"), prog0) + fdinstall := program.MapBuilderSensor("fdinstall_map", prog0) if has.fdInstall { fdinstall.SetMaxEntries(fdInstallMapMaxEntries) } maps = append(maps, fdinstall) - tailCalls := program.MapBuilderPin("tp_calls", sensors.PathJoin(pinPath, "tp_calls"), prog0) + tailCalls := program.MapBuilderProgram("tp_calls", prog0) maps = append(maps, tailCalls) // tracepoint tail calls details prog0.SetTailCall("tracepoint", tailCalls) - filterMap := program.MapBuilderPin("filter_map", sensors.PathJoin(pinPath, "filter_map"), prog0) + filterMap := program.MapBuilderProgram("filter_map", prog0) maps = append(maps, filterMap) - argFilterMaps := program.MapBuilderPin("argfilter_maps", sensors.PathJoin(pinPath, "argfilter_maps"), prog0) + argFilterMaps := program.MapBuilderProgram("argfilter_maps", prog0) if !kernels.MinKernelVersion("5.9") { // Versions before 5.9 do not allow inner maps to have different sizes. // See: https://lore.kernel.org/bpf/20200828011800.1970018-1-kafai@fb.com/ @@ -439,7 +439,7 @@ func createGenericTracepointSensor( } maps = append(maps, argFilterMaps) - addr4FilterMaps := program.MapBuilderPin("addr4lpm_maps", sensors.PathJoin(pinPath, "addr4lpm_maps"), prog0) + addr4FilterMaps := program.MapBuilderProgram("addr4lpm_maps", prog0) if !kernels.MinKernelVersion("5.9") { // Versions before 5.9 do not allow inner maps to have different sizes. // See: https://lore.kernel.org/bpf/20200828011800.1970018-1-kafai@fb.com/ @@ -448,7 +448,7 @@ func createGenericTracepointSensor( } maps = append(maps, addr4FilterMaps) - addr6FilterMaps := program.MapBuilderPin("addr6lpm_maps", sensors.PathJoin(pinPath, "addr6lpm_maps"), prog0) + addr6FilterMaps := program.MapBuilderProgram("addr6lpm_maps", prog0) if !kernels.MinKernelVersion("5.9") { // Versions before 5.9 do not allow inner maps to have different sizes. // See: https://lore.kernel.org/bpf/20200828011800.1970018-1-kafai@fb.com/ @@ -462,8 +462,7 @@ func createGenericTracepointSensor( numSubMaps = selectors.StringMapsNumSubMapsSmall } for string_map_index := 0; string_map_index < numSubMaps; string_map_index++ { - stringFilterMap := program.MapBuilderPin(fmt.Sprintf("string_maps_%d", string_map_index), - sensors.PathJoin(pinPath, fmt.Sprintf("string_maps_%d", string_map_index)), prog0) + stringFilterMap := program.MapBuilderProgram(fmt.Sprintf("string_maps_%d", string_map_index), prog0) if !kernels.MinKernelVersion("5.9") { // Versions before 5.9 do not allow inner maps to have different sizes. // See: https://lore.kernel.org/bpf/20200828011800.1970018-1-kafai@fb.com/ @@ -473,7 +472,7 @@ func createGenericTracepointSensor( maps = append(maps, stringFilterMap) } - stringPrefixFilterMaps := program.MapBuilderPin("string_prefix_maps", sensors.PathJoin(pinPath, "string_prefix_maps"), prog0) + stringPrefixFilterMaps := program.MapBuilderProgram("string_prefix_maps", prog0) if !kernels.MinKernelVersion("5.9") { // Versions before 5.9 do not allow inner maps to have different sizes. // See: https://lore.kernel.org/bpf/20200828011800.1970018-1-kafai@fb.com/ @@ -482,7 +481,7 @@ func createGenericTracepointSensor( } maps = append(maps, stringPrefixFilterMaps) - stringPostfixFilterMaps := program.MapBuilderPin("string_postfix_maps", sensors.PathJoin(pinPath, "string_postfix_maps"), prog0) + stringPostfixFilterMaps := program.MapBuilderProgram("string_postfix_maps", prog0) if !kernels.MinKernelVersion("5.9") { // Versions before 5.9 do not allow inner maps to have different sizes. // See: https://lore.kernel.org/bpf/20200828011800.1970018-1-kafai@fb.com/ @@ -491,7 +490,7 @@ func createGenericTracepointSensor( } maps = append(maps, stringPostfixFilterMaps) - matchBinariesPaths := program.MapBuilderPin("tg_mb_paths", sensors.PathJoin(pinPath, "tg_mb_paths"), prog0) + matchBinariesPaths := program.MapBuilderProgram("tg_mb_paths", prog0) if !kernels.MinKernelVersion("5.9") { // Versions before 5.9 do not allow inner maps to have different sizes. // See: https://lore.kernel.org/bpf/20200828011800.1970018-1-kafai@fb.com/ @@ -505,14 +504,15 @@ func createGenericTracepointSensor( } maps = append(maps, enforcerDataMap) - selMatchBinariesMap := program.MapBuilderPin("tg_mb_sel_opts", sensors.PathJoin(pinPath, "tg_mb_sel_opts"), prog0) + selMatchBinariesMap := program.MapBuilderProgram("tg_mb_sel_opts", prog0) maps = append(maps, selMatchBinariesMap) } return &sensors.Sensor{ - Name: name, - Progs: progs, - Maps: maps, + Name: name, + Progs: progs, + Maps: maps, + Policy: policyName, }, nil } From ea8f6aca4e156194854c55ae9bcb8952f2f7cf6f Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 25 Feb 2024 08:57:54 +0000 Subject: [PATCH 08/35] tetragon: Move genericuprobe sensor maps under new hierarchy Moving genericuprobe sensor maps under new hierarchy. per program maps: config_map uprobe_calls filter_map tg_mb_sel_opts Signed-off-by: Jiri Olsa --- pkg/sensors/tracing/genericuprobe.go | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/pkg/sensors/tracing/genericuprobe.go b/pkg/sensors/tracing/genericuprobe.go index cdc4db58986..66855df2f2c 100644 --- a/pkg/sensors/tracing/genericuprobe.go +++ b/pkg/sensors/tracing/genericuprobe.go @@ -288,9 +288,10 @@ func createGenericUprobeSensor( } return &sensors.Sensor{ - Name: name, - Progs: progs, - Maps: maps, + Name: name, + Progs: progs, + Maps: maps, + Policy: policyName, }, nil } @@ -415,9 +416,9 @@ func createMultiUprobeSensor(sensorPath string, multiIDs []idtable.EntryID) ([]* progs = append(progs, load) - configMap := program.MapBuilderPin("config_map", sensors.PathJoin(pinPath, "config_map"), load) - tailCalls := program.MapBuilderPin("uprobe_calls", sensors.PathJoin(pinPath, "up_calls"), load) - filterMap := program.MapBuilderPin("filter_map", sensors.PathJoin(pinPath, "filter_map"), load) + configMap := program.MapBuilderProgram("config_map", load) + tailCalls := program.MapBuilderProgram("uprobe_calls", load) + filterMap := program.MapBuilderProgram("filter_map", load) maps = append(maps, configMap, tailCalls, filterMap) @@ -472,10 +473,10 @@ func createUprobeSensorFromEntry(uprobeEntry *genericUprobe, progs = append(progs, load) - configMap := program.MapBuilderPin("config_map", sensors.PathJoin(pinPath, "config_map"), load) - tailCalls := program.MapBuilderPin("uprobe_calls", sensors.PathJoin(pinPath, "up_calls"), load) - filterMap := program.MapBuilderPin("filter_map", sensors.PathJoin(pinPath, "filter_map"), load) - selMatchBinariesMap := program.MapBuilderPin("tg_mb_sel_opts", sensors.PathJoin(pinPath, "tg_mb_sel_opts"), load) + configMap := program.MapBuilderProgram("config_map", load) + tailCalls := program.MapBuilderProgram("uprobe_calls", load) + filterMap := program.MapBuilderProgram("filter_map", load) + selMatchBinariesMap := program.MapBuilderProgram("tg_mb_sel_opts", load) maps = append(maps, configMap, tailCalls, filterMap, selMatchBinariesMap) load.SetTailCall("uprobe", tailCalls) return progs, maps From 490bf57140bb82c249993e00aeefd3cf1fe904a2 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 19 Jul 2024 12:05:14 +0000 Subject: [PATCH 09/35] tetragon: Move genericlsm sensor maps under new hierarchy Moving genericlsm sensor maps under new hierarchy: per program maps: config_map lsm_calls filter_map tg_mb_sel_opts tg_mb_paths argfilter_maps addr4lpm_maps addr6lpm_maps string_maps_%d string_prefix_maps string_postfix_maps process_call_heap Signed-off-by: Jiri Olsa --- pkg/sensors/tracing/genericlsm.go | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/pkg/sensors/tracing/genericlsm.go b/pkg/sensors/tracing/genericlsm.go index a003ae00965..3a43fe20fa7 100644 --- a/pkg/sensors/tracing/genericlsm.go +++ b/pkg/sensors/tracing/genericlsm.go @@ -341,6 +341,7 @@ func createGenericLsmSensor( } return errs }, + Policy: policyName, }, nil } @@ -366,26 +367,26 @@ func createLsmSensorFromEntry(lsmEntry *genericLsm, SetLoaderData(lsmEntry.tableId) progs = append(progs, load) - configMap := program.MapBuilderPin("config_map", sensors.PathJoin(pinPath, "config_map"), load) + configMap := program.MapBuilderProgram("config_map", load) maps = append(maps, configMap) - tailCalls := program.MapBuilderPin("lsm_calls", sensors.PathJoin(pinPath, "lsm_calls"), load) + tailCalls := program.MapBuilderProgram("lsm_calls", load) maps = append(maps, tailCalls) load.SetTailCall("lsm", tailCalls) - filterMap := program.MapBuilderPin("filter_map", sensors.PathJoin(pinPath, "filter_map"), load) + filterMap := program.MapBuilderProgram("filter_map", load) maps = append(maps, filterMap) - maps = append(maps, filterMapsForLsm(load, pinPath, lsmEntry)...) + maps = append(maps, filterMapsForLsm(load, lsmEntry)...) - callHeap := program.MapBuilderPin("process_call_heap", sensors.PathJoin(pinPath, "process_call_heap"), load) + callHeap := program.MapBuilderProgram("process_call_heap", load) maps = append(maps, callHeap) - selMatchBinariesMap := program.MapBuilderPin("tg_mb_sel_opts", sensors.PathJoin(pinPath, "tg_mb_sel_opts"), load) + selMatchBinariesMap := program.MapBuilderProgram("tg_mb_sel_opts", load) maps = append(maps, selMatchBinariesMap) - matchBinariesPaths := program.MapBuilderPin("tg_mb_paths", sensors.PathJoin(pinPath, "tg_mb_paths"), load) + matchBinariesPaths := program.MapBuilderProgram("tg_mb_paths", load) if !kernels.MinKernelVersion("5.9") { // Versions before 5.9 do not allow inner maps to have different sizes. // See: https://lore.kernel.org/bpf/20200828011800.1970018-1-kafai@fb.com/ @@ -398,10 +399,10 @@ func createLsmSensorFromEntry(lsmEntry *genericLsm, return progs, maps } -func filterMapsForLsm(load *program.Program, pinPath string, lsmEntry *genericLsm) []*program.Map { +func filterMapsForLsm(load *program.Program, lsmEntry *genericLsm) []*program.Map { var maps []*program.Map - argFilterMaps := program.MapBuilderPin("argfilter_maps", sensors.PathJoin(pinPath, "argfilter_maps"), load) + argFilterMaps := program.MapBuilderProgram("argfilter_maps", load) if !kernels.MinKernelVersion("5.9") { // Versions before 5.9 do not allow inner maps to have different sizes. // See: https://lore.kernel.org/bpf/20200828011800.1970018-1-kafai@fb.com/ @@ -410,7 +411,7 @@ func filterMapsForLsm(load *program.Program, pinPath string, lsmEntry *genericLs } maps = append(maps, argFilterMaps) - addr4FilterMaps := program.MapBuilderPin("addr4lpm_maps", sensors.PathJoin(pinPath, "addr4lpm_maps"), load) + addr4FilterMaps := program.MapBuilderProgram("addr4lpm_maps", load) if !kernels.MinKernelVersion("5.9") { // Versions before 5.9 do not allow inner maps to have different sizes. // See: https://lore.kernel.org/bpf/20200828011800.1970018-1-kafai@fb.com/ @@ -419,7 +420,7 @@ func filterMapsForLsm(load *program.Program, pinPath string, lsmEntry *genericLs } maps = append(maps, addr4FilterMaps) - addr6FilterMaps := program.MapBuilderPin("addr6lpm_maps", sensors.PathJoin(pinPath, "addr6lpm_maps"), load) + addr6FilterMaps := program.MapBuilderProgram("addr6lpm_maps", load) if !kernels.MinKernelVersion("5.9") { // Versions before 5.9 do not allow inner maps to have different sizes. // See: https://lore.kernel.org/bpf/20200828011800.1970018-1-kafai@fb.com/ @@ -435,8 +436,7 @@ func filterMapsForLsm(load *program.Program, pinPath string, lsmEntry *genericLs } for string_map_index := 0; string_map_index < numSubMaps; string_map_index++ { - stringFilterMap[string_map_index] = program.MapBuilderPin(fmt.Sprintf("string_maps_%d", string_map_index), - sensors.PathJoin(pinPath, fmt.Sprintf("string_maps_%d", string_map_index)), load) + stringFilterMap[string_map_index] = program.MapBuilderProgram(fmt.Sprintf("string_maps_%d", string_map_index), load) if !kernels.MinKernelVersion("5.9") { // Versions before 5.9 do not allow inner maps to have different sizes. // See: https://lore.kernel.org/bpf/20200828011800.1970018-1-kafai@fb.com/ @@ -446,7 +446,7 @@ func filterMapsForLsm(load *program.Program, pinPath string, lsmEntry *genericLs maps = append(maps, stringFilterMap[string_map_index]) } - stringPrefixFilterMaps := program.MapBuilderPin("string_prefix_maps", sensors.PathJoin(pinPath, "string_prefix_maps"), load) + stringPrefixFilterMaps := program.MapBuilderProgram("string_prefix_maps", load) if !kernels.MinKernelVersion("5.9") { // Versions before 5.9 do not allow inner maps to have different sizes. // See: https://lore.kernel.org/bpf/20200828011800.1970018-1-kafai@fb.com/ @@ -455,7 +455,7 @@ func filterMapsForLsm(load *program.Program, pinPath string, lsmEntry *genericLs } maps = append(maps, stringPrefixFilterMaps) - stringPostfixFilterMaps := program.MapBuilderPin("string_postfix_maps", sensors.PathJoin(pinPath, "string_postfix_maps"), load) + stringPostfixFilterMaps := program.MapBuilderProgram("string_postfix_maps", load) if !kernels.MinKernelVersion("5.9") { // Versions before 5.9 do not allow inner maps to have different sizes. // See: https://lore.kernel.org/bpf/20200828011800.1970018-1-kafai@fb.com/ From c3a6b7af69b2630da8ac479df848eec0ee304d70 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 24 Feb 2024 00:16:32 +0000 Subject: [PATCH 10/35] tetragon: Change generickprobe sensor pin path Change the generickprobe sensor pin path for programs under sysfs hierarchy. Now the program pin looks like below, for multi kprobes: sigkilltest/gkp-sensor-1/multi_kprobe/prog sigkilltest/gkp-sensor-1/multi_retkprobe/prog for regular kprobes: sigkilltest/gkp-sensor-1/__x64_sys_lseek/prog sigkilltest/gkp-sensor-1/__x64_sys_lseek_return/prog Signed-off-by: Jiri Olsa --- pkg/sensors/tracing/generickprobe.go | 45 +++++++++------------------- 1 file changed, 14 insertions(+), 31 deletions(-) diff --git a/pkg/sensors/tracing/generickprobe.go b/pkg/sensors/tracing/generickprobe.go index bcff8c85f61..5b3397751d8 100644 --- a/pkg/sensors/tracing/generickprobe.go +++ b/pkg/sensors/tracing/generickprobe.go @@ -120,8 +120,6 @@ type genericKprobe struct { // for kprobes that have a GetUrl or DnsLookup action, we store the table of arguments. actionArgs idtable.Table - pinPathPrefix string - // policyName is the name of the policy that this tracepoint belongs to policyName string @@ -184,10 +182,6 @@ var ( MaxFilterIntArgs = 8 ) -func multiKprobePinPath(sensorPath string) string { - return sensors.PathJoin(sensorPath, "multi_kprobe") -} - func getProgramSelector(load *program.Program, kprobeEntry *genericKprobe) *selectors.KernelSelectorState { if kprobeEntry != nil { if load.RetProbe { @@ -198,7 +192,7 @@ func getProgramSelector(load *program.Program, kprobeEntry *genericKprobe) *sele return nil } -func filterMaps(load *program.Program, pinPath string, kprobeEntry *genericKprobe) []*program.Map { +func filterMaps(load *program.Program, kprobeEntry *genericKprobe) []*program.Map { var maps []*program.Map /* @@ -273,7 +267,7 @@ func filterMaps(load *program.Program, pinPath string, kprobeEntry *genericKprob return maps } -func createMultiKprobeSensor(sensorPath, policyName string, multiIDs []idtable.EntryID, has hasMaps) ([]*program.Program, []*program.Map, error) { +func createMultiKprobeSensor(policyName string, multiIDs []idtable.EntryID, has hasMaps) ([]*program.Program, []*program.Map, error) { var multiRetIDs []idtable.EntryID var progs []*program.Program var maps []*program.Map @@ -305,13 +299,11 @@ func createMultiKprobeSensor(sensorPath, policyName string, multiIDs []idtable.E loadProgRetName = "bpf_multi_retkprobe_v511.o" } - pinPath := multiKprobePinPath(sensorPath) - load := program.Builder( path.Join(option.Config.HubbleLib, loadProgName), fmt.Sprintf("kprobe_multi (%d functions)", len(multiIDs)), "kprobe.multi/generic_kprobe", - pinPath, + "multi_kprobe", "generic_kprobe"). SetLoaderData(multiIDs). SetPolicy(policyName) @@ -334,7 +326,7 @@ func createMultiKprobeSensor(sensorPath, policyName string, multiIDs []idtable.E filterMap := program.MapBuilderProgram("filter_map", load) maps = append(maps, filterMap) - maps = append(maps, filterMaps(load, pinPath, nil)...) + maps = append(maps, filterMaps(load, nil)...) retProbe := program.MapBuilderSensor("retprobe_map", load) maps = append(maps, retProbe) @@ -405,7 +397,7 @@ func createMultiKprobeSensor(sensorPath, policyName string, multiIDs []idtable.E retFilterMap := program.MapBuilderProgram("filter_map", loadret) maps = append(maps, retFilterMap) - maps = append(maps, filterMaps(loadret, pinPath, nil)...) + maps = append(maps, filterMaps(loadret, nil)...) callHeap := program.MapBuilderSensor("process_call_heap", loadret) maps = append(maps, callHeap) @@ -649,9 +641,9 @@ func createGenericKprobeSensor( } if useMulti { - progs, maps, err = createMultiKprobeSensor(in.sensorPath, in.policyName, ids, has) + progs, maps, err = createMultiKprobeSensor(in.policyName, ids, has) } else { - progs, maps, err = createSingleKprobeSensor(in.sensorPath, ids, has) + progs, maps, err = createSingleKprobeSensor(ids, has) } if err != nil { @@ -873,12 +865,6 @@ func addKprobe(funcName string, f *v1alpha1.KProbeSpec, in *addKprobeIn) (id idt genericKprobeTable.AddEntry(&kprobeEntry) config.FuncId = uint32(kprobeEntry.tableId.ID) - if in.useMulti { - kprobeEntry.pinPathPrefix = multiKprobePinPath(in.sensorPath) - } else { - kprobeEntry.pinPathPrefix = sensors.PathJoin(in.sensorPath, fmt.Sprintf("gkp-%d", kprobeEntry.tableId.ID)) - } - logger.GetLogger(). WithField("return", setRetprobe). WithField("function", kprobeEntry.funcName). @@ -888,20 +874,17 @@ func addKprobe(funcName string, f *v1alpha1.KProbeSpec, in *addKprobeIn) (id idt return kprobeEntry.tableId, nil } -func createKprobeSensorFromEntry(kprobeEntry *genericKprobe, sensorPath string, +func createKprobeSensorFromEntry(kprobeEntry *genericKprobe, progs []*program.Program, maps []*program.Map, has hasMaps) ([]*program.Program, []*program.Map) { loadProgName, loadProgRetName := kernels.GenericKprobeObjs() isSecurityFunc := strings.HasPrefix(kprobeEntry.funcName, "security_") - pinPath := kprobeEntry.pinPathPrefix - pinProg := sensors.PathJoin(pinPath, fmt.Sprintf("%s_prog", kprobeEntry.funcName)) - load := program.Builder( path.Join(option.Config.HubbleLib, loadProgName), kprobeEntry.funcName, "kprobe/generic_kprobe", - pinProg, + kprobeEntry.funcName, "generic_kprobe"). SetLoaderData(kprobeEntry.tableId). SetPolicy(kprobeEntry.policyName) @@ -928,7 +911,7 @@ func createKprobeSensorFromEntry(kprobeEntry *genericKprobe, sensorPath string, filterMap := program.MapBuilderProgram("filter_map", load) maps = append(maps, filterMap) - maps = append(maps, filterMaps(load, pinPath, kprobeEntry)...) + maps = append(maps, filterMaps(load, kprobeEntry)...) retProbe := program.MapBuilderSensor("retprobe_map", load) maps = append(maps, retProbe) @@ -987,7 +970,7 @@ func createKprobeSensorFromEntry(kprobeEntry *genericKprobe, sensorPath string, maps = append(maps, overrideTasksMap) if kprobeEntry.loadArgs.retprobe { - pinRetProg := sensors.PathJoin(pinPath, fmt.Sprintf("%s_ret_prog", kprobeEntry.funcName)) + pinRetProg := sensors.PathJoin(fmt.Sprintf("%s_return", kprobeEntry.funcName)) loadret := program.Builder( path.Join(option.Config.HubbleLib, loadProgRetName), kprobeEntry.funcName, @@ -1013,7 +996,7 @@ func createKprobeSensorFromEntry(kprobeEntry *genericKprobe, sensorPath string, filterMap := program.MapBuilderProgram("filter_map", loadret) maps = append(maps, filterMap) - maps = append(maps, filterMaps(loadret, pinPath, kprobeEntry)...) + maps = append(maps, filterMaps(loadret, kprobeEntry)...) // add maps with non-default paths (pins) to the retprobe callHeap := program.MapBuilderSensor("process_call_heap", loadret) @@ -1036,7 +1019,7 @@ func createKprobeSensorFromEntry(kprobeEntry *genericKprobe, sensorPath string, return progs, maps } -func createSingleKprobeSensor(sensorPath string, ids []idtable.EntryID, has hasMaps) ([]*program.Program, []*program.Map, error) { +func createSingleKprobeSensor(ids []idtable.EntryID, has hasMaps) ([]*program.Program, []*program.Map, error) { var progs []*program.Program var maps []*program.Map @@ -1052,7 +1035,7 @@ func createSingleKprobeSensor(sensorPath string, ids []idtable.EntryID, has hasM has.rateLimit = gk.hasRatelimit has.override = gk.hasOverride - progs, maps = createKprobeSensorFromEntry(gk, sensorPath, progs, maps, has) + progs, maps = createKprobeSensorFromEntry(gk, progs, maps, has) } return progs, maps, nil From 28972107a2af6a06f3cbfa58d272affa244b4077 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 25 Feb 2024 08:37:41 +0000 Subject: [PATCH 11/35] tetragon: Change generictracepoint sensor pin path Change the generictracepoint sensor pin path for programs under sysfs hierarchy. Now the program pin looks like below: raw-syscalls/gtp-sensor-1/raw_syscalls:sys_enter/prog Signed-off-by: Jiri Olsa --- pkg/sensors/tracing/generictracepoint.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pkg/sensors/tracing/generictracepoint.go b/pkg/sensors/tracing/generictracepoint.go index 968db4c8ff3..e736fda8795 100644 --- a/pkg/sensors/tracing/generictracepoint.go +++ b/pkg/sensors/tracing/generictracepoint.go @@ -394,8 +394,7 @@ func createGenericTracepointSensor( maps := []*program.Map{} progs := make([]*program.Program, 0, len(tracepoints)) for _, tp := range tracepoints { - pinPath := tp.pinPathPrefix - pinProg := sensors.PathJoin(pinPath, fmt.Sprintf("%s:%s_prog", tp.Info.Subsys, tp.Info.Event)) + pinProg := sensors.PathJoin(fmt.Sprintf("%s:%s", tp.Info.Subsys, tp.Info.Event)) attach := fmt.Sprintf("%s/%s", tp.Info.Subsys, tp.Info.Event) prog0 := program.Builder( path.Join(option.Config.HubbleLib, progName), From d796c1e9109875ccddf7a64199643a0743fa74f2 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 25 Feb 2024 09:05:41 +0000 Subject: [PATCH 12/35] tetragon: Change genericuprobe sensor pin path Change the genericuprobe sensor pin path for programs under sysfs hierarchy. Now the program pin looks like below: uprobe/gup-sensor-1/0-readline/prog uprobe/gup-sensor-1/1-main/prog Signed-off-by: Jiri Olsa --- pkg/sensors/tracing/genericuprobe.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pkg/sensors/tracing/genericuprobe.go b/pkg/sensors/tracing/genericuprobe.go index 66855df2f2c..c748bd64b0c 100644 --- a/pkg/sensors/tracing/genericuprobe.go +++ b/pkg/sensors/tracing/genericuprobe.go @@ -454,9 +454,6 @@ func createUprobeSensorFromEntry(uprobeEntry *genericUprobe, loadProgName = "bpf_generic_uprobe_v53.o" } - pinPath := uprobeEntry.pinPathPrefix - pinProg := sensors.PathJoin(pinPath, "prog") - attachData := &program.UprobeAttachData{ Path: uprobeEntry.path, Symbol: uprobeEntry.symbol, @@ -466,7 +463,7 @@ func createUprobeSensorFromEntry(uprobeEntry *genericUprobe, path.Join(option.Config.HubbleLib, loadProgName), "", "uprobe/generic_uprobe", - pinProg, + fmt.Sprintf("%d-%s", uprobeEntry.tableId.ID, uprobeEntry.symbol), "generic_uprobe"). SetAttachData(attachData). SetLoaderData(uprobeEntry) From 830ee2cd299685822bc920b38397a5c822d590e4 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 19 Jul 2024 12:15:43 +0000 Subject: [PATCH 13/35] tetragon: Change genericlsm sensor pin path Change the genericlsm sensor pin path for programs under sysfs hierarchy. Now the program pin looks like below: lsm-file-open/glsm-sensor-1/file_open/prog Signed-off-by: Jiri Olsa --- pkg/sensors/tracing/genericlsm.go | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/pkg/sensors/tracing/genericlsm.go b/pkg/sensors/tracing/genericlsm.go index 3a43fe20fa7..7688e427427 100644 --- a/pkg/sensors/tracing/genericlsm.go +++ b/pkg/sensors/tracing/genericlsm.go @@ -48,11 +48,10 @@ var ( ) type genericLsm struct { - tableId idtable.EntryID - pinPathPrefix string - config *api.EventConfig - hook string - selectors *selectors.KernelSelectorState + tableId idtable.EntryID + config *api.EventConfig + hook string + selectors *selectors.KernelSelectorState // policyName is the name of the policy that this uprobe belongs to policyName string // message field of the Tracing Policy @@ -272,8 +271,6 @@ func addLsm(f *v1alpha1.LsmHookSpec, in *addLsmIn) (id idtable.EntryID, err erro genericLsmTable.AddEntry(&lsmEntry) config.FuncId = uint32(lsmEntry.tableId.ID) - lsmEntry.pinPathPrefix = sensors.PathJoin(in.sensorPath, fmt.Sprintf("glsm-%d", lsmEntry.tableId.ID)) - logger.GetLogger(). WithField("hook", lsmEntry.hook). Infof("Added lsm Hook") @@ -355,14 +352,11 @@ func createLsmSensorFromEntry(lsmEntry *genericLsm, loadProgName = "bpf_generic_lsm_v511.o" } - pinPath := lsmEntry.pinPathPrefix - pinProg := sensors.PathJoin(pinPath, fmt.Sprintf("%s_prog", lsmEntry.hook)) - load := program.Builder( path.Join(option.Config.HubbleLib, loadProgName), lsmEntry.hook, "lsm/generic_lsm", - pinProg, + lsmEntry.hook, "generic_lsm"). SetLoaderData(lsmEntry.tableId) progs = append(progs, load) From 69b53fd33de1e4eea5a4c63c68032ccbe4a8ab46 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 25 Feb 2024 09:08:08 +0000 Subject: [PATCH 14/35] tetragon: Move enforcer sensor maps under new hierarchy Moving enforcer sensor maps under new hierarchy. per policy maps: enforcer_data Signed-off-by: Jiri Olsa --- pkg/sensors/tracing/enforcer.go | 14 +++++++------- pkg/sensors/tracing/generickprobe.go | 4 ++-- pkg/sensors/tracing/generictracepoint.go | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/pkg/sensors/tracing/enforcer.go b/pkg/sensors/tracing/enforcer.go index 1266376dc98..9b663c2fd70 100644 --- a/pkg/sensors/tracing/enforcer.go +++ b/pkg/sensors/tracing/enforcer.go @@ -50,9 +50,8 @@ func init() { sensors.RegisterPolicyHandlerAtInit("enforcer", gEnforcerPolicy) } -func enforcerMap(policyName string, load ...*program.Program) *program.Map { - return program.MapBuilderPin(enforcerDataMapName, - fmt.Sprintf("%s_%s", enforcerDataMapName, policyName), load...) +func enforcerMap(load ...*program.Program) *program.Map { + return program.MapBuilderPolicy(enforcerDataMapName, load...) } func (kp *enforcerPolicy) enforcerGet(name string) (*enforcerHandler, bool) { @@ -315,7 +314,7 @@ func (kp *enforcerPolicy) createEnforcerSensor( return nil, fmt.Errorf("unexpected override method: %d", overrideMethod) } - enforcerDataMap := enforcerMap(policyName, progs...) + enforcerDataMap := enforcerMap(progs...) enforcerDataMap.SetMaxEntries(enforcerMapMaxEntries) maps = append(maps, enforcerDataMap) @@ -327,9 +326,10 @@ func (kp *enforcerPolicy) createEnforcerSensor( logger.GetLogger().Infof("Added enforcer sensor '%s'", name) return &sensors.Sensor{ - Name: "__enforcer__", - Progs: progs, - Maps: maps, + Name: "__enforcer__", + Progs: progs, + Maps: maps, + Policy: policyName, PostUnloadHook: func() error { if ok := kp.enforcerDel(name); !ok { logger.GetLogger().Infof("Failed to clean up enforcer sensor '%s'", name) diff --git a/pkg/sensors/tracing/generickprobe.go b/pkg/sensors/tracing/generickprobe.go index 5b3397751d8..6b6ab81782d 100644 --- a/pkg/sensors/tracing/generickprobe.go +++ b/pkg/sensors/tracing/generickprobe.go @@ -361,7 +361,7 @@ func createMultiKprobeSensor(policyName string, multiIDs []idtable.EntryID, has maps = append(maps, ratelimitMap) } - enforcerDataMap := enforcerMap(policyName, load) + enforcerDataMap := enforcerMap(load) if has.enforcer { enforcerDataMap.SetMaxEntries(enforcerMapMaxEntries) } @@ -957,7 +957,7 @@ func createKprobeSensorFromEntry(kprobeEntry *genericKprobe, maps = append(maps, ratelimitMap) } - enforcerDataMap := enforcerMap(kprobeEntry.policyName, load) + enforcerDataMap := enforcerMap(load) if has.enforcer { enforcerDataMap.SetMaxEntries(enforcerMapMaxEntries) } diff --git a/pkg/sensors/tracing/generictracepoint.go b/pkg/sensors/tracing/generictracepoint.go index e736fda8795..53a279af440 100644 --- a/pkg/sensors/tracing/generictracepoint.go +++ b/pkg/sensors/tracing/generictracepoint.go @@ -497,7 +497,7 @@ func createGenericTracepointSensor( } maps = append(maps, matchBinariesPaths) - enforcerDataMap := enforcerMap(policyName, prog0) + enforcerDataMap := enforcerMap(prog0) if has.enforcer { enforcerDataMap.SetMaxEntries(enforcerMapMaxEntries) } From abca15378bf206c2da141e7f14cf645f533c22fd Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 16 Jun 2024 20:51:02 +0000 Subject: [PATCH 15/35] tetragon: Get rid of MapBuilderPin functions Removing MapBuilderPin, because it's no longer needed and removing the pin argument from mapBuilder function. Signed-off-by: Jiri Olsa --- pkg/sensors/load.go | 8 ++++---- pkg/sensors/program/map.go | 21 ++++++++------------- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/pkg/sensors/load.go b/pkg/sensors/load.go index e4d34c6bfb8..a62c3fcc393 100644 --- a/pkg/sensors/load.go +++ b/pkg/sensors/load.go @@ -221,13 +221,13 @@ func (s *Sensor) FindPrograms() error { func (s *Sensor) setMapPinPath(m *program.Map) { switch m.Type { case program.MapTypeGlobal: - m.PinPath = filepath.Join(m.PinName) + m.PinPath = filepath.Join(m.Name) case program.MapTypePolicy: - m.PinPath = filepath.Join(s.Policy, m.PinName) + m.PinPath = filepath.Join(s.Policy, m.Name) case program.MapTypeSensor: - m.PinPath = filepath.Join(s.Policy, s.Name, m.PinName) + m.PinPath = filepath.Join(s.Policy, s.Name, m.Name) case program.MapTypeProgram: - m.PinPath = filepath.Join(s.Policy, s.Name, m.Prog.PinName, m.PinName) + m.PinPath = filepath.Join(s.Policy, s.Name, m.Prog.PinName, m.Name) } } diff --git a/pkg/sensors/program/map.go b/pkg/sensors/program/map.go index 95734a6ef24..bb66c55fcb8 100644 --- a/pkg/sensors/program/map.go +++ b/pkg/sensors/program/map.go @@ -31,7 +31,6 @@ const ( // Map represents BPF maps. type Map struct { Name string - PinName string PinPath string Prog *Program PinState State @@ -54,8 +53,8 @@ type Map struct { // p.PinMap["map2"] = &map2 // ... // p.PinMap["mapX"] = &mapX -func mapBuilder(name, pin string, ty MapType, lds ...*Program) *Map { - m := &Map{name, pin, "", lds[0], Idle(), nil, MaxEntries{0, false}, MaxEntries{0, false}, ty} +func mapBuilder(name string, ty MapType, lds ...*Program) *Map { + m := &Map{name, "", lds[0], Idle(), nil, MaxEntries{0, false}, MaxEntries{0, false}, ty} for _, ld := range lds { ld.PinMap[name] = m } @@ -63,27 +62,23 @@ func mapBuilder(name, pin string, ty MapType, lds ...*Program) *Map { } func MapBuilder(name string, lds ...*Program) *Map { - return mapBuilder(name, name, MapTypeGlobal, lds...) -} - -func MapBuilderPin(name, pin string, lds ...*Program) *Map { - return mapBuilder(name, pin, MapTypeGlobal, lds...) + return mapBuilder(name, MapTypeGlobal, lds...) } func MapBuilderProgram(name string, lds ...*Program) *Map { - return mapBuilder(name, name, MapTypeProgram, lds...) + return mapBuilder(name, MapTypeProgram, lds...) } func MapBuilderSensor(name string, lds ...*Program) *Map { - return mapBuilder(name, name, MapTypeSensor, lds...) + return mapBuilder(name, MapTypeSensor, lds...) } func MapBuilderPolicy(name string, lds ...*Program) *Map { - return mapBuilder(name, name, MapTypePolicy, lds...) + return mapBuilder(name, MapTypePolicy, lds...) } func MapBuilderType(name string, ty MapType, lds ...*Program) *Map { - return mapBuilder(name, name, ty, lds...) + return mapBuilder(name, ty, lds...) } func PolicyMapPath(mapDir, policy, name string) string { @@ -91,7 +86,7 @@ func PolicyMapPath(mapDir, policy, name string) string { } func (m *Map) Unload() error { - log := logger.GetLogger().WithField("map", m.Name).WithField("pin", m.PinName) + log := logger.GetLogger().WithField("map", m.Name).WithField("pin", m.Name) if !m.PinState.IsLoaded() { log.WithField("count", m.PinState.count).Debug("Refusing to unload map as it is not loaded") return nil From bce80975342f07dffecc68ee690d451e7ccb8577 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 13 Jun 2024 08:30:54 +0000 Subject: [PATCH 16/35] tetragon: Sanitize policy name before using it in path Policy name is provided by tracing-policy/user. It already has some restrictions, but let's add at least substitute for '/' characters for '_' to ensure the path is not mangled. Signed-off-by: Jiri Olsa --- pkg/sensors/load.go | 9 +++++---- pkg/sensors/sensors.go | 5 +++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/pkg/sensors/load.go b/pkg/sensors/load.go index a62c3fcc393..3fd4a7c9e0f 100644 --- a/pkg/sensors/load.go +++ b/pkg/sensors/load.go @@ -65,7 +65,7 @@ func LoadConfig(bpfDir string, sens []*Sensor) error { func (s *Sensor) setupProgsPinPath(bpfDir string) { for _, p := range s.Progs { // setup sensor based program pin path - p.PinPath = filepath.Join(s.Policy, s.Name, p.PinName) + p.PinPath = filepath.Join(sanitize(s.Policy), s.Name, p.PinName) // and make the path os.MkdirAll(filepath.Join(bpfDir, p.PinPath), os.ModeDir) } @@ -219,15 +219,16 @@ func (s *Sensor) FindPrograms() error { } func (s *Sensor) setMapPinPath(m *program.Map) { + policy := sanitize(s.Policy) switch m.Type { case program.MapTypeGlobal: m.PinPath = filepath.Join(m.Name) case program.MapTypePolicy: - m.PinPath = filepath.Join(s.Policy, m.Name) + m.PinPath = filepath.Join(policy, m.Name) case program.MapTypeSensor: - m.PinPath = filepath.Join(s.Policy, s.Name, m.Name) + m.PinPath = filepath.Join(policy, s.Name, m.Name) case program.MapTypeProgram: - m.PinPath = filepath.Join(s.Policy, s.Name, m.Prog.PinName, m.Name) + m.PinPath = filepath.Join(policy, s.Name, m.Prog.PinName, m.Name) } } diff --git a/pkg/sensors/sensors.go b/pkg/sensors/sensors.go index cd7e4f70757..698276436a3 100644 --- a/pkg/sensors/sensors.go +++ b/pkg/sensors/sensors.go @@ -5,6 +5,7 @@ package sensors import ( "fmt" + "strings" "sync" "github.com/cilium/tetragon/pkg/logger" @@ -63,6 +64,10 @@ type Sensor struct { DestroyHook SensorHook } +func sanitize(name string) string { + return strings.ReplaceAll(name, "/", "_") +} + // SensorIface is an interface for sensors.Sensor that allows implementing sensors for testing. type SensorIface interface { GetName() string From b2414a97bb639ae2f6bfc585c605222eb06fbd8a Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 9 Jul 2024 08:54:56 +0000 Subject: [PATCH 17/35] tetragon: Adjust linkPinPath for new hierarchy Adjusting linkPinPath for new hierarchy to use program's PinPath directory with 'link' file name. Plus '_override' suffix for override link. Signed-off-by: Jiri Olsa --- pkg/sensors/program/loader.go | 12 +++--------- pkg/sensors/program/loader_test.go | 19 ++++++++++--------- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/pkg/sensors/program/loader.go b/pkg/sensors/program/loader.go index 1163d9d4e59..fe95f12280d 100644 --- a/pkg/sensors/program/loader.go +++ b/pkg/sensors/program/loader.go @@ -32,17 +32,11 @@ type LoadOpts struct { } func linkPinPath(bpfDir string, load *Program, extra ...string) string { - pinPath := filepath.Join(bpfDir, load.PinPath) - if load.Override { - pinPath = pinPath + "_override" - } - if load.RetProbe { - pinPath = pinPath + "_return" - } + pinPath := filepath.Join(bpfDir, load.PinPath, "link") if len(extra) != 0 { pinPath = pinPath + "_" + strings.Join(extra, "_") } - return pinPath + "_link" + return pinPath } func linkPin(lnk link.Link, bpfDir string, load *Program, extra ...string) error { @@ -235,7 +229,7 @@ func kprobeAttachOverride(load *Program, bpfDir string, return fmt.Errorf("pinning '%s' to '%s' failed: %w", load.Label, pinPath, err) } - load.unloaderOverride, err = kprobeAttach(load, prog, spec, load.Attach, bpfDir) + load.unloaderOverride, err = kprobeAttach(load, prog, spec, load.Attach, bpfDir, "override") if err != nil { logger.GetLogger().Warnf("Failed to attach override program: %w", err) } diff --git a/pkg/sensors/program/loader_test.go b/pkg/sensors/program/loader_test.go index 6fc14f10003..c4084108093 100644 --- a/pkg/sensors/program/loader_test.go +++ b/pkg/sensors/program/loader_test.go @@ -16,20 +16,21 @@ func TestLoaderLinkPinPath(t *testing.T) { var load *Program var pin string + // standard link load = Builder("", "", "", "event", "") + load.PinPath = "test/generic_kprobe/__x64_sys_linkat" pin = linkPinPath(bpfDir, load) - assert.Equal(t, filepath.Join(bpfDir, "event_link"), pin) + assert.Equal(t, filepath.Join(bpfDir, "test/generic_kprobe/__x64_sys_linkat", "link"), pin) + // override link load = Builder("", "", "", "event", "") - load.Override = true - pin = linkPinPath(bpfDir, load) - assert.Equal(t, filepath.Join(bpfDir, "event_override_link"), pin) - - load = Builder("", "", "", "event", "").SetRetProbe(true) - pin = linkPinPath(bpfDir, load) - assert.Equal(t, filepath.Join(bpfDir, "event_return_link"), pin) + load.PinPath = "test/generic_kprobe/__x64_sys_linkat" + pin = linkPinPath(bpfDir, load, "override") + assert.Equal(t, filepath.Join(bpfDir, "test/generic_kprobe/__x64_sys_linkat", "link_override"), pin) + // many-kprobe link load = Builder("", "", "", "event", "") + load.PinPath = "test/generic_kprobe/__x64_sys_linkat" pin = linkPinPath(bpfDir, load, "1_sys_exit") - assert.Equal(t, filepath.Join(bpfDir, "event_1_sys_exit_link"), pin) + assert.Equal(t, filepath.Join(bpfDir, "test/generic_kprobe/__x64_sys_linkat", "link_1_sys_exit"), pin) } From 4af2d826d6431e1281455bdfb0b9434ba389ff32 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 24 May 2024 10:31:51 +0000 Subject: [PATCH 18/35] tetragon: Add policy argument to SensorBuilder function Adding policy argument to SensorBuilder function so it's passed to the Sensor object. Signed-off-by: Jiri Olsa --- pkg/sensors/sensors.go | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/pkg/sensors/sensors.go b/pkg/sensors/sensors.go index 698276436a3..56b1917b999 100644 --- a/pkg/sensors/sensors.go +++ b/pkg/sensors/sensors.go @@ -89,21 +89,22 @@ func (s *Sensor) IsLoaded() bool { // that can be called during sensor unloading and removing. type SensorHook func() error -func SensorCombine(name string, sensors ...*Sensor) *Sensor { +func SensorCombine(policy, name string, sensors ...*Sensor) *Sensor { progs := []*program.Program{} maps := []*program.Map{} for _, s := range sensors { progs = append(progs, s.Progs...) maps = append(maps, s.Maps...) } - return SensorBuilder(name, progs, maps) + return SensorBuilder(policy, name, progs, maps) } -func SensorBuilder(name string, p []*program.Program, m []*program.Map) *Sensor { +func SensorBuilder(policy, name string, p []*program.Program, m []*program.Map) *Sensor { return &Sensor{ - Name: name, - Progs: p, - Maps: m, + Name: name, + Progs: p, + Maps: m, + Policy: policy, } } @@ -175,7 +176,7 @@ func GetMergedSensorFromParserPolicy(tp tracingpolicy.TracingPolicy) (SensorIfac sensors = append(sensors, s) } - return SensorCombine(tp.TpName(), sensors...), nil + return SensorCombine(tp.TpName(), tp.TpName(), sensors...), nil } func progsAdd(progs []*program.Program) { From cbe8a474528b1ee663b32df6ef9e0d756fd4012a Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 18 Jun 2024 08:15:58 +0000 Subject: [PATCH 19/35] tetragon: Add tests for map builders Add tests for the map builders, will be likely extended. Signed-off-by: Jiri Olsa --- bpf/Makefile | 3 +- bpf/process/bpf_map_test_p1.c | 30 ++++++ bpf/process/bpf_map_test_p2.c | 30 ++++++ pkg/sensors/test/sensors_test.go | 163 +++++++++++++++++++++++++++++++ 4 files changed, 225 insertions(+), 1 deletion(-) create mode 100644 bpf/process/bpf_map_test_p1.c create mode 100644 bpf/process/bpf_map_test_p2.c create mode 100644 pkg/sensors/test/sensors_test.go diff --git a/bpf/Makefile b/bpf/Makefile index 11d7309c770..1a6fb86c093 100644 --- a/bpf/Makefile +++ b/bpf/Makefile @@ -30,7 +30,8 @@ PROCESS = bpf_execve_event.o bpf_execve_event_v53.o bpf_fork.o bpf_exit.o bpf_ge bpf_generic_lsm_v61.o \ bpf_loader.o \ bpf_cgroup.o \ - bpf_enforcer.o bpf_multi_enforcer.o bpf_fmodret_enforcer.o + bpf_enforcer.o bpf_multi_enforcer.o bpf_fmodret_enforcer.o \ + bpf_map_test_p1.o bpf_map_test_p2.o CGROUP = bpf_cgroup_mkdir.o bpf_cgroup_rmdir.o bpf_cgroup_release.o BPFTEST = bpf_lseek.o diff --git a/bpf/process/bpf_map_test_p1.c b/bpf/process/bpf_map_test_p1.c new file mode 100644 index 00000000000..ecf6eca49f4 --- /dev/null +++ b/bpf/process/bpf_map_test_p1.c @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* Copyright Authors of Cilium */ + +#include "vmlinux.h" +#include "api.h" +#include "bpf_tracing.h" +#include "bpf_helpers.h" +#include "compiler.h" + +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __uint(max_entries, 1); + __type(key, int); + __type(value, int); +} m1 SEC(".maps"); + +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __uint(max_entries, 1); + __type(key, int); + __type(value, int); +} m2 SEC(".maps"); + +__attribute__((section("kprobe/wake_up_new_task"), used)) int +BPF_KPROBE(p1) +{ + map_lookup_elem(&m1, &(int){ 0 }); + map_lookup_elem(&m2, &(int){ 0 }); + return 0; +} diff --git a/bpf/process/bpf_map_test_p2.c b/bpf/process/bpf_map_test_p2.c new file mode 100644 index 00000000000..42c20563a6c --- /dev/null +++ b/bpf/process/bpf_map_test_p2.c @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* Copyright Authors of Cilium */ + +#include "vmlinux.h" +#include "api.h" +#include "bpf_tracing.h" +#include "bpf_helpers.h" +#include "compiler.h" + +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __uint(max_entries, 1); + __type(key, int); + __type(value, int); +} m1 SEC(".maps"); + +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __uint(max_entries, 1); + __type(key, int); + __type(value, int); +} m2 SEC(".maps"); + +__attribute__((section("kprobe/wake_up_new_task"), used)) int +BPF_KPROBE(p2) +{ + map_lookup_elem(&m1, &(int){ 0 }); + map_lookup_elem(&m2, &(int){ 0 }); + return 0; +} diff --git a/pkg/sensors/test/sensors_test.go b/pkg/sensors/test/sensors_test.go new file mode 100644 index 00000000000..099b44f1456 --- /dev/null +++ b/pkg/sensors/test/sensors_test.go @@ -0,0 +1,163 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Authors of Tetragon + +package test + +import ( + "path/filepath" + "testing" + + "github.com/cilium/tetragon/pkg/bpf" + "github.com/cilium/tetragon/pkg/option" + "github.com/cilium/tetragon/pkg/sensors" + "github.com/cilium/tetragon/pkg/sensors/program" + tus "github.com/cilium/tetragon/pkg/testutils/sensors" + "github.com/stretchr/testify/assert" +) + +func TestMapBuildersSingle(t *testing.T) { + option.Config.HubbleLib = tus.Conf().TetragonLib + option.Config.Verbosity = 5 + + p1 := program.Builder( + "bpf_map_test_p1.o", + "wake_up_new_task", + "kprobe/wake_up_new_task", + "p1", + "kprobe", + ) + + test := func(m1 *program.Map, ty program.MapType) { + s := &sensors.Sensor{ + Name: "sensor", + Progs: []*program.Program{p1}, + Maps: []*program.Map{m1}, + Policy: "policy", + } + + getMapPath := func(m *program.Map) string { + path := "./" + switch ty { + case program.MapTypeGlobal: + // nothing + case program.MapTypePolicy: + path = filepath.Join(path, "policy") + case program.MapTypeSensor: + path = filepath.Join(path, "policy", "sensor") + case program.MapTypeProgram: + path = filepath.Join(path, "policy", "sensor", m.Prog.PinName) + } + return filepath.Join(path, m.Name) + } + + s.Load(bpf.MapPrefixPath()) + + assert.Equal(t, getMapPath(m1), m1.PinPath) + + s.Unload() + } + + test(program.MapBuilder("m1", p1), program.MapTypeGlobal) + test(program.MapBuilderProgram("m1", p1), program.MapTypeProgram) + test(program.MapBuilderSensor("m1", p1), program.MapTypeSensor) + test(program.MapBuilderPolicy("m1", p1), program.MapTypePolicy) +} + +func TestMapBuildersMulti(t *testing.T) { + option.Config.HubbleLib = tus.Conf().TetragonLib + option.Config.Verbosity = 5 + + p1 := program.Builder( + "bpf_map_test_p1.o", + "wake_up_new_task", + "kprobe/wake_up_new_task", + "p1", + "kprobe", + ) + + p2 := program.Builder( + "bpf_map_test_p2.o", + "wake_up_new_task", + "kprobe/wake_up_new_task", + "p2", + "kprobe", + ) + + test := func(m1, m2 *program.Map, path1, path2 string) { + s := &sensors.Sensor{ + Name: "sensor", + Progs: []*program.Program{p1, p2}, + Maps: []*program.Map{m1, m2}, + Policy: "policy", + } + + s.Load(bpf.MapPrefixPath()) + + assert.Equal(t, path1, m1.PinPath) + assert.Equal(t, path2, m2.PinPath) + + s.Unload() + } + + var m1 *program.Map + var m2 *program.Map + + // NOTE For program.MapBuilderProgram the map takes the + // first program as the base for its path + + // m1: policy/sensor/p1/m1 + // m2: policy/sensor/p2/m2 + m1 = program.MapBuilderProgram("m1", p1, p2) + m2 = program.MapBuilderProgram("m2", p2, p1) + + test(m1, m2, "policy/sensor/p1/m1", "policy/sensor/p2/m2") + + // m1: policy/m1 + // m2: policy/m2 + m1 = program.MapBuilderPolicy("m1", p1, p2) + m2 = program.MapBuilderPolicy("m2", p2, p1) + + test(m1, m2, "policy/m1", "policy/m2") + + // m1: policy/sensor/p1/m1 + // m2: policy/m2 + m1 = program.MapBuilderProgram("m1", p1, p2) + m2 = program.MapBuilderPolicy("m2", p2, p1) + + test(m1, m2, "policy/sensor/p1/m1", "policy/m2") + + // m1: policy/sensor/p1/m1 + // m2: policy/m2 + m1 = program.MapBuilderSensor("m1", p2, p1) + m2 = program.MapBuilderPolicy("m2", p2, p1) + + test(m1, m2, "policy/sensor/m1", "policy/m2") +} + +func TestPolicyMapPath(t *testing.T) { + option.Config.HubbleLib = tus.Conf().TetragonLib + option.Config.Verbosity = 5 + + p1 := program.Builder( + "bpf_map_test_p1.o", + "wake_up_new_task", + "kprobe/wake_up_new_task", + "p1", + "kprobe", + ) + + m1 := program.MapBuilderPolicy("m1", p1) + + s := &sensors.Sensor{ + Name: "sensor", + Progs: []*program.Program{p1}, + Maps: []*program.Map{m1}, + Policy: "policy", + } + + s.Load(bpf.MapPrefixPath()) + + assert.Equal(t, filepath.Join(bpf.MapPrefixPath(), m1.PinPath), program.PolicyMapPath(bpf.MapPrefixPath(), "policy", "m1")) + + s.Unload() +} From a27381e3b34ad7d3db01eda59c0dcd4b0087c4ee Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 18 Jun 2024 11:59:29 +0000 Subject: [PATCH 20/35] tetragon: Add tests for map max entries setup Adding tests for map max entries setup. Signed-off-by: Jiri Olsa --- pkg/sensors/test/sensors_test.go | 96 ++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/pkg/sensors/test/sensors_test.go b/pkg/sensors/test/sensors_test.go index 099b44f1456..cfd7e9fcc51 100644 --- a/pkg/sensors/test/sensors_test.go +++ b/pkg/sensors/test/sensors_test.go @@ -7,6 +7,7 @@ import ( "path/filepath" "testing" + "github.com/cilium/ebpf" "github.com/cilium/tetragon/pkg/bpf" "github.com/cilium/tetragon/pkg/option" "github.com/cilium/tetragon/pkg/sensors" @@ -161,3 +162,98 @@ func TestPolicyMapPath(t *testing.T) { s.Unload() } + +func getMaxEntries(t *testing.T, path string) uint32 { + m, err := ebpf.LoadPinnedMap(path, nil) + if err != nil { + t.Fatalf("failed to load map from '%s': %s\n", path, err) + } + + info, err := m.Info() + if err != nil { + t.Fatalf("failed to get map info: %s\n", err) + } + + return info.MaxEntries +} + +func TestMaxEntriesSingle(t *testing.T) { + option.Config.HubbleLib = tus.Conf().TetragonLib + option.Config.Verbosity = 5 + + p1 := program.Builder( + "bpf_map_test_p1.o", + "wake_up_new_task", + "kprobe/wake_up_new_task", + "p1", + "kprobe", + ) + + m1 := program.MapBuilderPolicy("m1", p1) + m1.SetMaxEntries(111) + + s := &sensors.Sensor{ + Name: "sensor", + Progs: []*program.Program{p1}, + Maps: []*program.Map{m1}, + Policy: "policy", + } + + s.Load(bpf.MapPrefixPath()) + defer s.Unload() + + path := program.PolicyMapPath(bpf.MapPrefixPath(), "policy", "m1") + assert.Equal(t, uint32(111), getMaxEntries(t, path)) +} + +func TestMaxEntriesMulti(t *testing.T) { + option.Config.HubbleLib = tus.Conf().TetragonLib + option.Config.Verbosity = 5 + + p1 := program.Builder( + "bpf_map_test_p1.o", + "wake_up_new_task", + "kprobe/wake_up_new_task", + "p1", + "kprobe", + ) + + p2 := program.Builder( + "bpf_map_test_p2.o", + "wake_up_new_task", + "kprobe/wake_up_new_task", + "p2", + "kprobe", + ) + + m1 := program.MapBuilderPolicy("m1", p1, p2) + m2 := program.MapBuilderSensor("m2", p2, p1) + m1.SetMaxEntries(111) + m2.SetMaxEntries(222) + + s := &sensors.Sensor{ + Name: "sensor", + Progs: []*program.Program{p1, p2}, + Maps: []*program.Map{m1, m2}, + Policy: "policy", + } + + s.Load(bpf.MapPrefixPath()) + defer s.Unload() + + path1 := filepath.Join(bpf.MapPrefixPath(), m1.PinPath) + assert.Equal(t, uint32(111), getMaxEntries(t, path1)) + + path2 := filepath.Join(bpf.MapPrefixPath(), m2.PinPath) + assert.Equal(t, uint32(222), getMaxEntries(t, path2)) +} + +func TestMaxEntriesInnerSingle(t *testing.T) { + // TODO, we need to check BTF for inner map max entries + t.Skip() +} + +func TestMaxEntriesInnerMulti(t *testing.T) { + // TODO, we need to check BTF for inner map max entries + t.Skip() +} From ff00258e8160d82c654c8db1aa4b2e905e0ffd03 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 18 Jun 2024 11:34:23 +0000 Subject: [PATCH 21/35] tetragon: Add documentation for maps usage Adding some notes in map.go header about maps usage. Signed-off-by: Jiri Olsa --- pkg/sensors/program/map.go | 47 ++++++++++++++++++++++++++++++++++ pkg/sensors/program/program.go | 25 ++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/pkg/sensors/program/map.go b/pkg/sensors/program/map.go index bb66c55fcb8..b9a6c8f9a93 100644 --- a/pkg/sensors/program/map.go +++ b/pkg/sensors/program/map.go @@ -1,6 +1,53 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright Authors of Tetragon +// We allow to define several types of maps: +// +// MapTypeGlobal MapType = iota +// MapTypePolicy +// MapTypeSensor +// MapTypeProgram +// +// Each type defines the maps position in the sysfs hierarchy: +// +// MapTypeGlobal: /sys/fs/bpf/tetragon/map +// MapTypePolicy: /sys/fs/bpf/tetragon/policy/map +// MapTypeSensor: /sys/fs/bpf/tetragon/policy/sensor/map +// MapTypeProgram: /sys/fs/bpf/tetragon/policy/sensor/program/map +// +// Each type has appropriate helper defined, which sets map's +// path to specific level of sysfs hierarchy: +// +// MapTypeGlobal: MapBuilder +// MapTypePolicy: MapBuilderPolicy +// MapTypeSensor: MapBuilderSensor +// MapTypeProgram: MapBuilderProgram +// +// It's possible to share map between more programs like: +// +// m := MapBuilderSensor("map", prog1, prog2, prog3) +// +// All prog1-3 programs will attach to m1 through: +// +// /sys/fs/bpf/tetragon/policy/sensor/map +// +// The idea is to share map on higher level which denotes to scope +// of the map, like: +// +// /sys/fs/bpf/tetragon/map +// - map is global shared with all policies/sensors/programs +// +// /sys/fs/bpf/tetragon/policy/map +// - map is local for policy, shared by all its sensors/programs +// +// /sys/fs/bpf/tetragon/policy/sensors/map +// - map is local for sensor, shared by all its programs +// +// /sys/fs/bpf/tetragon/policy/sensors/program/map +// - map is local for program, not shared at all +// +// NOTE Please do not share MapTypeProgram maps, it brings confusion. + package program import ( diff --git a/pkg/sensors/program/program.go b/pkg/sensors/program/program.go index c4df3b6e020..835d7d7d1fb 100644 --- a/pkg/sensors/program/program.go +++ b/pkg/sensors/program/program.go @@ -3,6 +3,31 @@ package program +// Program sysfs hierarchy +// +// Each program is part of policy and sensor and defines PinName +// which determine its path in sysfs hierarchy, like: +// +// /sys/fs/bpf/tetragon/policy/sensor/program/prog +// +// which broken down means: +// +// /sys/fs/bpf/tetragon +// - bpf (map) directory +// +// policy/sensor +// - defined by sensor.Policy/sensor.Name +// +// program +// - defined by program.PinName +// +// prog +// - fixed file name (prog_override for override program) +// +// The program.PinPath field hods following portion of the path: +// policy/sensor/program +// and is initialized when the sensor is loaded. + import ( "fmt" From d844a13a6d8082cda33b58637f2371ae95b717db Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 19 Aug 2024 13:40:17 +0000 Subject: [PATCH 22/35] github: Allow extern declarations in c files Signed-off-by: Jiri Olsa --- .github/workflows/checkpatch.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/checkpatch.yaml b/.github/workflows/checkpatch.yaml index c9bc8da64c7..2b1c82a61f0 100644 --- a/.github/workflows/checkpatch.yaml +++ b/.github/workflows/checkpatch.yaml @@ -19,4 +19,4 @@ jobs: - name: Run checkpatch.pl uses: docker://quay.io/cilium/cilium-checkpatch:2f0f4f512e795d5668ea4e7ef0ba85abc75eb225@sha256:f307bf0315954e8b8c31edc1864d949bf211b0c6522346359317d757b5a6cea0 with: - args: "-- --ignore PREFER_DEFINED_ATTRIBUTE_MACRO,C99_COMMENTS,OPEN_ENDED_LINE,PREFER_KERNEL_TYPES,REPEATED_WORD,SPDX_LICENSE_TAG,LONG_LINE,LONG_LINE_STRING,LONG_LINE_COMMENT,TRACE_PRINTK" + args: "-- --ignore PREFER_DEFINED_ATTRIBUTE_MACRO,C99_COMMENTS,OPEN_ENDED_LINE,PREFER_KERNEL_TYPES,REPEATED_WORD,SPDX_LICENSE_TAG,LONG_LINE,LONG_LINE_STRING,LONG_LINE_COMMENT,TRACE_PRINTK,AVOID_EXTERNS" From fd592e152b6e026241075e6c4e0c7ea8978f4c0f Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 30 Aug 2024 06:38:33 +0000 Subject: [PATCH 23/35] tetragon: Add local ebpf version Signed-off-by: Jiri Olsa --- go.mod | 2 + go.sum | 4 +- vendor/github.com/cilium/ebpf/.golangci.yaml | 6 + vendor/github.com/cilium/ebpf/CODEOWNERS | 2 + .../github.com/cilium/ebpf/asm/instruction.go | 3 +- vendor/github.com/cilium/ebpf/btf/ext_info.go | 4 +- vendor/github.com/cilium/ebpf/btf/handle.go | 1 + vendor/github.com/cilium/ebpf/btf/kernel.go | 3 +- vendor/github.com/cilium/ebpf/btf/marshal.go | 4 +- .../github.com/cilium/ebpf/btf/traversal.go | 54 +++++- vendor/github.com/cilium/ebpf/btf/types.go | 92 +++++++--- .../github.com/cilium/ebpf/btf/workarounds.go | 2 +- vendor/github.com/cilium/ebpf/collection.go | 5 +- vendor/github.com/cilium/ebpf/elf_reader.go | 13 +- vendor/github.com/cilium/ebpf/features/map.go | 6 +- .../github.com/cilium/ebpf/features/prog.go | 4 +- .../cilium/ebpf/features/version.go | 4 +- .../github.com/cilium/ebpf/internal/errors.go | 6 +- .../cilium/ebpf/internal/kconfig/kconfig.go | 26 +-- .../cilium/ebpf/internal/{ => linux}/auxv.go | 2 +- .../cilium/ebpf/internal/linux/doc.go | 2 + .../cilium/ebpf/internal/linux/kconfig.go | 31 ++++ .../ebpf/internal/{ => linux}/statfs.go | 2 +- .../cilium/ebpf/internal/{ => linux}/vdso.go | 9 +- .../cilium/ebpf/internal/linux/version.go | 34 ++++ .../github.com/cilium/ebpf/internal/sys/fd.go | 23 +-- .../cilium/ebpf/internal/sys/fd_trace.go | 93 ---------- .../ebpf/internal/sys/mapflags_string.go | 53 ------ .../cilium/ebpf/internal/{ => sys}/pinning.go | 16 +- .../cilium/ebpf/internal/sys/syscall.go | 37 ++-- .../cilium/ebpf/internal/sys/types.go | 168 +++++++++++++++++- .../internal/testutils/fdtrace/fd_trace.go | 103 +++++++++++ .../ebpf/internal/testutils/fdtrace/main.go | 31 ++++ .../cilium/ebpf/internal/tracefs/kprobe.go | 3 +- .../cilium/ebpf/internal/unix/types_linux.go | 5 +- .../cilium/ebpf/internal/unix/types_other.go | 5 +- .../cilium/ebpf/internal/version.go | 30 ---- vendor/github.com/cilium/ebpf/link/kprobe.go | 2 +- .../cilium/ebpf/link/kprobe_multi.go | 4 +- vendor/github.com/cilium/ebpf/link/link.go | 4 +- .../github.com/cilium/ebpf/link/netfilter.go | 2 +- .../github.com/cilium/ebpf/link/perf_event.go | 4 +- vendor/github.com/cilium/ebpf/link/tracing.go | 2 +- vendor/github.com/cilium/ebpf/link/uprobe.go | 2 +- .../cilium/ebpf/link/uprobe_multi.go | 4 +- vendor/github.com/cilium/ebpf/map.go | 28 +-- vendor/github.com/cilium/ebpf/prog.go | 15 +- vendor/github.com/cilium/ebpf/syscalls.go | 8 +- vendor/github.com/cilium/ebpf/types.go | 5 +- vendor/modules.txt | 5 +- 50 files changed, 603 insertions(+), 370 deletions(-) rename vendor/github.com/cilium/ebpf/internal/{ => linux}/auxv.go (98%) create mode 100644 vendor/github.com/cilium/ebpf/internal/linux/doc.go create mode 100644 vendor/github.com/cilium/ebpf/internal/linux/kconfig.go rename vendor/github.com/cilium/ebpf/internal/{ => linux}/statfs.go (96%) rename vendor/github.com/cilium/ebpf/internal/{ => linux}/vdso.go (93%) create mode 100644 vendor/github.com/cilium/ebpf/internal/linux/version.go delete mode 100644 vendor/github.com/cilium/ebpf/internal/sys/fd_trace.go delete mode 100644 vendor/github.com/cilium/ebpf/internal/sys/mapflags_string.go rename vendor/github.com/cilium/ebpf/internal/{ => sys}/pinning.go (77%) create mode 100644 vendor/github.com/cilium/ebpf/internal/testutils/fdtrace/fd_trace.go create mode 100644 vendor/github.com/cilium/ebpf/internal/testutils/fdtrace/main.go diff --git a/go.mod b/go.mod index fe51a9b5499..913b0bb4d30 100644 --- a/go.mod +++ b/go.mod @@ -205,6 +205,8 @@ require ( ) replace ( + github.com/cilium/ebpf => github.com/olsajiri/ebpf v0.9.1-0.20240829231511-6b7605ff8747 + // Use local version of API github.com/cilium/tetragon/api => ./api github.com/cilium/tetragon/pkg/k8s => ./pkg/k8s diff --git a/go.sum b/go.sum index 2d30c513c6a..4d29c6f2165 100644 --- a/go.sum +++ b/go.sum @@ -57,8 +57,6 @@ github.com/cilium/cilium v1.15.7 h1:7LwGfAW/fR/VFcm6zlESjE2Ut5vJWe+kdWq3RNJrNRc= github.com/cilium/cilium v1.15.7/go.mod h1:6Ml8eeyWjMJKDeadutWhn5NibMps0H+yLOgfKBoHTUs= github.com/cilium/controller-tools v0.8.0-1 h1:D5xhwSUZZceaKAacHOyfcpUMgLbs2TGeJEijNHlAQlc= github.com/cilium/controller-tools v0.8.0-1/go.mod h1:qE2DXhVOiEq5ijmINcFbqi9GZrrUjzB1TuJU0xa6eoY= -github.com/cilium/ebpf v0.16.0 h1:+BiEnHL6Z7lXnlGUsXQPPAE7+kenAd4ES8MQ5min0Ok= -github.com/cilium/ebpf v0.16.0/go.mod h1:L7u2Blt2jMM/vLAVgjxluxtBKlz3/GWjB0dMOEngfwE= github.com/cilium/little-vm-helper v0.0.19 h1:eJeJM/03MGLrLUXXTBDZo2JoX5cIbm5+9iWjoHgpy/M= github.com/cilium/little-vm-helper v0.0.19/go.mod h1:X3HGJKJ3/8vqP06VyajvD0nNDLYnGv96W8jWx4m3I7g= github.com/cilium/lumberjack/v2 v2.3.0 h1:IhVJMvPpqDYmQzC0KDhAoy7KlaRsyOsZnT97Nsa3u0o= @@ -421,6 +419,8 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olsajiri/ebpf v0.9.1-0.20240829231511-6b7605ff8747 h1:5OBQ4MW75++0AOFhXUcijJoE47eulhR+0xkWEroBY6U= +github.com/olsajiri/ebpf v0.9.1-0.20240829231511-6b7605ff8747/go.mod h1:L7u2Blt2jMM/vLAVgjxluxtBKlz3/GWjB0dMOEngfwE= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.17.2 h1:7eMhcy3GimbsA3hEnVKdw/PQM9XN9krpKVXsZdph0/g= diff --git a/vendor/github.com/cilium/ebpf/.golangci.yaml b/vendor/github.com/cilium/ebpf/.golangci.yaml index 65f91b910bf..366d4893f20 100644 --- a/vendor/github.com/cilium/ebpf/.golangci.yaml +++ b/vendor/github.com/cilium/ebpf/.golangci.yaml @@ -11,3 +11,9 @@ linters: - typecheck - unused - gofmt +linters-settings: + goimports: + # A comma-separated list of prefixes, which, if set, checks import paths + # with the given prefixes are grouped after 3rd-party packages. + # Default: "" + local-prefixes: github.com/cilium/ebpf diff --git a/vendor/github.com/cilium/ebpf/CODEOWNERS b/vendor/github.com/cilium/ebpf/CODEOWNERS index ca65d23c09d..0f76dce85c8 100644 --- a/vendor/github.com/cilium/ebpf/CODEOWNERS +++ b/vendor/github.com/cilium/ebpf/CODEOWNERS @@ -9,3 +9,5 @@ ringbuf/ @florianl btf/ @dylandreimerink cmd/bpf2go/ @mejedi + +docs/ @ti-mo diff --git a/vendor/github.com/cilium/ebpf/asm/instruction.go b/vendor/github.com/cilium/ebpf/asm/instruction.go index 67cd39d6f67..86b384c02a9 100644 --- a/vendor/github.com/cilium/ebpf/asm/instruction.go +++ b/vendor/github.com/cilium/ebpf/asm/instruction.go @@ -12,7 +12,6 @@ import ( "strings" "github.com/cilium/ebpf/internal/sys" - "github.com/cilium/ebpf/internal/unix" ) // InstructionSize is the size of a BPF instruction in bytes @@ -804,7 +803,7 @@ func (insns Instructions) Tag(bo binary.ByteOrder) (string, error) { return "", fmt.Errorf("instruction %d: %w", i, err) } } - return hex.EncodeToString(h.Sum(nil)[:unix.BPF_TAG_SIZE]), nil + return hex.EncodeToString(h.Sum(nil)[:sys.BPF_TAG_SIZE]), nil } // encodeFunctionReferences populates the Offset (or Constant, depending on diff --git a/vendor/github.com/cilium/ebpf/btf/ext_info.go b/vendor/github.com/cilium/ebpf/btf/ext_info.go index eb9044badf2..227189fcc42 100644 --- a/vendor/github.com/cilium/ebpf/btf/ext_info.go +++ b/vendor/github.com/cilium/ebpf/btf/ext_info.go @@ -799,7 +799,7 @@ func parseCORERelos(r io.Reader, bo binary.ByteOrder, strings *stringTable) (map return nil, err } - records, err := parseCOREReloRecords(r, bo, recordSize, infoHeader.NumInfo) + records, err := parseCOREReloRecords(r, bo, infoHeader.NumInfo) if err != nil { return nil, fmt.Errorf("section %v: %w", secName, err) } @@ -811,7 +811,7 @@ func parseCORERelos(r io.Reader, bo binary.ByteOrder, strings *stringTable) (map // parseCOREReloRecords parses a stream of CO-RE relocation entries into a // coreRelos. These records appear after a btf_ext_info_sec header in the // core_relos sub-section of .BTF.ext. -func parseCOREReloRecords(r io.Reader, bo binary.ByteOrder, recordSize uint32, recordNum uint32) ([]bpfCORERelo, error) { +func parseCOREReloRecords(r io.Reader, bo binary.ByteOrder, recordNum uint32) ([]bpfCORERelo, error) { var out []bpfCORERelo var relo bpfCORERelo diff --git a/vendor/github.com/cilium/ebpf/btf/handle.go b/vendor/github.com/cilium/ebpf/btf/handle.go index adfa6fed4bc..53dd763f64d 100644 --- a/vendor/github.com/cilium/ebpf/btf/handle.go +++ b/vendor/github.com/cilium/ebpf/btf/handle.go @@ -56,6 +56,7 @@ func NewHandleFromRawBTF(btf []byte) (*Handle, error) { logBuf []byte err error ) + for { var fd *sys.FD fd, err = sys.BtfLoad(attr) diff --git a/vendor/github.com/cilium/ebpf/btf/kernel.go b/vendor/github.com/cilium/ebpf/btf/kernel.go index 8584ebcb932..e5c54ce67b5 100644 --- a/vendor/github.com/cilium/ebpf/btf/kernel.go +++ b/vendor/github.com/cilium/ebpf/btf/kernel.go @@ -9,6 +9,7 @@ import ( "github.com/cilium/ebpf/internal" "github.com/cilium/ebpf/internal/kallsyms" + "github.com/cilium/ebpf/internal/linux" ) var kernelBTF = struct { @@ -130,7 +131,7 @@ func loadKernelModuleSpec(module string, base *Spec) (*Spec, error) { // findVMLinux scans multiple well-known paths for vmlinux kernel images. func findVMLinux() (*os.File, error) { - release, err := internal.KernelRelease() + release, err := linux.KernelRelease() if err != nil { return nil, err } diff --git a/vendor/github.com/cilium/ebpf/btf/marshal.go b/vendor/github.com/cilium/ebpf/btf/marshal.go index f14cfa6e973..ea6fc99aadd 100644 --- a/vendor/github.com/cilium/ebpf/btf/marshal.go +++ b/vendor/github.com/cilium/ebpf/btf/marshal.go @@ -409,7 +409,7 @@ func (e *encoder) deflateType(typ Type) (err error) { raw.data = &btfDeclTag{uint32(v.Index)} raw.NameOff, err = e.strings.Add(v.Value) - case *typeTag: + case *TypeTag: raw.SetKind(kindTypeTag) raw.SetType(e.id(v.Type)) raw.NameOff, err = e.strings.Add(v.Value) @@ -521,7 +521,7 @@ func (e *encoder) deflateEnum64(raw *rawType, enum *Enum) (err error) { }) } - return e.deflateUnion(raw, &Union{enum.Name, enum.Size, members}) + return e.deflateUnion(raw, &Union{enum.Name, enum.Size, members, nil}) } raw.SetKind(kindEnum64) diff --git a/vendor/github.com/cilium/ebpf/btf/traversal.go b/vendor/github.com/cilium/ebpf/btf/traversal.go index c39dc66e46c..aabd1609ddb 100644 --- a/vendor/github.com/cilium/ebpf/btf/traversal.go +++ b/vendor/github.com/cilium/ebpf/btf/traversal.go @@ -41,7 +41,7 @@ func children(typ Type, yield func(child *Type) bool) bool { // do its work. This avoids allocating intermediate slices from walk() on // the heap. switch v := typ.(type) { - case *Void, *Int, *Enum, *Fwd, *Float: + case *Void, *Int, *Enum, *Fwd, *Float, *declTag: // No children to traverse. case *Pointer: if !yield(&v.Target) { @@ -59,12 +59,36 @@ func children(typ Type, yield func(child *Type) bool) bool { if !yield(&v.Members[i].Type) { return false } + for _, t := range v.Members[i].Tags { + var tag Type = &declTag{t, v, i} + if !yield(&tag) { + return false + } + } + } + for _, t := range v.Tags { + var tag Type = &declTag{t, v, -1} + if !yield(&tag) { + return false + } } case *Union: for i := range v.Members { if !yield(&v.Members[i].Type) { return false } + for _, t := range v.Members[i].Tags { + var tag Type = &declTag{t, v, i} + if !yield(&tag) { + return false + } + } + } + for _, t := range v.Tags { + var tag Type = &declTag{t, v, -1} + if !yield(&tag) { + return false + } } case *Typedef: if !yield(&v.Type) { @@ -86,6 +110,22 @@ func children(typ Type, yield func(child *Type) bool) bool { if !yield(&v.Type) { return false } + for _, t := range v.Tags { + var tag Type = &declTag{t, v, -1} + if !yield(&tag) { + return false + } + } + if fp, ok := v.Type.(*FuncProto); ok { + for i, param := range fp.Params { + for _, t := range param.Tags { + var tag Type = &declTag{t, v, i} + if !yield(&tag) { + return false + } + } + } + } case *FuncProto: if !yield(&v.Return) { return false @@ -99,17 +139,19 @@ func children(typ Type, yield func(child *Type) bool) bool { if !yield(&v.Type) { return false } + for _, t := range v.Tags { + var tag Type = &declTag{t, v, -1} + if !yield(&tag) { + return false + } + } case *Datasec: for i := range v.Vars { if !yield(&v.Vars[i].Type) { return false } } - case *declTag: - if !yield(&v.Type) { - return false - } - case *typeTag: + case *TypeTag: if !yield(&v.Type) { return false } diff --git a/vendor/github.com/cilium/ebpf/btf/types.go b/vendor/github.com/cilium/ebpf/btf/types.go index a3397460b9d..c094b2ea75c 100644 --- a/vendor/github.com/cilium/ebpf/btf/types.go +++ b/vendor/github.com/cilium/ebpf/btf/types.go @@ -66,8 +66,7 @@ var ( _ Type = (*Var)(nil) _ Type = (*Datasec)(nil) _ Type = (*Float)(nil) - _ Type = (*declTag)(nil) - _ Type = (*typeTag)(nil) + _ Type = (*TypeTag)(nil) _ Type = (*cycle)(nil) ) @@ -169,6 +168,7 @@ type Struct struct { // The size of the struct including padding, in bytes Size uint32 Members []Member + Tags []string } func (s *Struct) Format(fs fmt.State, verb rune) { @@ -195,6 +195,7 @@ type Union struct { // The size of the union including padding, in bytes. Size uint32 Members []Member + Tags []string } func (u *Union) Format(fs fmt.State, verb rune) { @@ -247,6 +248,7 @@ type Member struct { Type Type Offset Bits BitfieldSize Bits + Tags []string } // Enum lists possible values. @@ -334,6 +336,7 @@ func (f *Fwd) matches(typ Type) bool { type Typedef struct { Name string Type Type + Tags []string } func (td *Typedef) Format(fs fmt.State, verb rune) { @@ -403,6 +406,7 @@ type Func struct { Name string Type Type Linkage FuncLinkage + Tags []string } func FuncMetadata(ins *asm.Instruction) *Func { @@ -449,6 +453,7 @@ func (fp *FuncProto) copy() Type { type FuncParam struct { Name string Type Type + Tags []string } // Var is a global variable. @@ -456,6 +461,7 @@ type Var struct { Name string Type Type Linkage VarLinkage + Tags []string } func (v *Var) Format(fs fmt.State, verb rune) { @@ -522,8 +528,8 @@ func (f *Float) copy() Type { // declTag associates metadata with a declaration. type declTag struct { - Type Type Value string + Type Type // The index this tag refers to in the target type. For composite types, // a value of -1 indicates that the tag refers to the whole type. Otherwise // it indicates which member or argument the tag applies to. @@ -540,19 +546,19 @@ func (dt *declTag) copy() Type { return &cpy } -// typeTag associates metadata with a type. -type typeTag struct { +// TypeTag associates metadata with a type. +type TypeTag struct { Type Type Value string } -func (tt *typeTag) Format(fs fmt.State, verb rune) { +func (tt *TypeTag) Format(fs fmt.State, verb rune) { formatType(fs, verb, tt, "type=", tt.Type, "value=", tt.Value) } -func (tt *typeTag) TypeName() string { return "" } -func (tt *typeTag) qualify() Type { return tt.Type } -func (tt *typeTag) copy() Type { +func (tt *TypeTag) TypeName() string { return "" } +func (tt *TypeTag) qualify() Type { return tt.Type } +func (tt *TypeTag) copy() Type { cpy := *tt return &cpy } @@ -591,7 +597,7 @@ var ( _ qualifier = (*Const)(nil) _ qualifier = (*Restrict)(nil) _ qualifier = (*Volatile)(nil) - _ qualifier = (*typeTag)(nil) + _ qualifier = (*TypeTag)(nil) ) var errUnsizedType = errors.New("type is unsized") @@ -918,7 +924,7 @@ func readAndInflateTypes(r io.Reader, bo binary.ByteOrder, typeLen uint32, rawSt if err != nil { return nil, fmt.Errorf("struct %s (id %d): %w", name, id, err) } - typ = &Struct{name, header.Size(), members} + typ = &Struct{name, header.Size(), members, nil} case kindUnion: vlen := header.Vlen() @@ -935,7 +941,7 @@ func readAndInflateTypes(r io.Reader, bo binary.ByteOrder, typeLen uint32, rawSt if err != nil { return nil, fmt.Errorf("union %s (id %d): %w", name, id, err) } - typ = &Union{name, header.Size(), members} + typ = &Union{name, header.Size(), members, nil} case kindEnum: vlen := header.Vlen() @@ -968,7 +974,7 @@ func readAndInflateTypes(r io.Reader, bo binary.ByteOrder, typeLen uint32, rawSt typ = &Fwd{name, header.FwdKind()} case kindTypedef: - typedef := &Typedef{name, nil} + typedef := &Typedef{name, nil, nil} fixup(header.Type(), &typedef.Type) typ = typedef @@ -988,7 +994,7 @@ func readAndInflateTypes(r io.Reader, bo binary.ByteOrder, typeLen uint32, rawSt typ = restrict case kindFunc: - fn := &Func{name, nil, header.Linkage()} + fn := &Func{name, nil, header.Linkage(), nil} fixup(header.Type(), &fn.Type) typ = fn @@ -1030,7 +1036,7 @@ func readAndInflateTypes(r io.Reader, bo binary.ByteOrder, typeLen uint32, rawSt return nil, fmt.Errorf("can't read btfVariable, id: %d: %w", id, err) } - v := &Var{name, nil, VarLinkage(bVariable.Linkage)} + v := &Var{name, nil, VarLinkage(bVariable.Linkage), nil} fixup(header.Type(), &v.Type) typ = v @@ -1074,14 +1080,14 @@ func readAndInflateTypes(r io.Reader, bo binary.ByteOrder, typeLen uint32, rawSt return nil, fmt.Errorf("type id %d: index exceeds int", id) } - dt := &declTag{nil, name, int(int32(btfIndex))} + dt := &declTag{name, nil, int(int32(btfIndex))} fixup(header.Type(), &dt.Type) - typ = dt + typ = &Void{} declTags = append(declTags, dt) case kindTypeTag: - tt := &typeTag{nil, name} + tt := &TypeTag{nil, name} fixup(header.Type(), &tt.Type) typ = tt @@ -1142,26 +1148,64 @@ func readAndInflateTypes(r io.Reader, bo binary.ByteOrder, typeLen uint32, rawSt for _, dt := range declTags { switch t := dt.Type.(type) { - case *Var, *Typedef: + case *Var: + if dt.Index != -1 { + return nil, fmt.Errorf("type %s: component idx %d is not -1", dt, dt.Index) + } + t.Tags = append(t.Tags, dt.Value) + + case *Typedef: if dt.Index != -1 { - return nil, fmt.Errorf("type %s: index %d is not -1", dt, dt.Index) + return nil, fmt.Errorf("type %s: component idx %d is not -1", dt, dt.Index) } + t.Tags = append(t.Tags, dt.Value) case composite: - if dt.Index >= len(t.members()) { - return nil, fmt.Errorf("type %s: index %d exceeds members of %s", dt, dt.Index, t) + if dt.Index >= 0 { + members := t.members() + if dt.Index >= len(members) { + return nil, fmt.Errorf("type %s: component idx %d exceeds members of %s", dt, dt.Index, t) + } + + members[dt.Index].Tags = append(members[dt.Index].Tags, dt.Value) + continue + } + + if dt.Index == -1 { + switch t2 := t.(type) { + case *Struct: + t2.Tags = append(t2.Tags, dt.Value) + case *Union: + t2.Tags = append(t2.Tags, dt.Value) + } + + continue } + return nil, fmt.Errorf("type %s: decl tag for type %s has invalid component idx", dt, t) + case *Func: fp, ok := t.Type.(*FuncProto) if !ok { return nil, fmt.Errorf("type %s: %s is not a FuncProto", dt, t.Type) } - if dt.Index >= len(fp.Params) { - return nil, fmt.Errorf("type %s: index %d exceeds params of %s", dt, dt.Index, t) + if dt.Index >= 0 { + if dt.Index >= len(fp.Params) { + return nil, fmt.Errorf("type %s: component idx %d exceeds params of %s", dt, dt.Index, t) + } + + fp.Params[dt.Index].Tags = append(fp.Params[dt.Index].Tags, dt.Value) + continue } + if dt.Index == -1 { + t.Tags = append(t.Tags, dt.Value) + continue + } + + return nil, fmt.Errorf("type %s: decl tag for type %s has invalid component idx", dt, t) + default: return nil, fmt.Errorf("type %s: decl tag for type %s is not supported", dt, t) } diff --git a/vendor/github.com/cilium/ebpf/btf/workarounds.go b/vendor/github.com/cilium/ebpf/btf/workarounds.go index 12a89b87eed..eb09047fb30 100644 --- a/vendor/github.com/cilium/ebpf/btf/workarounds.go +++ b/vendor/github.com/cilium/ebpf/btf/workarounds.go @@ -12,7 +12,7 @@ func datasecResolveWorkaround(b *Builder, ds *Datasec) error { } switch v.Type.(type) { - case *Typedef, *Volatile, *Const, *Restrict, *typeTag: + case *Typedef, *Volatile, *Const, *Restrict, *TypeTag: // NB: We must never call Add on a Datasec, otherwise we risk // infinite recursion. _, err := b.Add(v.Type) diff --git a/vendor/github.com/cilium/ebpf/collection.go b/vendor/github.com/cilium/ebpf/collection.go index b2cb214adce..36231056fa4 100644 --- a/vendor/github.com/cilium/ebpf/collection.go +++ b/vendor/github.com/cilium/ebpf/collection.go @@ -11,6 +11,7 @@ import ( "github.com/cilium/ebpf/btf" "github.com/cilium/ebpf/internal" "github.com/cilium/ebpf/internal/kconfig" + "github.com/cilium/ebpf/internal/linux" "github.com/cilium/ebpf/internal/sysenc" ) @@ -619,7 +620,7 @@ func resolveKconfig(m *MapSpec) error { return fmt.Errorf("variable %s must be a 32 bits integer, got %s", n, v.Type) } - kv, err := internal.KernelVersion() + kv, err := linux.KernelVersion() if err != nil { return fmt.Errorf("getting kernel version: %w", err) } @@ -651,7 +652,7 @@ func resolveKconfig(m *MapSpec) error { // We only parse kconfig file if a CONFIG_* variable was found. if len(configs) > 0 { - f, err := kconfig.Find() + f, err := linux.FindKConfig() if err != nil { return fmt.Errorf("cannot find a kconfig file: %w", err) } diff --git a/vendor/github.com/cilium/ebpf/elf_reader.go b/vendor/github.com/cilium/ebpf/elf_reader.go index 620037d80a8..a7b844a7ddd 100644 --- a/vendor/github.com/cilium/ebpf/elf_reader.go +++ b/vendor/github.com/cilium/ebpf/elf_reader.go @@ -16,7 +16,6 @@ import ( "github.com/cilium/ebpf/btf" "github.com/cilium/ebpf/internal" "github.com/cilium/ebpf/internal/sys" - "github.com/cilium/ebpf/internal/unix" ) type kconfigMetaKey struct{} @@ -71,7 +70,7 @@ func LoadCollectionSpecFromReader(rd io.ReaderAt) (*CollectionSpec, error) { // Checks if the ELF file is for BPF data. // Old LLVM versions set e_machine to EM_NONE. - if f.File.Machine != unix.EM_NONE && f.File.Machine != elf.EM_BPF { + if f.File.Machine != elf.EM_NONE && f.File.Machine != elf.EM_BPF { return nil, fmt.Errorf("unexpected machine type for BPF ELF: %s", f.File.Machine) } @@ -101,7 +100,7 @@ func LoadCollectionSpecFromReader(rd io.ReaderAt) (*CollectionSpec, error) { sections[idx] = newElfSection(sec, mapSection) case sec.Name == ".maps": sections[idx] = newElfSection(sec, btfMapSection) - case sec.Name == ".bss" || sec.Name == ".data" || strings.HasPrefix(sec.Name, ".rodata"): + case sec.Name == ".bss" || strings.HasPrefix(sec.Name, ".data") || strings.HasPrefix(sec.Name, ".rodata"): sections[idx] = newElfSection(sec, dataSection) case sec.Type == elf.SHT_REL: // Store relocations under the section index of the target @@ -1139,7 +1138,7 @@ func (ec *elfCode) loadDataSections() error { } if strings.HasPrefix(sec.Name, ".rodata") { - mapSpec.Flags = unix.BPF_F_RDONLY_PROG + mapSpec.Flags = sys.BPF_F_RDONLY_PROG mapSpec.Freeze = true } @@ -1175,7 +1174,7 @@ func (ec *elfCode) loadKconfigSection() error { KeySize: uint32(4), ValueSize: ds.Size, MaxEntries: 1, - Flags: unix.BPF_F_RDONLY_PROG, + Flags: sys.BPF_F_RDONLY_PROG, Freeze: true, Key: &btf.Int{Size: 4}, Value: ds, @@ -1266,10 +1265,10 @@ func getProgType(sectionName string) (ProgramType, AttachType, uint32, string) { var flags uint32 if t.flags&_SEC_SLEEPABLE > 0 { - flags |= unix.BPF_F_SLEEPABLE + flags |= sys.BPF_F_SLEEPABLE } if t.flags&_SEC_XDP_FRAGS > 0 { - flags |= unix.BPF_F_XDP_HAS_FRAGS + flags |= sys.BPF_F_XDP_HAS_FRAGS } if t.flags&_SEC_EXP_ATTACH_OPT > 0 { if programType == XDP { diff --git a/vendor/github.com/cilium/ebpf/features/map.go b/vendor/github.com/cilium/ebpf/features/map.go index 8923e736a1c..4b16e6af42a 100644 --- a/vendor/github.com/cilium/ebpf/features/map.go +++ b/vendor/github.com/cilium/ebpf/features/map.go @@ -40,7 +40,7 @@ func probeStorageMap(mt sys.MapType) error { KeySize: 4, ValueSize: 4, MaxEntries: 0, - MapFlags: unix.BPF_F_NO_PREALLOC, + MapFlags: sys.BPF_F_NO_PREALLOC, BtfKeyTypeId: 1, BtfValueTypeId: 1, BtfFd: ^uint32(0), @@ -123,7 +123,7 @@ var haveMapTypeMatrix = internal.FeatureMatrix[ebpf.MapType]{ MapType: sys.BPF_MAP_TYPE_LPM_TRIE, KeySize: 8, ValueSize: 8, - MapFlags: unix.BPF_F_NO_PREALLOC, + MapFlags: sys.BPF_F_NO_PREALLOC, }) }, }, @@ -227,7 +227,7 @@ func init() { } // MapFlags document which flags may be feature probed. -type MapFlags = sys.MapFlags +type MapFlags uint32 // Flags which may be feature probed. const ( diff --git a/vendor/github.com/cilium/ebpf/features/prog.go b/vendor/github.com/cilium/ebpf/features/prog.go index dc13b86d3a6..003bf006464 100644 --- a/vendor/github.com/cilium/ebpf/features/prog.go +++ b/vendor/github.com/cilium/ebpf/features/prog.go @@ -185,7 +185,7 @@ var haveProgramTypeMatrix = internal.FeatureMatrix[ebpf.ProgramType]{ Fn: func() error { return probeProgram(&ebpf.ProgramSpec{ Type: ebpf.Syscall, - Flags: unix.BPF_F_SLEEPABLE, + Flags: sys.BPF_F_SLEEPABLE, }) }, }, @@ -263,7 +263,7 @@ func haveProgramHelper(pt ebpf.ProgramType, helper asm.BuiltinFunc) error { case ebpf.SkLookup: spec.AttachType = ebpf.AttachSkLookup case ebpf.Syscall: - spec.Flags = unix.BPF_F_SLEEPABLE + spec.Flags = sys.BPF_F_SLEEPABLE } prog, err := ebpf.NewProgramWithOptions(spec, ebpf.ProgramOptions{ diff --git a/vendor/github.com/cilium/ebpf/features/version.go b/vendor/github.com/cilium/ebpf/features/version.go index 69e1c39c1a5..d54d3ea2121 100644 --- a/vendor/github.com/cilium/ebpf/features/version.go +++ b/vendor/github.com/cilium/ebpf/features/version.go @@ -1,6 +1,6 @@ package features -import "github.com/cilium/ebpf/internal" +import "github.com/cilium/ebpf/internal/linux" // LinuxVersionCode returns the version of the currently running kernel // as defined in the LINUX_VERSION_CODE compile-time macro. It is represented @@ -10,7 +10,7 @@ import "github.com/cilium/ebpf/internal" // kernel features, always prefer feature probes in this package. Some // distributions backport or disable eBPF features. func LinuxVersionCode() (uint32, error) { - v, err := internal.KernelVersion() + v, err := linux.KernelVersion() if err != nil { return 0, err } diff --git a/vendor/github.com/cilium/ebpf/internal/errors.go b/vendor/github.com/cilium/ebpf/internal/errors.go index 83a371ad35d..19d5294ca04 100644 --- a/vendor/github.com/cilium/ebpf/internal/errors.go +++ b/vendor/github.com/cilium/ebpf/internal/errors.go @@ -23,7 +23,7 @@ func ErrorWithLog(source string, err error, log []byte) *VerifierError { log = bytes.Trim(log, whitespace) if len(log) == 0 { - return &VerifierError{source, err, nil, false} + return &VerifierError{source, err, nil} } logLines := bytes.Split(log, []byte{'\n'}) @@ -34,7 +34,7 @@ func ErrorWithLog(source string, err error, log []byte) *VerifierError { lines = append(lines, string(bytes.TrimRight(line, whitespace))) } - return &VerifierError{source, err, lines, false} + return &VerifierError{source, err, lines} } // VerifierError includes information from the eBPF verifier. @@ -46,8 +46,6 @@ type VerifierError struct { Cause error // The verifier output split into lines. Log []string - // Deprecated: the log is never truncated anymore. - Truncated bool } func (le *VerifierError) Unwrap() error { diff --git a/vendor/github.com/cilium/ebpf/internal/kconfig/kconfig.go b/vendor/github.com/cilium/ebpf/internal/kconfig/kconfig.go index 1921e4f15ad..c32c066eb0b 100644 --- a/vendor/github.com/cilium/ebpf/internal/kconfig/kconfig.go +++ b/vendor/github.com/cilium/ebpf/internal/kconfig/kconfig.go @@ -1,3 +1,4 @@ +// Package kconfig implements a parser for the format of Linux's .config file. package kconfig import ( @@ -7,7 +8,6 @@ import ( "fmt" "io" "math" - "os" "strconv" "strings" @@ -15,30 +15,6 @@ import ( "github.com/cilium/ebpf/internal" ) -// Find find a kconfig file on the host. -// It first reads from /boot/config- of the current running kernel and tries -// /proc/config.gz if nothing was found in /boot. -// If none of the file provide a kconfig, it returns an error. -func Find() (*os.File, error) { - kernelRelease, err := internal.KernelRelease() - if err != nil { - return nil, fmt.Errorf("cannot get kernel release: %w", err) - } - - path := "/boot/config-" + kernelRelease - f, err := os.Open(path) - if err == nil { - return f, nil - } - - f, err = os.Open("/proc/config.gz") - if err == nil { - return f, nil - } - - return nil, fmt.Errorf("neither %s nor /proc/config.gz provide a kconfig", path) -} - // Parse parses the kconfig file for which a reader is given. // All the CONFIG_* which are in filter and which are set set will be // put in the returned map as key with their corresponding value as map value. diff --git a/vendor/github.com/cilium/ebpf/internal/auxv.go b/vendor/github.com/cilium/ebpf/internal/linux/auxv.go similarity index 98% rename from vendor/github.com/cilium/ebpf/internal/auxv.go rename to vendor/github.com/cilium/ebpf/internal/linux/auxv.go index 45fd0d37f13..98bb5d83cad 100644 --- a/vendor/github.com/cilium/ebpf/internal/auxv.go +++ b/vendor/github.com/cilium/ebpf/internal/linux/auxv.go @@ -1,4 +1,4 @@ -package internal +package linux import ( "errors" diff --git a/vendor/github.com/cilium/ebpf/internal/linux/doc.go b/vendor/github.com/cilium/ebpf/internal/linux/doc.go new file mode 100644 index 00000000000..064e75437d8 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/internal/linux/doc.go @@ -0,0 +1,2 @@ +// Package linux contains OS specific wrappers around package unix. +package linux diff --git a/vendor/github.com/cilium/ebpf/internal/linux/kconfig.go b/vendor/github.com/cilium/ebpf/internal/linux/kconfig.go new file mode 100644 index 00000000000..1488ecb35c3 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/internal/linux/kconfig.go @@ -0,0 +1,31 @@ +package linux + +import ( + "fmt" + "os" +) + +// FindKConfig searches for a kconfig file on the host. +// +// It first reads from /boot/config- of the current running kernel and tries +// /proc/config.gz if nothing was found in /boot. +// If none of the file provide a kconfig, it returns an error. +func FindKConfig() (*os.File, error) { + kernelRelease, err := KernelRelease() + if err != nil { + return nil, fmt.Errorf("cannot get kernel release: %w", err) + } + + path := "/boot/config-" + kernelRelease + f, err := os.Open(path) + if err == nil { + return f, nil + } + + f, err = os.Open("/proc/config.gz") + if err == nil { + return f, nil + } + + return nil, fmt.Errorf("neither %s nor /proc/config.gz provide a kconfig", path) +} diff --git a/vendor/github.com/cilium/ebpf/internal/statfs.go b/vendor/github.com/cilium/ebpf/internal/linux/statfs.go similarity index 96% rename from vendor/github.com/cilium/ebpf/internal/statfs.go rename to vendor/github.com/cilium/ebpf/internal/linux/statfs.go index 44c02d676e6..e268c06fab6 100644 --- a/vendor/github.com/cilium/ebpf/internal/statfs.go +++ b/vendor/github.com/cilium/ebpf/internal/linux/statfs.go @@ -1,4 +1,4 @@ -package internal +package linux import ( "unsafe" diff --git a/vendor/github.com/cilium/ebpf/internal/vdso.go b/vendor/github.com/cilium/ebpf/internal/linux/vdso.go similarity index 93% rename from vendor/github.com/cilium/ebpf/internal/vdso.go rename to vendor/github.com/cilium/ebpf/internal/linux/vdso.go index 1049278554e..1d8d0ef6b11 100644 --- a/vendor/github.com/cilium/ebpf/internal/vdso.go +++ b/vendor/github.com/cilium/ebpf/internal/linux/vdso.go @@ -1,4 +1,4 @@ -package internal +package linux import ( "debug/elf" @@ -9,6 +9,7 @@ import ( "math" "os" + "github.com/cilium/ebpf/internal" "github.com/cilium/ebpf/internal/unix" ) @@ -82,7 +83,7 @@ type elfNoteHeader struct { // vdsoLinuxVersionCode returns the LINUX_VERSION_CODE embedded in // the ELF notes section of the binary provided by the reader. func vdsoLinuxVersionCode(r io.ReaderAt) (uint32, error) { - hdr, err := NewSafeELFFile(r) + hdr, err := internal.NewSafeELFFile(r) if err != nil { return 0, fmt.Errorf("reading vDSO ELF: %w", err) } @@ -110,7 +111,7 @@ func vdsoLinuxVersionCode(r io.ReaderAt) (uint32, error) { var name string if n.NameSize > 0 { // Read the note name, aligned to 4 bytes. - buf := make([]byte, Align(n.NameSize, 4)) + buf := make([]byte, internal.Align(n.NameSize, 4)) if err := binary.Read(sr, hdr.ByteOrder, &buf); err != nil { return 0, fmt.Errorf("reading note name: %w", err) } @@ -132,7 +133,7 @@ func vdsoLinuxVersionCode(r io.ReaderAt) (uint32, error) { } // Discard the note descriptor if it exists but we're not interested in it. - if _, err := io.CopyN(io.Discard, sr, int64(Align(n.DescSize, 4))); err != nil { + if _, err := io.CopyN(io.Discard, sr, int64(internal.Align(n.DescSize, 4))); err != nil { return 0, err } } diff --git a/vendor/github.com/cilium/ebpf/internal/linux/version.go b/vendor/github.com/cilium/ebpf/internal/linux/version.go new file mode 100644 index 00000000000..798dd3fed02 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/internal/linux/version.go @@ -0,0 +1,34 @@ +package linux + +import ( + "fmt" + "sync" + + "github.com/cilium/ebpf/internal" + "github.com/cilium/ebpf/internal/unix" +) + +// KernelVersion returns the version of the currently running kernel. +var KernelVersion = sync.OnceValues(detectKernelVersion) + +// detectKernelVersion returns the version of the running kernel. +func detectKernelVersion() (internal.Version, error) { + vc, err := vdsoVersion() + if err != nil { + return internal.Version{}, err + } + return internal.NewVersionFromCode(vc), nil +} + +// KernelRelease returns the release string of the running kernel. +// Its format depends on the Linux distribution and corresponds to directory +// names in /lib/modules by convention. Some examples are 5.15.17-1-lts and +// 4.19.0-16-amd64. +func KernelRelease() (string, error) { + var uname unix.Utsname + if err := unix.Uname(&uname); err != nil { + return "", fmt.Errorf("uname failed: %w", err) + } + + return unix.ByteSliceToString(uname.Release[:]), nil +} diff --git a/vendor/github.com/cilium/ebpf/internal/sys/fd.go b/vendor/github.com/cilium/ebpf/internal/sys/fd.go index 941a56fb91b..028be004557 100644 --- a/vendor/github.com/cilium/ebpf/internal/sys/fd.go +++ b/vendor/github.com/cilium/ebpf/internal/sys/fd.go @@ -7,6 +7,7 @@ import ( "runtime" "strconv" + "github.com/cilium/ebpf/internal/testutils/fdtrace" "github.com/cilium/ebpf/internal/unix" ) @@ -17,15 +18,7 @@ type FD struct { } func newFD(value int) *FD { - if onLeakFD != nil { - // Attempt to store the caller's stack for the given fd value. - // Panic if fds contains an existing stack for the fd. - old, exist := fds.LoadOrStore(value, callersFrames()) - if exist { - f := old.(*runtime.Frames) - panic(fmt.Sprintf("found existing stack for fd %d:\n%s", value, FormatFrames(f))) - } - } + fdtrace.TraceFD(value, 1) fd := &FD{value} runtime.SetFinalizer(fd, (*FD).finalize) @@ -39,13 +32,7 @@ func (fd *FD) finalize() { return } - // Invoke the fd leak callback. Calls LoadAndDelete to guarantee the callback - // is invoked at most once for one sys.FD allocation, runtime.Frames can only - // be unwound once. - f, ok := fds.LoadAndDelete(fd.Int()) - if ok && onLeakFD != nil { - onLeakFD(f.(*runtime.Frames)) - } + fdtrace.LeakFD(fd.raw) _ = fd.Close() } @@ -96,8 +83,8 @@ func (fd *FD) Close() error { } func (fd *FD) disown() int { - value := int(fd.raw) - fds.Delete(int(value)) + value := fd.raw + fdtrace.ForgetFD(value) fd.raw = -1 runtime.SetFinalizer(fd, nil) diff --git a/vendor/github.com/cilium/ebpf/internal/sys/fd_trace.go b/vendor/github.com/cilium/ebpf/internal/sys/fd_trace.go deleted file mode 100644 index cd50dd1f642..00000000000 --- a/vendor/github.com/cilium/ebpf/internal/sys/fd_trace.go +++ /dev/null @@ -1,93 +0,0 @@ -package sys - -import ( - "bytes" - "fmt" - "runtime" - "sync" -) - -// OnLeakFD controls tracing [FD] lifetime to detect resources that are not -// closed by Close(). -// -// If fn is not nil, tracing is enabled for all FDs created going forward. fn is -// invoked for all FDs that are closed by the garbage collector instead of an -// explicit Close() by a caller. Calling OnLeakFD twice with a non-nil fn -// (without disabling tracing in the meantime) will cause a panic. -// -// If fn is nil, tracing will be disabled. Any FDs that have not been closed are -// considered to be leaked, fn will be invoked for them, and the process will be -// terminated. -// -// fn will be invoked at most once for every unique sys.FD allocation since a -// runtime.Frames can only be unwound once. -func OnLeakFD(fn func(*runtime.Frames)) { - // Enable leak tracing if new fn is provided. - if fn != nil { - if onLeakFD != nil { - panic("OnLeakFD called twice with non-nil fn") - } - - onLeakFD = fn - return - } - - // fn is nil past this point. - - if onLeakFD == nil { - return - } - - // Call onLeakFD for all open fds. - if fs := flushFrames(); len(fs) != 0 { - for _, f := range fs { - onLeakFD(f) - } - } - - onLeakFD = nil -} - -var onLeakFD func(*runtime.Frames) - -// fds is a registry of all file descriptors wrapped into sys.fds that were -// created while an fd tracer was active. -var fds sync.Map // map[int]*runtime.Frames - -// flushFrames removes all elements from fds and returns them as a slice. This -// deals with the fact that a runtime.Frames can only be unwound once using -// Next(). -func flushFrames() []*runtime.Frames { - var frames []*runtime.Frames - fds.Range(func(key, value any) bool { - frames = append(frames, value.(*runtime.Frames)) - fds.Delete(key) - return true - }) - return frames -} - -func callersFrames() *runtime.Frames { - c := make([]uintptr, 32) - - // Skip runtime.Callers and this function. - i := runtime.Callers(2, c) - if i == 0 { - return nil - } - - return runtime.CallersFrames(c) -} - -// FormatFrames formats a runtime.Frames as a human-readable string. -func FormatFrames(fs *runtime.Frames) string { - var b bytes.Buffer - for { - f, more := fs.Next() - b.WriteString(fmt.Sprintf("\t%s+%#x\n\t\t%s:%d\n", f.Function, f.PC-f.Entry, f.File, f.Line)) - if !more { - break - } - } - return b.String() -} diff --git a/vendor/github.com/cilium/ebpf/internal/sys/mapflags_string.go b/vendor/github.com/cilium/ebpf/internal/sys/mapflags_string.go deleted file mode 100644 index d9fe217222b..00000000000 --- a/vendor/github.com/cilium/ebpf/internal/sys/mapflags_string.go +++ /dev/null @@ -1,53 +0,0 @@ -// Code generated by "stringer -type MapFlags"; DO NOT EDIT. - -package sys - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[BPF_F_NO_PREALLOC-1] - _ = x[BPF_F_NO_COMMON_LRU-2] - _ = x[BPF_F_NUMA_NODE-4] - _ = x[BPF_F_RDONLY-8] - _ = x[BPF_F_WRONLY-16] - _ = x[BPF_F_STACK_BUILD_ID-32] - _ = x[BPF_F_ZERO_SEED-64] - _ = x[BPF_F_RDONLY_PROG-128] - _ = x[BPF_F_WRONLY_PROG-256] - _ = x[BPF_F_CLONE-512] - _ = x[BPF_F_MMAPABLE-1024] - _ = x[BPF_F_PRESERVE_ELEMS-2048] - _ = x[BPF_F_INNER_MAP-4096] - _ = x[BPF_F_LINK-8192] - _ = x[BPF_F_PATH_FD-16384] -} - -const _MapFlags_name = "BPF_F_NO_PREALLOCBPF_F_NO_COMMON_LRUBPF_F_NUMA_NODEBPF_F_RDONLYBPF_F_WRONLYBPF_F_STACK_BUILD_IDBPF_F_ZERO_SEEDBPF_F_RDONLY_PROGBPF_F_WRONLY_PROGBPF_F_CLONEBPF_F_MMAPABLEBPF_F_PRESERVE_ELEMSBPF_F_INNER_MAPBPF_F_LINKBPF_F_PATH_FD" - -var _MapFlags_map = map[MapFlags]string{ - 1: _MapFlags_name[0:17], - 2: _MapFlags_name[17:36], - 4: _MapFlags_name[36:51], - 8: _MapFlags_name[51:63], - 16: _MapFlags_name[63:75], - 32: _MapFlags_name[75:95], - 64: _MapFlags_name[95:110], - 128: _MapFlags_name[110:127], - 256: _MapFlags_name[127:144], - 512: _MapFlags_name[144:155], - 1024: _MapFlags_name[155:169], - 2048: _MapFlags_name[169:189], - 4096: _MapFlags_name[189:204], - 8192: _MapFlags_name[204:214], - 16384: _MapFlags_name[214:227], -} - -func (i MapFlags) String() string { - if str, ok := _MapFlags_map[i]; ok { - return str - } - return "MapFlags(" + strconv.FormatInt(int64(i), 10) + ")" -} diff --git a/vendor/github.com/cilium/ebpf/internal/pinning.go b/vendor/github.com/cilium/ebpf/internal/sys/pinning.go similarity index 77% rename from vendor/github.com/cilium/ebpf/internal/pinning.go rename to vendor/github.com/cilium/ebpf/internal/sys/pinning.go index 01d892f9344..9a4c6c7a153 100644 --- a/vendor/github.com/cilium/ebpf/internal/pinning.go +++ b/vendor/github.com/cilium/ebpf/internal/sys/pinning.go @@ -1,4 +1,4 @@ -package internal +package sys import ( "errors" @@ -7,11 +7,11 @@ import ( "path/filepath" "runtime" - "github.com/cilium/ebpf/internal/sys" + "github.com/cilium/ebpf/internal/linux" "github.com/cilium/ebpf/internal/unix" ) -func Pin(currentPath, newPath string, fd *sys.FD) error { +func Pin(currentPath, newPath string, fd *FD) error { if newPath == "" { return errors.New("given pinning path cannot be empty") } @@ -19,7 +19,7 @@ func Pin(currentPath, newPath string, fd *sys.FD) error { return nil } - fsType, err := FSType(filepath.Dir(newPath)) + fsType, err := linux.FSType(filepath.Dir(newPath)) if err != nil { return err } @@ -30,8 +30,8 @@ func Pin(currentPath, newPath string, fd *sys.FD) error { defer runtime.KeepAlive(fd) if currentPath == "" { - return sys.ObjPin(&sys.ObjPinAttr{ - Pathname: sys.NewStringPointer(newPath), + return ObjPin(&ObjPinAttr{ + Pathname: NewStringPointer(newPath), BpfFd: fd.Uint(), }) } @@ -47,8 +47,8 @@ func Pin(currentPath, newPath string, fd *sys.FD) error { return fmt.Errorf("unable to move pinned object to new path %v: %w", newPath, err) } // Internal state not in sync with the file system so let's fix it. - return sys.ObjPin(&sys.ObjPinAttr{ - Pathname: sys.NewStringPointer(newPath), + return ObjPin(&ObjPinAttr{ + Pathname: NewStringPointer(newPath), BpfFd: fd.Uint(), }) } diff --git a/vendor/github.com/cilium/ebpf/internal/sys/syscall.go b/vendor/github.com/cilium/ebpf/internal/sys/syscall.go index f6b6e934580..e37f4cf6710 100644 --- a/vendor/github.com/cilium/ebpf/internal/sys/syscall.go +++ b/vendor/github.com/cilium/ebpf/internal/sys/syscall.go @@ -133,12 +133,12 @@ func ObjInfo(fd *FD, info Info) error { // BPFObjName is a null-terminated string made up of // 'A-Za-z0-9_' characters. -type ObjName [unix.BPF_OBJ_NAME_LEN]byte +type ObjName [BPF_OBJ_NAME_LEN]byte // NewObjName truncates the result if it is too long. func NewObjName(name string) ObjName { var result ObjName - copy(result[:unix.BPF_OBJ_NAME_LEN-1], name) + copy(result[:BPF_OBJ_NAME_LEN-1], name) return result } @@ -160,29 +160,6 @@ type BTFID uint32 // TypeID identifies a type in a BTF blob. type TypeID uint32 -// MapFlags control map behaviour. -type MapFlags uint32 - -//go:generate go run golang.org/x/tools/cmd/stringer@latest -type MapFlags - -const ( - BPF_F_NO_PREALLOC MapFlags = 1 << iota - BPF_F_NO_COMMON_LRU - BPF_F_NUMA_NODE - BPF_F_RDONLY - BPF_F_WRONLY - BPF_F_STACK_BUILD_ID - BPF_F_ZERO_SEED - BPF_F_RDONLY_PROG - BPF_F_WRONLY_PROG - BPF_F_CLONE - BPF_F_MMAPABLE - BPF_F_PRESERVE_ELEMS - BPF_F_INNER_MAP - BPF_F_LINK - BPF_F_PATH_FD -) - // Flags used by bpf_mprog. const ( BPF_F_REPLACE = 1 << (iota + 2) @@ -192,6 +169,16 @@ const ( BPF_F_LINK_MPROG = 1 << 13 // aka BPF_F_LINK ) +// Flags used by BPF_PROG_LOAD. +const ( + BPF_F_SLEEPABLE = 1 << 4 + BPF_F_XDP_HAS_FRAGS = 1 << 5 + BPF_F_XDP_DEV_BOUND_ONLY = 1 << 6 +) + +const BPF_TAG_SIZE = 8 +const BPF_OBJ_NAME_LEN = 16 + // wrappedErrno wraps syscall.Errno to prevent direct comparisons with // syscall.E* or unix.E* constants. // diff --git a/vendor/github.com/cilium/ebpf/internal/sys/types.go b/vendor/github.com/cilium/ebpf/internal/sys/types.go index 70e754de71d..d46164ae8eb 100644 --- a/vendor/github.com/cilium/ebpf/internal/sys/types.go +++ b/vendor/github.com/cilium/ebpf/internal/sys/types.go @@ -6,6 +6,170 @@ import ( "unsafe" ) +const ( + BPF_ADJ_ROOM_ENCAP_L2_MASK = 255 + BPF_ADJ_ROOM_ENCAP_L2_SHIFT = 56 + BPF_ANY = 0 + BPF_CSUM_LEVEL_DEC = 2 + BPF_CSUM_LEVEL_INC = 1 + BPF_CSUM_LEVEL_QUERY = 0 + BPF_CSUM_LEVEL_RESET = 3 + BPF_EXIST = 2 + BPF_FIB_LKUP_RET_BLACKHOLE = 1 + BPF_FIB_LKUP_RET_FRAG_NEEDED = 8 + BPF_FIB_LKUP_RET_FWD_DISABLED = 5 + BPF_FIB_LKUP_RET_NOT_FWDED = 4 + BPF_FIB_LKUP_RET_NO_NEIGH = 7 + BPF_FIB_LKUP_RET_NO_SRC_ADDR = 9 + BPF_FIB_LKUP_RET_PROHIBIT = 3 + BPF_FIB_LKUP_RET_SUCCESS = 0 + BPF_FIB_LKUP_RET_UNREACHABLE = 2 + BPF_FIB_LKUP_RET_UNSUPP_LWT = 6 + BPF_FIB_LOOKUP_DIRECT = 1 + BPF_FIB_LOOKUP_OUTPUT = 2 + BPF_FIB_LOOKUP_SKIP_NEIGH = 4 + BPF_FIB_LOOKUP_SRC = 16 + BPF_FIB_LOOKUP_TBID = 8 + BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG = 1 + BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP = 4 + BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL = 2 + BPF_F_ADJ_ROOM_DECAP_L3_IPV4 = 128 + BPF_F_ADJ_ROOM_DECAP_L3_IPV6 = 256 + BPF_F_ADJ_ROOM_ENCAP_L2_ETH = 64 + BPF_F_ADJ_ROOM_ENCAP_L3_IPV4 = 2 + BPF_F_ADJ_ROOM_ENCAP_L3_IPV6 = 4 + BPF_F_ADJ_ROOM_ENCAP_L4_GRE = 8 + BPF_F_ADJ_ROOM_ENCAP_L4_UDP = 16 + BPF_F_ADJ_ROOM_FIXED_GSO = 1 + BPF_F_ADJ_ROOM_NO_CSUM_RESET = 32 + BPF_F_BPRM_SECUREEXEC = 1 + BPF_F_BROADCAST = 8 + BPF_F_CLONE = 512 + BPF_F_CTXLEN_MASK = 4503595332403200 + BPF_F_CURRENT_CPU = 4294967295 + BPF_F_CURRENT_NETNS = 18446744073709551615 + BPF_F_DONT_FRAGMENT = 4 + BPF_F_EXCLUDE_INGRESS = 16 + BPF_F_FAST_STACK_CMP = 512 + BPF_F_GET_BRANCH_RECORDS_SIZE = 1 + BPF_F_HDR_FIELD_MASK = 15 + BPF_F_INDEX_MASK = 4294967295 + BPF_F_INGRESS = 1 + BPF_F_INNER_MAP = 4096 + BPF_F_INVALIDATE_HASH = 2 + BPF_F_KPROBE_MULTI_RETURN = 1 + BPF_F_LINK = 8192 + BPF_F_LOCK = 4 + BPF_F_MARK_ENFORCE = 64 + BPF_F_MARK_MANGLED_0 = 32 + BPF_F_MMAPABLE = 1024 + BPF_F_NEIGH = 2 + BPF_F_NEXTHOP = 8 + BPF_F_NO_COMMON_LRU = 2 + BPF_F_NO_PREALLOC = 1 + BPF_F_NO_TUNNEL_KEY = 16 + BPF_F_NUMA_NODE = 4 + BPF_F_PATH_FD = 16384 + BPF_F_PEER = 4 + BPF_F_PRESERVE_ELEMS = 2048 + BPF_F_PSEUDO_HDR = 16 + BPF_F_RDONLY = 8 + BPF_F_RDONLY_PROG = 128 + BPF_F_RECOMPUTE_CSUM = 1 + BPF_F_REUSE_STACKID = 1024 + BPF_F_SEQ_NUMBER = 8 + BPF_F_SKIP_FIELD_MASK = 255 + BPF_F_STACK_BUILD_ID = 32 + BPF_F_SYSCTL_BASE_NAME = 1 + BPF_F_TIMER_ABS = 1 + BPF_F_TIMER_CPU_PIN = 2 + BPF_F_TUNINFO_FLAGS = 16 + BPF_F_TUNINFO_IPV6 = 1 + BPF_F_UPROBE_MULTI_RETURN = 1 + BPF_F_USER_BUILD_ID = 2048 + BPF_F_USER_STACK = 256 + BPF_F_WRONLY = 16 + BPF_F_WRONLY_PROG = 256 + BPF_F_ZERO_CSUM_TX = 2 + BPF_F_ZERO_SEED = 64 + BPF_LOAD_HDR_OPT_TCP_SYN = 1 + BPF_LOCAL_STORAGE_GET_F_CREATE = 1 + BPF_MAX_LOOPS = 8388608 + BPF_MAX_TRAMP_LINKS = 38 + BPF_NOEXIST = 1 + BPF_RB_AVAIL_DATA = 0 + BPF_RB_CONS_POS = 2 + BPF_RB_FORCE_WAKEUP = 2 + BPF_RB_NO_WAKEUP = 1 + BPF_RB_PROD_POS = 3 + BPF_RB_RING_SIZE = 1 + BPF_REG_0 = 0 + BPF_REG_1 = 1 + BPF_REG_10 = 10 + BPF_REG_2 = 2 + BPF_REG_3 = 3 + BPF_REG_4 = 4 + BPF_REG_5 = 5 + BPF_REG_6 = 6 + BPF_REG_7 = 7 + BPF_REG_8 = 8 + BPF_REG_9 = 9 + BPF_RINGBUF_BUSY_BIT = 2147483648 + BPF_RINGBUF_DISCARD_BIT = 1073741824 + BPF_RINGBUF_HDR_SZ = 8 + BPF_SKB_TSTAMP_DELIVERY_MONO = 1 + BPF_SKB_TSTAMP_UNSPEC = 0 + BPF_SK_LOOKUP_F_NO_REUSEPORT = 2 + BPF_SK_LOOKUP_F_REPLACE = 1 + BPF_SK_STORAGE_GET_F_CREATE = 1 + BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB = 4 + BPF_SOCK_OPS_ALL_CB_FLAGS = 127 + BPF_SOCK_OPS_BASE_RTT = 7 + BPF_SOCK_OPS_HDR_OPT_LEN_CB = 14 + BPF_SOCK_OPS_NEEDS_ECN = 6 + BPF_SOCK_OPS_PARSE_ALL_HDR_OPT_CB_FLAG = 16 + BPF_SOCK_OPS_PARSE_HDR_OPT_CB = 13 + BPF_SOCK_OPS_PARSE_UNKNOWN_HDR_OPT_CB_FLAG = 32 + BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB = 5 + BPF_SOCK_OPS_RETRANS_CB = 9 + BPF_SOCK_OPS_RETRANS_CB_FLAG = 2 + BPF_SOCK_OPS_RTO_CB = 8 + BPF_SOCK_OPS_RTO_CB_FLAG = 1 + BPF_SOCK_OPS_RTT_CB = 12 + BPF_SOCK_OPS_RTT_CB_FLAG = 8 + BPF_SOCK_OPS_RWND_INIT = 2 + BPF_SOCK_OPS_STATE_CB = 10 + BPF_SOCK_OPS_STATE_CB_FLAG = 4 + BPF_SOCK_OPS_TCP_CONNECT_CB = 3 + BPF_SOCK_OPS_TCP_LISTEN_CB = 11 + BPF_SOCK_OPS_TIMEOUT_INIT = 1 + BPF_SOCK_OPS_VOID = 0 + BPF_SOCK_OPS_WRITE_HDR_OPT_CB = 15 + BPF_SOCK_OPS_WRITE_HDR_OPT_CB_FLAG = 64 + BPF_STRUCT_OPS_TYPE_bpf_dummy_ops = 0 + BPF_STRUCT_OPS_TYPE_tcp_congestion_ops = 1 + BPF_TASK_ITER_ALL_PROCS = 0 + BPF_TASK_ITER_ALL_THREADS = 1 + BPF_TASK_ITER_PROC_THREADS = 2 + BPF_TCP_BOUND_INACTIVE = 13 + BPF_TCP_CLOSE = 7 + BPF_TCP_CLOSE_WAIT = 8 + BPF_TCP_CLOSING = 11 + BPF_TCP_ESTABLISHED = 1 + BPF_TCP_FIN_WAIT1 = 4 + BPF_TCP_FIN_WAIT2 = 5 + BPF_TCP_LAST_ACK = 9 + BPF_TCP_LISTEN = 10 + BPF_TCP_MAX_STATES = 14 + BPF_TCP_NEW_SYN_RECV = 12 + BPF_TCP_SYN_RECV = 3 + BPF_TCP_SYN_SENT = 2 + BPF_TCP_TIME_WAIT = 6 + BPF_WRITE_HDR_TCP_CURRENT_MSS = 1 + BPF_WRITE_HDR_TCP_SYNACK_COOKIE = 2 + BPF_XFRM_STATE_OPTS_SZ = 36 +) + type AdjRoomMode uint32 const ( @@ -537,7 +701,7 @@ type MapInfo struct { KeySize uint32 ValueSize uint32 MaxEntries uint32 - MapFlags MapFlags + MapFlags uint32 Name ObjName Ifindex uint32 BtfVmlinuxValueTypeId TypeID @@ -886,7 +1050,7 @@ type MapCreateAttr struct { KeySize uint32 ValueSize uint32 MaxEntries uint32 - MapFlags MapFlags + MapFlags uint32 InnerMapFd uint32 NumaNode uint32 MapName ObjName diff --git a/vendor/github.com/cilium/ebpf/internal/testutils/fdtrace/fd_trace.go b/vendor/github.com/cilium/ebpf/internal/testutils/fdtrace/fd_trace.go new file mode 100644 index 00000000000..562df2cc0c2 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/internal/testutils/fdtrace/fd_trace.go @@ -0,0 +1,103 @@ +package fdtrace + +import ( + "bytes" + "fmt" + "os" + "runtime" + "sync" + "sync/atomic" +) + +// foundLeak is atomic since the GC may collect objects in parallel. +var foundLeak atomic.Bool + +func onLeakFD(fs *runtime.Frames) { + foundLeak.Store(true) + fmt.Fprintln(os.Stderr, "leaked fd created at:") + fmt.Fprintln(os.Stderr, formatFrames(fs)) +} + +// fds is a registry of all file descriptors wrapped into sys.fds that were +// created while an fd tracer was active. +var fds *sync.Map // map[int]*runtime.Frames + +// TraceFD associates raw with the current execution stack. +// +// skip controls how many entries of the stack the function should skip. +func TraceFD(raw int, skip int) { + if fds == nil { + return + } + + // Attempt to store the caller's stack for the given fd value. + // Panic if fds contains an existing stack for the fd. + old, exist := fds.LoadOrStore(raw, callersFrames(skip)) + if exist { + f := old.(*runtime.Frames) + panic(fmt.Sprintf("found existing stack for fd %d:\n%s", raw, formatFrames(f))) + } +} + +// ForgetFD removes any existing association for raw. +func ForgetFD(raw int) { + if fds != nil { + fds.Delete(raw) + } +} + +// LeakFD indicates that raw was leaked. +// +// Calling the function with a value that was not passed to [TraceFD] before +// is undefined. +func LeakFD(raw int) { + if fds == nil { + return + } + + // Invoke the fd leak callback. Calls LoadAndDelete to guarantee the callback + // is invoked at most once for one sys.FD allocation, runtime.Frames can only + // be unwound once. + f, ok := fds.LoadAndDelete(raw) + if ok { + onLeakFD(f.(*runtime.Frames)) + } +} + +// flushFrames removes all elements from fds and returns them as a slice. This +// deals with the fact that a runtime.Frames can only be unwound once using +// Next(). +func flushFrames() []*runtime.Frames { + var frames []*runtime.Frames + fds.Range(func(key, value any) bool { + frames = append(frames, value.(*runtime.Frames)) + fds.Delete(key) + return true + }) + return frames +} + +func callersFrames(skip int) *runtime.Frames { + c := make([]uintptr, 32) + + // Skip runtime.Callers and this function. + i := runtime.Callers(skip+2, c) + if i == 0 { + return nil + } + + return runtime.CallersFrames(c) +} + +// formatFrames formats a runtime.Frames as a human-readable string. +func formatFrames(fs *runtime.Frames) string { + var b bytes.Buffer + for { + f, more := fs.Next() + b.WriteString(fmt.Sprintf("\t%s+%#x\n\t\t%s:%d\n", f.Function, f.PC-f.Entry, f.File, f.Line)) + if !more { + break + } + } + return b.String() +} diff --git a/vendor/github.com/cilium/ebpf/internal/testutils/fdtrace/main.go b/vendor/github.com/cilium/ebpf/internal/testutils/fdtrace/main.go new file mode 100644 index 00000000000..c1f7b42d91d --- /dev/null +++ b/vendor/github.com/cilium/ebpf/internal/testutils/fdtrace/main.go @@ -0,0 +1,31 @@ +package fdtrace + +import ( + "os" + "sync" +) + +type testingM interface { + Run() int +} + +// TestMain runs m with fd tracing enabled. +// +// The function calls [os.Exit] and does not return. +func TestMain(m testingM) { + fds = new(sync.Map) + + ret := m.Run() + + if fs := flushFrames(); len(fs) != 0 { + for _, f := range fs { + onLeakFD(f) + } + } + + if foundLeak.Load() { + ret = 99 + } + + os.Exit(ret) +} diff --git a/vendor/github.com/cilium/ebpf/internal/tracefs/kprobe.go b/vendor/github.com/cilium/ebpf/internal/tracefs/kprobe.go index 897740fec0c..800d352fd3a 100644 --- a/vendor/github.com/cilium/ebpf/internal/tracefs/kprobe.go +++ b/vendor/github.com/cilium/ebpf/internal/tracefs/kprobe.go @@ -12,6 +12,7 @@ import ( "syscall" "github.com/cilium/ebpf/internal" + "github.com/cilium/ebpf/internal/linux" "github.com/cilium/ebpf/internal/unix" ) @@ -121,7 +122,7 @@ var getTracefsPath = sync.OnceValues(func() (string, error) { // RHEL/CentOS {"/sys/kernel/debug/tracing", unix.DEBUGFS_MAGIC}, } { - if fsType, err := internal.FSType(p.path); err == nil && fsType == p.fsType { + if fsType, err := linux.FSType(p.path); err == nil && fsType == p.fsType { return p.path, nil } } diff --git a/vendor/github.com/cilium/ebpf/internal/unix/types_linux.go b/vendor/github.com/cilium/ebpf/internal/unix/types_linux.go index d725cfaa394..144e608d1c7 100644 --- a/vendor/github.com/cilium/ebpf/internal/unix/types_linux.go +++ b/vendor/github.com/cilium/ebpf/internal/unix/types_linux.go @@ -81,15 +81,16 @@ const ( SO_DETACH_BPF = linux.SO_DETACH_BPF SOL_SOCKET = linux.SOL_SOCKET SIGPROF = linux.SIGPROF + SIGUSR1 = linux.SIGUSR1 SIG_BLOCK = linux.SIG_BLOCK SIG_UNBLOCK = linux.SIG_UNBLOCK - EM_NONE = linux.EM_NONE - EM_BPF = linux.EM_BPF BPF_FS_MAGIC = linux.BPF_FS_MAGIC TRACEFS_MAGIC = linux.TRACEFS_MAGIC DEBUGFS_MAGIC = linux.DEBUGFS_MAGIC BPF_RB_NO_WAKEUP = linux.BPF_RB_NO_WAKEUP BPF_RB_FORCE_WAKEUP = linux.BPF_RB_FORCE_WAKEUP + AF_UNSPEC = linux.AF_UNSPEC + IFF_UP = linux.IFF_UP ) type Statfs_t = linux.Statfs_t diff --git a/vendor/github.com/cilium/ebpf/internal/unix/types_other.go b/vendor/github.com/cilium/ebpf/internal/unix/types_other.go index 3ff8962716a..06cc3a09663 100644 --- a/vendor/github.com/cilium/ebpf/internal/unix/types_other.go +++ b/vendor/github.com/cilium/ebpf/internal/unix/types_other.go @@ -84,16 +84,17 @@ const ( SO_DETACH_BPF SOL_SOCKET SIGPROF + SIGUSR1 SIG_BLOCK SIG_UNBLOCK - EM_NONE - EM_BPF BPF_FS_MAGIC TRACEFS_MAGIC DEBUGFS_MAGIC BPF_RB_NO_WAKEUP BPF_RB_FORCE_WAKEUP BPF_F_LOCK + AF_UNSPEC + IFF_UP ) type Statfs_t struct { diff --git a/vendor/github.com/cilium/ebpf/internal/version.go b/vendor/github.com/cilium/ebpf/internal/version.go index acd4650af73..a230830b013 100644 --- a/vendor/github.com/cilium/ebpf/internal/version.go +++ b/vendor/github.com/cilium/ebpf/internal/version.go @@ -2,9 +2,6 @@ package internal import ( "fmt" - "sync" - - "github.com/cilium/ebpf/internal/unix" ) const ( @@ -78,30 +75,3 @@ func (v Version) Kernel() uint32 { // each other when overflowing 8 bits. return uint32(uint8(v[0]))<<16 | uint32(uint8(v[1]))<<8 | uint32(uint8(s)) } - -// KernelVersion returns the version of the currently running kernel. -var KernelVersion = sync.OnceValues(func() (Version, error) { - return detectKernelVersion() -}) - -// detectKernelVersion returns the version of the running kernel. -func detectKernelVersion() (Version, error) { - vc, err := vdsoVersion() - if err != nil { - return Version{}, err - } - return NewVersionFromCode(vc), nil -} - -// KernelRelease returns the release string of the running kernel. -// Its format depends on the Linux distribution and corresponds to directory -// names in /lib/modules by convention. Some examples are 5.15.17-1-lts and -// 4.19.0-16-amd64. -func KernelRelease() (string, error) { - var uname unix.Utsname - if err := unix.Uname(&uname); err != nil { - return "", fmt.Errorf("uname failed: %w", err) - } - - return unix.ByteSliceToString(uname.Release[:]), nil -} diff --git a/vendor/github.com/cilium/ebpf/link/kprobe.go b/vendor/github.com/cilium/ebpf/link/kprobe.go index fe3f17c3717..c6fdece078e 100644 --- a/vendor/github.com/cilium/ebpf/link/kprobe.go +++ b/vendor/github.com/cilium/ebpf/link/kprobe.go @@ -177,7 +177,7 @@ func kprobe(symbol string, prog *ebpf.Program, opts *KprobeOptions, ret bool) (* if err == nil { return tp, nil } - if err != nil && !errors.Is(err, ErrNotSupported) { + if !errors.Is(err, ErrNotSupported) { return nil, fmt.Errorf("creating perf_kprobe PMU (arch-specific fallback for %q): %w", symbol, err) } diff --git a/vendor/github.com/cilium/ebpf/link/kprobe_multi.go b/vendor/github.com/cilium/ebpf/link/kprobe_multi.go index f7a8291f945..77aa586451c 100644 --- a/vendor/github.com/cilium/ebpf/link/kprobe_multi.go +++ b/vendor/github.com/cilium/ebpf/link/kprobe_multi.go @@ -60,7 +60,7 @@ func KprobeMulti(prog *ebpf.Program, opts KprobeMultiOptions) (Link, error) { // // Requires at least Linux 5.18. func KretprobeMulti(prog *ebpf.Program, opts KprobeMultiOptions) (Link, error) { - return kprobeMulti(prog, opts, unix.BPF_F_KPROBE_MULTI_RETURN) + return kprobeMulti(prog, opts, sys.BPF_F_KPROBE_MULTI_RETURN) } func kprobeMulti(prog *ebpf.Program, opts KprobeMultiOptions, flags uint32) (Link, error) { @@ -126,7 +126,7 @@ type kprobeMultiLink struct { var _ Link = (*kprobeMultiLink)(nil) -func (kml *kprobeMultiLink) Update(prog *ebpf.Program) error { +func (kml *kprobeMultiLink) Update(_ *ebpf.Program) error { return fmt.Errorf("update kprobe_multi: %w", ErrNotSupported) } diff --git a/vendor/github.com/cilium/ebpf/link/link.go b/vendor/github.com/cilium/ebpf/link/link.go index 9c34616c9a9..eef834a812d 100644 --- a/vendor/github.com/cilium/ebpf/link/link.go +++ b/vendor/github.com/cilium/ebpf/link/link.go @@ -380,7 +380,7 @@ func (l *RawLink) Close() error { // Calling Close on a pinned Link will not break the link // until the pin is removed. func (l *RawLink) Pin(fileName string) error { - if err := internal.Pin(l.pinnedPath, fileName, l.fd); err != nil { + if err := sys.Pin(l.pinnedPath, fileName, l.fd); err != nil { return err } l.pinnedPath = fileName @@ -389,7 +389,7 @@ func (l *RawLink) Pin(fileName string) error { // Unpin implements the Link interface. func (l *RawLink) Unpin() error { - if err := internal.Unpin(l.pinnedPath); err != nil { + if err := sys.Unpin(l.pinnedPath); err != nil { return err } l.pinnedPath = "" diff --git a/vendor/github.com/cilium/ebpf/link/netfilter.go b/vendor/github.com/cilium/ebpf/link/netfilter.go index 34be3908597..9436d11df93 100644 --- a/vendor/github.com/cilium/ebpf/link/netfilter.go +++ b/vendor/github.com/cilium/ebpf/link/netfilter.go @@ -63,7 +63,7 @@ func AttachNetfilter(opts NetfilterOptions) (Link, error) { return &netfilterLink{RawLink{fd, ""}}, nil } -func (*netfilterLink) Update(new *ebpf.Program) error { +func (*netfilterLink) Update(_ *ebpf.Program) error { return fmt.Errorf("netfilter update: %w", ErrNotSupported) } diff --git a/vendor/github.com/cilium/ebpf/link/perf_event.go b/vendor/github.com/cilium/ebpf/link/perf_event.go index 1d8feb58c1c..675ddf91e5e 100644 --- a/vendor/github.com/cilium/ebpf/link/perf_event.go +++ b/vendor/github.com/cilium/ebpf/link/perf_event.go @@ -115,7 +115,7 @@ func (pl *perfEventLink) Close() error { return nil } -func (pl *perfEventLink) Update(prog *ebpf.Program) error { +func (pl *perfEventLink) Update(_ *ebpf.Program) error { return fmt.Errorf("perf event link update: %w", ErrNotSupported) } @@ -185,7 +185,7 @@ func (pi *perfEventIoctl) isLink() {} // // Detaching a program from a perf event is currently not possible, so a // program replacement mechanism cannot be implemented for perf events. -func (pi *perfEventIoctl) Update(prog *ebpf.Program) error { +func (pi *perfEventIoctl) Update(_ *ebpf.Program) error { return fmt.Errorf("perf event ioctl update: %w", ErrNotSupported) } diff --git a/vendor/github.com/cilium/ebpf/link/tracing.go b/vendor/github.com/cilium/ebpf/link/tracing.go index 9e570afc96a..a461007f9f5 100644 --- a/vendor/github.com/cilium/ebpf/link/tracing.go +++ b/vendor/github.com/cilium/ebpf/link/tracing.go @@ -14,7 +14,7 @@ type tracing struct { RawLink } -func (f *tracing) Update(new *ebpf.Program) error { +func (f *tracing) Update(_ *ebpf.Program) error { return fmt.Errorf("tracing update: %w", ErrNotSupported) } diff --git a/vendor/github.com/cilium/ebpf/link/uprobe.go b/vendor/github.com/cilium/ebpf/link/uprobe.go index 194d1d319a7..2cb185243ed 100644 --- a/vendor/github.com/cilium/ebpf/link/uprobe.go +++ b/vendor/github.com/cilium/ebpf/link/uprobe.go @@ -321,7 +321,7 @@ func (ex *Executable) uprobe(symbol string, prog *ebpf.Program, opts *UprobeOpti if err == nil { return tp, nil } - if err != nil && !errors.Is(err, ErrNotSupported) { + if !errors.Is(err, ErrNotSupported) { return nil, fmt.Errorf("creating perf_uprobe PMU: %w", err) } diff --git a/vendor/github.com/cilium/ebpf/link/uprobe_multi.go b/vendor/github.com/cilium/ebpf/link/uprobe_multi.go index aea807b329a..2af270efb86 100644 --- a/vendor/github.com/cilium/ebpf/link/uprobe_multi.go +++ b/vendor/github.com/cilium/ebpf/link/uprobe_multi.go @@ -47,7 +47,7 @@ func (ex *Executable) UretprobeMulti(symbols []string, prog *ebpf.Program, opts // The return probe is not limited for symbols entry, so there's no special // setup for return uprobes (other than the extra flag). The symbols, opts.Offsets // and opts.Addresses arrays follow the same logic as for entry uprobes. - return ex.uprobeMulti(symbols, prog, opts, unix.BPF_F_UPROBE_MULTI_RETURN) + return ex.uprobeMulti(symbols, prog, opts, sys.BPF_F_UPROBE_MULTI_RETURN) } func (ex *Executable) uprobeMulti(symbols []string, prog *ebpf.Program, opts *UprobeMultiOptions, flags uint32) (Link, error) { @@ -168,7 +168,7 @@ type uprobeMultiLink struct { var _ Link = (*uprobeMultiLink)(nil) -func (kml *uprobeMultiLink) Update(prog *ebpf.Program) error { +func (kml *uprobeMultiLink) Update(_ *ebpf.Program) error { return fmt.Errorf("update uprobe_multi: %w", ErrNotSupported) } diff --git a/vendor/github.com/cilium/ebpf/map.go b/vendor/github.com/cilium/ebpf/map.go index 0b62101c3cb..d0ea05d4ac8 100644 --- a/vendor/github.com/cilium/ebpf/map.go +++ b/vendor/github.com/cilium/ebpf/map.go @@ -66,7 +66,7 @@ type MapSpec struct { Pinning PinType // Specify numa node during map creation - // (effective only if unix.BPF_F_NUMA_NODE flag is set, + // (effective only if sys.BPF_F_NUMA_NODE flag is set, // which can be imported from golang.org/x/sys/unix) NumaNode uint32 @@ -222,7 +222,7 @@ func (ms *MapSpec) Compatible(m *Map) error { // BPF_F_RDONLY_PROG is set unconditionally for devmaps. Explicitly allow this // mismatch. - if !((ms.Type == DevMap || ms.Type == DevMapHash) && m.flags^ms.Flags == unix.BPF_F_RDONLY_PROG) && + if !((ms.Type == DevMap || ms.Type == DevMapHash) && m.flags^ms.Flags == sys.BPF_F_RDONLY_PROG) && m.flags != ms.Flags { diffs = append(diffs, fmt.Sprintf("Flags: %d changed to %d", m.flags, ms.Flags)) } @@ -359,7 +359,7 @@ func newMapWithOptions(spec *MapSpec, opts MapOptions) (_ *Map, err error) { return nil, errors.New("inner maps cannot be pinned") } - template, err := spec.InnerMap.createMap(nil, opts) + template, err := spec.InnerMap.createMap(nil) if err != nil { return nil, fmt.Errorf("inner map: %w", err) } @@ -371,7 +371,7 @@ func newMapWithOptions(spec *MapSpec, opts MapOptions) (_ *Map, err error) { innerFd = template.fd } - m, err := spec.createMap(innerFd, opts) + m, err := spec.createMap(innerFd) if err != nil { return nil, err } @@ -389,7 +389,7 @@ func newMapWithOptions(spec *MapSpec, opts MapOptions) (_ *Map, err error) { // createMap validates the spec's properties and creates the map in the kernel // using the given opts. It does not populate or freeze the map. -func (spec *MapSpec) createMap(inner *sys.FD, opts MapOptions) (_ *Map, err error) { +func (spec *MapSpec) createMap(inner *sys.FD) (_ *Map, err error) { closeOnError := func(closer io.Closer) { if err != nil { closer.Close() @@ -416,7 +416,7 @@ func (spec *MapSpec) createMap(inner *sys.FD, opts MapOptions) (_ *Map, err erro KeySize: spec.KeySize, ValueSize: spec.ValueSize, MaxEntries: spec.MaxEntries, - MapFlags: sys.MapFlags(spec.Flags), + MapFlags: spec.Flags, NumaNode: spec.NumaNode, } @@ -474,7 +474,7 @@ func handleMapCreateError(attr sys.MapCreateAttr, spec *MapSpec, err error) erro if errors.Is(err, unix.EINVAL) && spec.Type == UnspecifiedMap { return fmt.Errorf("map create: cannot use type %s", UnspecifiedMap) } - if errors.Is(err, unix.EINVAL) && spec.Flags&unix.BPF_F_NO_PREALLOC > 0 { + if errors.Is(err, unix.EINVAL) && spec.Flags&sys.BPF_F_NO_PREALLOC > 0 { return fmt.Errorf("map create: %w (noPrealloc flag may be incompatible with map type %s)", err, spec.Type) } @@ -484,22 +484,22 @@ func handleMapCreateError(attr sys.MapCreateAttr, spec *MapSpec, err error) erro return fmt.Errorf("map create: %w", haveFeatErr) } } - if spec.Flags&(unix.BPF_F_RDONLY_PROG|unix.BPF_F_WRONLY_PROG) > 0 || spec.Freeze { + if spec.Flags&(sys.BPF_F_RDONLY_PROG|sys.BPF_F_WRONLY_PROG) > 0 || spec.Freeze { if haveFeatErr := haveMapMutabilityModifiers(); haveFeatErr != nil { return fmt.Errorf("map create: %w", haveFeatErr) } } - if spec.Flags&unix.BPF_F_MMAPABLE > 0 { + if spec.Flags&sys.BPF_F_MMAPABLE > 0 { if haveFeatErr := haveMmapableMaps(); haveFeatErr != nil { return fmt.Errorf("map create: %w", haveFeatErr) } } - if spec.Flags&unix.BPF_F_INNER_MAP > 0 { + if spec.Flags&sys.BPF_F_INNER_MAP > 0 { if haveFeatErr := haveInnerMaps(); haveFeatErr != nil { return fmt.Errorf("map create: %w", haveFeatErr) } } - if spec.Flags&unix.BPF_F_NO_PREALLOC > 0 { + if spec.Flags&sys.BPF_F_NO_PREALLOC > 0 { if haveFeatErr := haveNoPreallocMaps(); haveFeatErr != nil { return fmt.Errorf("map create: %w", haveFeatErr) } @@ -604,7 +604,7 @@ func (m *Map) Handle() (*btf.Handle, error) { type MapLookupFlags uint64 // LookupLock look up the value of a spin-locked map. -const LookupLock MapLookupFlags = unix.BPF_F_LOCK +const LookupLock MapLookupFlags = sys.BPF_F_LOCK // Lookup retrieves a value from a Map. // @@ -1349,7 +1349,7 @@ func (m *Map) Clone() (*Map, error) { // This requires bpffs to be mounted above fileName. // See https://docs.cilium.io/en/stable/network/kubernetes/configuration/#mounting-bpffs-with-systemd func (m *Map) Pin(fileName string) error { - if err := internal.Pin(m.pinnedPath, fileName, m.fd); err != nil { + if err := sys.Pin(m.pinnedPath, fileName, m.fd); err != nil { return err } m.pinnedPath = fileName @@ -1362,7 +1362,7 @@ func (m *Map) Pin(fileName string) error { // // Unpinning an unpinned Map returns nil. func (m *Map) Unpin() error { - if err := internal.Unpin(m.pinnedPath); err != nil { + if err := sys.Unpin(m.pinnedPath); err != nil { return err } m.pinnedPath = "" diff --git a/vendor/github.com/cilium/ebpf/prog.go b/vendor/github.com/cilium/ebpf/prog.go index 9bc6325f887..776799e3b7b 100644 --- a/vendor/github.com/cilium/ebpf/prog.go +++ b/vendor/github.com/cilium/ebpf/prog.go @@ -16,6 +16,7 @@ import ( "github.com/cilium/ebpf/btf" "github.com/cilium/ebpf/internal" "github.com/cilium/ebpf/internal/kallsyms" + "github.com/cilium/ebpf/internal/linux" "github.com/cilium/ebpf/internal/sys" "github.com/cilium/ebpf/internal/sysenc" "github.com/cilium/ebpf/internal/unix" @@ -46,10 +47,6 @@ const ( outputPad = 256 + 2 ) -// Deprecated: the correct log size is now detected automatically and this -// constant is unused. -const DefaultVerifierLogSize = 64 * 1024 - // minVerifierLogSize is the default number of bytes allocated for the // verifier log. const minVerifierLogSize = 64 * 1024 @@ -73,10 +70,6 @@ type ProgramOptions struct { // attempt at loading the program. LogLevel LogLevel - // Deprecated: the correct log buffer size is determined automatically - // and this field is ignored. - LogSize int - // Disables the verifier log completely, regardless of other options. LogDisabled bool @@ -261,7 +254,7 @@ func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions) (*Program, er // Overwrite Kprobe program version if set to zero or the magic version constant. kv := spec.KernelVersion if spec.Type == Kprobe && (kv == 0 || kv == internal.MagicKernelVersion) { - v, err := internal.KernelVersion() + v, err := linux.KernelVersion() if err != nil { return nil, fmt.Errorf("detecting kernel version: %w", err) } @@ -598,7 +591,7 @@ func (p *Program) Clone() (*Program, error) { // This requires bpffs to be mounted above fileName. // See https://docs.cilium.io/en/stable/network/kubernetes/configuration/#mounting-bpffs-with-systemd func (p *Program) Pin(fileName string) error { - if err := internal.Pin(p.pinnedPath, fileName, p.fd); err != nil { + if err := sys.Pin(p.pinnedPath, fileName, p.fd); err != nil { return err } p.pinnedPath = fileName @@ -611,7 +604,7 @@ func (p *Program) Pin(fileName string) error { // // Unpinning an unpinned Program returns nil. func (p *Program) Unpin() error { - if err := internal.Unpin(p.pinnedPath); err != nil { + if err := sys.Unpin(p.pinnedPath); err != nil { return err } p.pinnedPath = "" diff --git a/vendor/github.com/cilium/ebpf/syscalls.go b/vendor/github.com/cilium/ebpf/syscalls.go index 4aef7faebc8..0766e7dd64c 100644 --- a/vendor/github.com/cilium/ebpf/syscalls.go +++ b/vendor/github.com/cilium/ebpf/syscalls.go @@ -86,7 +86,7 @@ var haveMapMutabilityModifiers = internal.NewFeatureTest("read- and write-only m KeySize: 4, ValueSize: 4, MaxEntries: 1, - MapFlags: unix.BPF_F_RDONLY_PROG, + MapFlags: sys.BPF_F_RDONLY_PROG, }) if err != nil { return internal.ErrNotSupported @@ -102,7 +102,7 @@ var haveMmapableMaps = internal.NewFeatureTest("mmapable maps", "5.5", func() er KeySize: 4, ValueSize: 4, MaxEntries: 1, - MapFlags: unix.BPF_F_MMAPABLE, + MapFlags: sys.BPF_F_MMAPABLE, }) if err != nil { return internal.ErrNotSupported @@ -118,7 +118,7 @@ var haveInnerMaps = internal.NewFeatureTest("inner maps", "5.10", func() error { KeySize: 4, ValueSize: 4, MaxEntries: 1, - MapFlags: unix.BPF_F_INNER_MAP, + MapFlags: sys.BPF_F_INNER_MAP, }) if err != nil { @@ -135,7 +135,7 @@ var haveNoPreallocMaps = internal.NewFeatureTest("prealloc maps", "4.6", func() KeySize: 4, ValueSize: 4, MaxEntries: 1, - MapFlags: unix.BPF_F_NO_PREALLOC, + MapFlags: sys.BPF_F_NO_PREALLOC, }) if err != nil { diff --git a/vendor/github.com/cilium/ebpf/types.go b/vendor/github.com/cilium/ebpf/types.go index 542c2397cab..b272b35b882 100644 --- a/vendor/github.com/cilium/ebpf/types.go +++ b/vendor/github.com/cilium/ebpf/types.go @@ -2,7 +2,6 @@ package ebpf import ( "github.com/cilium/ebpf/internal/sys" - "github.com/cilium/ebpf/internal/unix" ) //go:generate go run golang.org/x/tools/cmd/stringer@latest -output types_string.go -type=MapType,ProgramType,PinType @@ -263,10 +262,10 @@ func (lpo *LoadPinOptions) Marshal() uint32 { flags := lpo.Flags if lpo.ReadOnly { - flags |= unix.BPF_F_RDONLY + flags |= sys.BPF_F_RDONLY } if lpo.WriteOnly { - flags |= unix.BPF_F_WRONLY + flags |= sys.BPF_F_WRONLY } return flags } diff --git a/vendor/modules.txt b/vendor/modules.txt index c4d051123ef..fb25f054950 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -198,7 +198,7 @@ github.com/cilium/cilium/pkg/u8proto github.com/cilium/cilium/pkg/version github.com/cilium/cilium/pkg/versioncheck github.com/cilium/cilium/pkg/wireguard/types -# github.com/cilium/ebpf v0.16.0 +# github.com/cilium/ebpf v0.16.0 => github.com/olsajiri/ebpf v0.9.1-0.20240829231511-6b7605ff8747 ## explicit; go 1.21 github.com/cilium/ebpf github.com/cilium/ebpf/asm @@ -208,8 +208,10 @@ github.com/cilium/ebpf/internal github.com/cilium/ebpf/internal/epoll github.com/cilium/ebpf/internal/kallsyms github.com/cilium/ebpf/internal/kconfig +github.com/cilium/ebpf/internal/linux github.com/cilium/ebpf/internal/sys github.com/cilium/ebpf/internal/sysenc +github.com/cilium/ebpf/internal/testutils/fdtrace github.com/cilium/ebpf/internal/tracefs github.com/cilium/ebpf/internal/unix github.com/cilium/ebpf/link @@ -1774,6 +1776,7 @@ sigs.k8s.io/structured-merge-diff/v4/value ## explicit; go 1.12 sigs.k8s.io/yaml sigs.k8s.io/yaml/goyaml.v2 +# github.com/cilium/ebpf => github.com/olsajiri/ebpf v0.9.1-0.20240829231511-6b7605ff8747 # github.com/cilium/tetragon/api => ./api # github.com/cilium/tetragon/pkg/k8s => ./pkg/k8s # go.universe.tf/metallb => github.com/cilium/metallb v0.1.1-0.20220829170633-5d7dfb1129f7 From 6307bea59512b7afb02e5a4a06cc53974948f5be Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 30 Aug 2024 07:09:07 +0000 Subject: [PATCH 24/35] cilium fix Signed-off-by: Jiri Olsa --- .../cilium/cilium/pkg/bpf/collection.go | 34 ------------------- 1 file changed, 34 deletions(-) diff --git a/vendor/github.com/cilium/cilium/pkg/bpf/collection.go b/vendor/github.com/cilium/cilium/pkg/bpf/collection.go index 55450a515e8..e139d593428 100644 --- a/vendor/github.com/cilium/cilium/pkg/bpf/collection.go +++ b/vendor/github.com/cilium/cilium/pkg/bpf/collection.go @@ -259,46 +259,12 @@ func LoadCollection(spec *ebpf.CollectionSpec, opts ebpf.CollectionOptions) (*eb return nil, fmt.Errorf("inlining global data: %w", err) } - // Set initial size of verifier log buffer. - // - // Up until kernel 5.1, the maximum log size is (2^24)-1. In 5.2, this was - // increased to (2^30)-1 by 7a9f5c65abcc ("bpf: increase verifier log limit"). - // - // The default value of (2^22)-1 was chosen to be large enough to fit the log - // of most Cilium programs, while falling just within the 5.1 maximum size in - // one of the steps of the multiplication loop below. Without the -1, it would - // overshoot the cap to 2^24, making e.g. verifier tests unable to load the - // program if the previous size (2^22) was too small to fit the log. - if opts.Programs.LogSize == 0 { - opts.Programs.LogSize = 4_194_303 - } - - attempt := 1 for { coll, err := ebpf.NewCollectionWithOptions(spec, opts) if err == nil { return coll, nil } - // Bump LogSize and retry if there's a truncated VerifierError. - var ve *ebpf.VerifierError - if errors.As(err, &ve) && ve.Truncated { - if attempt >= 5 { - return nil, fmt.Errorf("%d-byte truncated verifier log after %d attempts: %w", opts.Programs.LogSize, attempt, err) - } - - // Retry with non-zero log level to avoid retrying with log disabled. - if opts.Programs.LogLevel == 0 { - opts.Programs.LogLevel = ebpf.LogLevelBranch - } - - opts.Programs.LogSize *= 4 - - attempt++ - - continue - } - // Not a truncated VerifierError. return nil, err } From 859a2b01cd5127547be7e288ad90032ce8266170 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 16 Aug 2024 21:50:56 +0000 Subject: [PATCH 25/35] tetragon: Use strict patern in test ReadAvailFuncs calls With current pattern we can match functions with extra suffix while the expected function is missing, which can happen on current upstream kernel. Signed-off-by: Jiri Olsa --- pkg/sensors/tracing/kprobe_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/sensors/tracing/kprobe_test.go b/pkg/sensors/tracing/kprobe_test.go index 3b9542de014..5c25b9121c3 100644 --- a/pkg/sensors/tracing/kprobe_test.go +++ b/pkg/sensors/tracing/kprobe_test.go @@ -6159,7 +6159,7 @@ func TestLinuxBinprmExtractPath(t *testing.T) { // Test module loading/unloading on Ubuntu func TestTraceKernelModule(t *testing.T) { - _, err := ftrace.ReadAvailFuncs("find_module_sections") + _, err := ftrace.ReadAvailFuncs("^find_module_sections$") if err != nil { t.Skip("Skipping test: could not find find_module_sections") } @@ -6592,7 +6592,7 @@ func trigger(t *testing.T) { } func TestKprobeArgs(t *testing.T) { - _, err := ftrace.ReadAvailFuncs("bpf_fentry_test1") + _, err := ftrace.ReadAvailFuncs("^bpf_fentry_test1$") if err != nil { t.Skip("Skipping test: could not find bpf_fentry_test1") } From 19a56bc528c6abf8fbf2d9aef7d1bec649e65ee0 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 17 Aug 2024 13:28:07 +0000 Subject: [PATCH 26/35] tetragon: Fix debug message in observerLoadInstance Adding missing spaces to the message. Signed-off-by: Jiri Olsa --- pkg/sensors/load.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/sensors/load.go b/pkg/sensors/load.go index 3fd4a7c9e0f..69bdf6105c8 100644 --- a/pkg/sensors/load.go +++ b/pkg/sensors/load.go @@ -307,7 +307,7 @@ func observerLoadInstance(bpfDir string, load *program.Program) error { l.WithFields(logrus.Fields{ "prog": load.Name, "kern_version": version, - }).Debug("observerLoadInstance", load.Name, version) + }).Debugf("observerLoadInstance %s %d", load.Name, version) if load.Type == "tracepoint" { err = loadInstance(bpfDir, load, version, option.Config.Verbosity) if err != nil { From 97dac0e610abad8455581193139e4e0ffce575c1 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 17 Aug 2024 18:05:11 +0000 Subject: [PATCH 27/35] tetragon: Add missing calls to DeleteTracingPolicy in kprobe tests We're missing cleanup in some kprobe tests, so we get leftovers in the tetragon directory, like: time="2024-08-17T18:01:54Z" level=info msg="`gkp-sensor-3-multi_kprobe-string_maps_5` still exists after test" time="2024-08-17T18:01:54Z" level=info msg="`gkp-sensor-3-multi_kprobe-string_maps_6` still exists after test" time="2024-08-17T18:01:54Z" level=info msg="`gkp-sensor-3-multi_kprobe-string_maps_7` still exists after test" Adding missing DeleteTracingPolicy cleanup call. Signed-off-by: Jiri Olsa --- pkg/sensors/tracing/kprobe_test.go | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/pkg/sensors/tracing/kprobe_test.go b/pkg/sensors/tracing/kprobe_test.go index 5c25b9121c3..8a0d5749d41 100644 --- a/pkg/sensors/tracing/kprobe_test.go +++ b/pkg/sensors/tracing/kprobe_test.go @@ -4001,7 +4001,11 @@ func matchBinariesPerfringTest(t *testing.T, operator string, values []string) { } err := sm.Manager.AddTracingPolicy(ctx, &matchBinariesTracingPolicy) - assert.NoError(t, err) + if assert.NoError(t, err) { + t.Cleanup(func() { + sm.Manager.DeleteTracingPolicy(ctx, "match-binaries", "") + }) + } var tailPID, headPID int ops := func() { @@ -4112,7 +4116,11 @@ func TestKprobeMatchBinariesEarlyExec(t *testing.T) { } err = sm.Manager.AddTracingPolicy(ctx, &matchBinariesTracingPolicy) - assert.NoError(t, err) + if assert.NoError(t, err) { + t.Cleanup(func() { + sm.Manager.DeleteTracingPolicy(ctx, "match-binaries", "") + }) + } ops := func() { file.WriteString("trigger!") @@ -4188,7 +4196,11 @@ func TestKprobeMatchBinariesPrefixMatchArgs(t *testing.T) { } err := sm.Manager.AddTracingPolicy(ctx, &matchBinariesTracingPolicy) - assert.NoError(t, err) + if assert.NoError(t, err) { + t.Cleanup(func() { + sm.Manager.DeleteTracingPolicy(ctx, "match-binaries", "") + }) + } var tailEtcPID, tailProcPID, headPID int ops := func() { @@ -6123,7 +6135,11 @@ func TestLinuxBinprmExtractPath(t *testing.T) { } err := sm.Manager.AddTracingPolicy(ctx, &bprmTracingPolicy) - assert.NoError(t, err) + if assert.NoError(t, err) { + t.Cleanup(func() { + sm.Manager.DeleteTracingPolicy(ctx, "bprm-extract-path", "") + }) + } targetCommand := exec.Command("/usr/bin/id") filteredCommand := exec.Command("/usr/bin/uname") From c287d671e5d3f8fee5bea47efea31660a77b1abd Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 30 Aug 2024 07:22:54 +0000 Subject: [PATCH 28/35] tetragon: Disable contents loading in initial map loading Signed-off-by: Jiri Olsa --- pkg/sensors/load.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/sensors/load.go b/pkg/sensors/load.go index 69bdf6105c8..80ff8734801 100644 --- a/pkg/sensors/load.go +++ b/pkg/sensors/load.go @@ -257,6 +257,8 @@ func (s *Sensor) loadMaps(bpfDir string) error { return fmt.Errorf("map '%s' not found from '%s'", m.Name, m.Prog.Name) } + mapSpec.Contents = nil + if max, ok := m.GetMaxEntries(); ok { mapSpec.MaxEntries = max } From a91aaefa9e955969ccebf22bb51cd1efb063a7ea Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 17 Aug 2024 19:42:41 +0000 Subject: [PATCH 29/35] tetragon: Load tail calls directly in execve program Signed-off-by: Jiri Olsa --- bpf/process/bpf_execve_event.c | 16 ++++++++++++---- pkg/sensors/base/base.go | 3 --- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/bpf/process/bpf_execve_event.c b/bpf/process/bpf_execve_event.c index af8e4d46f2b..dee90be22bf 100644 --- a/bpf/process/bpf_execve_event.c +++ b/bpf/process/bpf_execve_event.c @@ -13,14 +13,22 @@ #include "policy_filter.h" +int execve_rate(void *ctx); +int execve_send(void *ctx); + char _license[] __attribute__((section("license"), used)) = "Dual BSD/GPL"; struct { __uint(type, BPF_MAP_TYPE_PROG_ARRAY); __uint(max_entries, 2); __uint(key_size, sizeof(__u32)); - __uint(value_size, sizeof(__u32)); -} execve_calls SEC(".maps"); + __array(values, int(void *)); +} execve_calls SEC(".maps") = { + .values = { + [0] = (void *)&execve_rate, + [1] = (void *)&execve_send, + }, +}; #include "data_event.h" @@ -273,7 +281,7 @@ event_execve(struct trace_event_raw_sched_process_exec *ctx) return 0; } -__attribute__((section("tracepoint/0"), used)) int +__attribute__((section("tracepoint"), used)) int execve_rate(void *ctx) { struct msg_execve_event *msg; @@ -318,7 +326,7 @@ void update_mb_bitset(struct binary *bin) * is to update the pid execve_map entry to reflect the new execve event that * has already been collected, then send it to the perf buffer. */ -__attribute__((section("tracepoint/1"), used)) int +__attribute__((section("tracepoint"), used)) int execve_send(void *ctx) { struct msg_execve_event *event; diff --git a/pkg/sensors/base/base.go b/pkg/sensors/base/base.go index 06f9e135a23..71a93e06cb0 100644 --- a/pkg/sensors/base/base.go +++ b/pkg/sensors/base/base.go @@ -97,9 +97,6 @@ var ( ) func setupPrograms() { - // execve program tail calls details - Execve.SetTailCall("tracepoint", ExecveTailCallsMap) - // exit program function ks, err := ksyms.KernelSymbols() if err == nil { From b6272af8262d3f94a807b368ee87b71f9998f07f Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 19 Aug 2024 13:00:12 +0000 Subject: [PATCH 30/35] tetragon: Load tail calls directly in generickprobe program Signed-off-by: Jiri Olsa --- bpf/process/bpf_generic_kprobe.c | 32 +++++++++++++++++++++------- bpf/process/bpf_generic_retkprobe.c | 20 ++++++++++++----- pkg/sensors/tracing/generickprobe.go | 8 ------- 3 files changed, 39 insertions(+), 21 deletions(-) diff --git a/bpf/process/bpf_generic_kprobe.c b/bpf/process/bpf_generic_kprobe.c index d8743d5d97b..cf9aacb18bf 100644 --- a/bpf/process/bpf_generic_kprobe.c +++ b/bpf/process/bpf_generic_kprobe.c @@ -25,12 +25,28 @@ struct { __type(value, struct msg_generic_kprobe); } process_call_heap SEC(".maps"); +int generic_kprobe_setup_event(void *ctx); +int generic_kprobe_process_event(void *ctx); +int generic_kprobe_process_filter(void *ctx); +int generic_kprobe_filter_arg(void *ctx); +int generic_kprobe_actions(void *ctx); +int generic_kprobe_output(void *ctx); + struct { __uint(type, BPF_MAP_TYPE_PROG_ARRAY); __uint(max_entries, 13); __uint(key_size, sizeof(__u32)); - __uint(value_size, sizeof(__u32)); -} kprobe_calls SEC(".maps"); + __array(values, int(void *)); +} kprobe_calls SEC(".maps") = { + .values = { + [0] = (void *)&generic_kprobe_setup_event, + [1] = (void *)&generic_kprobe_process_event, + [2] = (void *)&generic_kprobe_process_filter, + [3] = (void *)&generic_kprobe_filter_arg, + [4] = (void *)&generic_kprobe_actions, + [5] = (void *)&generic_kprobe_output, + }, +}; struct { __uint(type, BPF_MAP_TYPE_HASH); @@ -115,7 +131,7 @@ generic_kprobe_event(struct pt_regs *ctx) return generic_start_process_filter(ctx, &maps); } -__attribute__((section("kprobe/0"), used)) int +__attribute__((section("kprobe"), used)) int generic_kprobe_setup_event(void *ctx) { return generic_process_event_and_setup( @@ -125,7 +141,7 @@ generic_kprobe_setup_event(void *ctx) (struct bpf_map_def *)data_heap_ptr); } -__attribute__((section("kprobe/1"), used)) int +__attribute__((section("kprobe"), used)) int generic_kprobe_process_event(void *ctx) { return generic_process_event(ctx, @@ -135,7 +151,7 @@ generic_kprobe_process_event(void *ctx) (struct bpf_map_def *)data_heap_ptr); } -__attribute__((section("kprobe/2"), used)) int +__attribute__((section("kprobe"), used)) int generic_kprobe_process_filter(void *ctx) { int ret; @@ -152,7 +168,7 @@ generic_kprobe_process_filter(void *ctx) return PFILTER_REJECT; } -__attribute__((section("kprobe/3"), used)) int +__attribute__((section("kprobe"), used)) int generic_kprobe_filter_arg(void *ctx) { return filter_read_arg(ctx, (struct bpf_map_def *)&process_call_heap, @@ -162,13 +178,13 @@ generic_kprobe_filter_arg(void *ctx) true); } -__attribute__((section("kprobe/4"), used)) int +__attribute__((section("kprobe"), used)) int generic_kprobe_actions(void *ctx) { return generic_actions(ctx, &maps); } -__attribute__((section("kprobe/5"), used)) int +__attribute__((section("kprobe"), used)) int generic_kprobe_output(void *ctx) { return generic_output(ctx, (struct bpf_map_def *)&process_call_heap, MSG_OP_GENERIC_KPROBE); diff --git a/bpf/process/bpf_generic_retkprobe.c b/bpf/process/bpf_generic_retkprobe.c index 924b01a6177..2d65d86b79c 100644 --- a/bpf/process/bpf_generic_retkprobe.c +++ b/bpf/process/bpf_generic_retkprobe.c @@ -24,12 +24,22 @@ struct { __type(value, struct msg_generic_kprobe); } process_call_heap SEC(".maps"); +int generic_retkprobe_filter_arg(struct pt_regs *ctx); +int generic_retkprobe_actions(struct pt_regs *ctx); +int generic_retkprobe_output(struct pt_regs *ctx); + struct { __uint(type, BPF_MAP_TYPE_PROG_ARRAY); __uint(max_entries, 6); __uint(key_size, sizeof(__u32)); - __uint(value_size, sizeof(__u32)); -} retkprobe_calls SEC(".maps"); + __array(values, int(struct pt_regs *)); +} retkprobe_calls SEC(".maps") = { + .values = { + [3] = (void *)&generic_retkprobe_filter_arg, + [4] = (void *)&generic_retkprobe_actions, + [5] = (void *)&generic_retkprobe_output, + }, +}; struct filter_map_value { unsigned char buf[FILTER_SIZE]; @@ -171,7 +181,7 @@ BPF_KRETPROBE(generic_retkprobe_event, unsigned long ret) return 1; } -__attribute__((section("kprobe/3"), used)) int +__attribute__((section("kprobe"), used)) int BPF_KRETPROBE(generic_retkprobe_filter_arg) { return filter_read_arg(ctx, (struct bpf_map_def *)&process_call_heap, @@ -181,13 +191,13 @@ BPF_KRETPROBE(generic_retkprobe_filter_arg) false); } -__attribute__((section("kprobe/4"), used)) int +__attribute__((section("kprobe"), used)) int BPF_KRETPROBE(generic_retkprobe_actions) { return generic_actions(ctx, &maps); } -__attribute__((section("kprobe/5"), used)) int +__attribute__((section("kprobe"), used)) int BPF_KRETPROBE(generic_retkprobe_output) { return generic_output(ctx, (struct bpf_map_def *)&process_call_heap, MSG_OP_GENERIC_KPROBE); diff --git a/pkg/sensors/tracing/generickprobe.go b/pkg/sensors/tracing/generickprobe.go index 6b6ab81782d..eaad6a45849 100644 --- a/pkg/sensors/tracing/generickprobe.go +++ b/pkg/sensors/tracing/generickprobe.go @@ -321,8 +321,6 @@ func createMultiKprobeSensor(policyName string, multiIDs []idtable.EntryID, has tailCalls := program.MapBuilderProgram("kprobe_calls", load) maps = append(maps, tailCalls) - load.SetTailCall("kprobe", tailCalls) - filterMap := program.MapBuilderProgram("filter_map", load) maps = append(maps, filterMap) @@ -414,8 +412,6 @@ func createMultiKprobeSensor(policyName string, multiIDs []idtable.EntryID, has tailCalls := program.MapBuilderSensor("retkprobe_calls", loadret) maps = append(maps, tailCalls) - loadret.SetTailCall("kprobe", tailCalls) - retConfigMap.SetMaxEntries(len(multiRetIDs)) retFilterMap.SetMaxEntries(len(multiRetIDs)) } @@ -906,8 +902,6 @@ func createKprobeSensorFromEntry(kprobeEntry *genericKprobe, tailCalls := program.MapBuilderProgram("kprobe_calls", load) maps = append(maps, tailCalls) - load.SetTailCall("kprobe", tailCalls) - filterMap := program.MapBuilderProgram("filter_map", load) maps = append(maps, filterMap) @@ -991,8 +985,6 @@ func createKprobeSensorFromEntry(kprobeEntry *genericKprobe, tailCalls := program.MapBuilderProgram("retkprobe_calls", loadret) maps = append(maps, tailCalls) - loadret.SetTailCall("kprobe", tailCalls) - filterMap := program.MapBuilderProgram("filter_map", loadret) maps = append(maps, filterMap) From 506cf61b090139467ed5d0020f9687d42c113f34 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 19 Aug 2024 13:04:41 +0000 Subject: [PATCH 31/35] tetragon: Load tail calls directly in generictracepoint program Signed-off-by: Jiri Olsa --- bpf/process/bpf_generic_tracepoint.c | 28 ++++++++++++++++++------ pkg/sensors/tracing/generictracepoint.go | 3 --- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/bpf/process/bpf_generic_tracepoint.c b/bpf/process/bpf_generic_tracepoint.c index 03264540fe7..37707f46b5e 100644 --- a/bpf/process/bpf_generic_tracepoint.c +++ b/bpf/process/bpf_generic_tracepoint.c @@ -17,12 +17,26 @@ #include "pfilter.h" #include "policy_filter.h" +int generic_tracepoint_process_event(void *ctx); +int generic_tracepoint_filter(void *ctx); +int generic_tracepoint_arg(void *ctx); +int generic_tracepoint_actions(void *ctx); +int generic_tracepoint_output(void *ctx); + struct { __uint(type, BPF_MAP_TYPE_PROG_ARRAY); __uint(max_entries, 13); __uint(key_size, sizeof(__u32)); - __uint(value_size, sizeof(__u32)); -} tp_calls SEC(".maps"); + __array(values, int(void *)); +} tp_calls SEC(".maps") = { + .values = { + [1] = (void *)&generic_tracepoint_process_event, + [2] = (void *)&generic_tracepoint_filter, + [3] = (void *)&generic_tracepoint_arg, + [4] = (void *)&generic_tracepoint_actions, + [5] = (void *)&generic_tracepoint_output, + }, +}; struct { __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); @@ -230,7 +244,7 @@ generic_tracepoint_event(struct generic_tracepoint_event_arg *ctx) return 0; } -__attribute__((section("tracepoint/1"), used)) int +__attribute__((section("tracepoint"), used)) int generic_tracepoint_process_event(void *ctx) { return generic_process_event(ctx, (struct bpf_map_def *)&tp_heap, @@ -238,7 +252,7 @@ generic_tracepoint_process_event(void *ctx) (struct bpf_map_def *)&config_map, 0); } -__attribute__((section("tracepoint/2"), used)) int +__attribute__((section("tracepoint"), used)) int generic_tracepoint_filter(void *ctx) { int ret; @@ -255,7 +269,7 @@ generic_tracepoint_filter(void *ctx) return PFILTER_REJECT; } -__attribute__((section("tracepoint/3"), used)) int +__attribute__((section("tracepoint"), used)) int generic_tracepoint_arg(void *ctx) { return filter_read_arg(ctx, (struct bpf_map_def *)&tp_heap, @@ -265,13 +279,13 @@ generic_tracepoint_arg(void *ctx) true); } -__attribute__((section("tracepoint/4"), used)) int +__attribute__((section("tracepoint"), used)) int generic_tracepoint_actions(void *ctx) { return generic_actions(ctx, &maps); } -__attribute__((section("tracepoint/5"), used)) int +__attribute__((section("tracepoint"), used)) int generic_tracepoint_output(void *ctx) { return generic_output(ctx, (struct bpf_map_def *)&tp_heap, MSG_OP_GENERIC_TRACEPOINT); diff --git a/pkg/sensors/tracing/generictracepoint.go b/pkg/sensors/tracing/generictracepoint.go index 53a279af440..03af2902751 100644 --- a/pkg/sensors/tracing/generictracepoint.go +++ b/pkg/sensors/tracing/generictracepoint.go @@ -423,9 +423,6 @@ func createGenericTracepointSensor( tailCalls := program.MapBuilderProgram("tp_calls", prog0) maps = append(maps, tailCalls) - // tracepoint tail calls details - prog0.SetTailCall("tracepoint", tailCalls) - filterMap := program.MapBuilderProgram("filter_map", prog0) maps = append(maps, filterMap) From 3e72eed862fcdf76c65b51a5c178051f291a7572 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 19 Aug 2024 13:09:42 +0000 Subject: [PATCH 32/35] tetragon: Load tail calls directly in genericlsm program Signed-off-by: Jiri Olsa --- bpf/process/bpf_generic_lsm.c | 32 +++++++++++++++++++++++-------- pkg/sensors/tracing/genericlsm.go | 2 -- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/bpf/process/bpf_generic_lsm.c b/bpf/process/bpf_generic_lsm.c index 69c53848e2c..f46acc624d9 100644 --- a/bpf/process/bpf_generic_lsm.c +++ b/bpf/process/bpf_generic_lsm.c @@ -23,12 +23,28 @@ struct { __type(value, struct msg_generic_kprobe); } process_call_heap SEC(".maps"); +int generic_lsm_setup_event(void *ctx); +int generic_lsm_process_event(void *ctx); +int generic_lsm_process_filter(void *ctx); +int generic_lsm_filter_arg(void *ctx); +int generic_lsm_actions(void *ctx); +int generic_lsm_output(void *ctx); + struct { __uint(type, BPF_MAP_TYPE_PROG_ARRAY); __uint(max_entries, 13); __uint(key_size, sizeof(__u32)); - __uint(value_size, sizeof(__u32)); -} lsm_calls SEC(".maps"); + __array(values, int(void *)); +} lsm_calls SEC(".maps") = { + .values = { + [0] = (void *)&generic_lsm_setup_event, + [1] = (void *)&generic_lsm_process_event, + [2] = (void *)&generic_lsm_process_filter, + [3] = (void *)&generic_lsm_filter_arg, + [4] = (void *)&generic_lsm_actions, + [5] = (void *)&generic_lsm_output, + }, +}; struct { __uint(type, BPF_MAP_TYPE_HASH); @@ -97,7 +113,7 @@ generic_lsm_event(struct pt_regs *ctx) return generic_start_process_filter(ctx, &maps); } -__attribute__((section("lsm/0"), used)) int +__attribute__((section("lsm"), used)) int generic_lsm_setup_event(void *ctx) { return generic_process_event_and_setup( @@ -107,7 +123,7 @@ generic_lsm_setup_event(void *ctx) (struct bpf_map_def *)data_heap_ptr); } -__attribute__((section("lsm/1"), used)) int +__attribute__((section("lsm"), used)) int generic_lsm_process_event(void *ctx) { return generic_process_event(ctx, @@ -117,7 +133,7 @@ generic_lsm_process_event(void *ctx) (struct bpf_map_def *)data_heap_ptr); } -__attribute__((section("lsm/2"), used)) int +__attribute__((section("lsm"), used)) int generic_lsm_process_filter(void *ctx) { int ret; @@ -131,7 +147,7 @@ generic_lsm_process_filter(void *ctx) return PFILTER_REJECT; } -__attribute__((section("lsm/3"), used)) int +__attribute__((section("lsm"), used)) int generic_lsm_filter_arg(void *ctx) { return filter_read_arg(ctx, (struct bpf_map_def *)&process_call_heap, @@ -141,7 +157,7 @@ generic_lsm_filter_arg(void *ctx) true); } -__attribute__((section("lsm/4"), used)) int +__attribute__((section("lsm"), used)) int generic_lsm_actions(void *ctx) { generic_actions(ctx, &maps); @@ -150,7 +166,7 @@ generic_lsm_actions(void *ctx) return try_override(ctx); } -__attribute__((section("lsm/5"), used)) int +__attribute__((section("lsm"), used)) int generic_lsm_output(void *ctx) { generic_output(ctx, (struct bpf_map_def *)&process_call_heap, MSG_OP_GENERIC_LSM); diff --git a/pkg/sensors/tracing/genericlsm.go b/pkg/sensors/tracing/genericlsm.go index 7688e427427..394a35f311e 100644 --- a/pkg/sensors/tracing/genericlsm.go +++ b/pkg/sensors/tracing/genericlsm.go @@ -367,8 +367,6 @@ func createLsmSensorFromEntry(lsmEntry *genericLsm, tailCalls := program.MapBuilderProgram("lsm_calls", load) maps = append(maps, tailCalls) - load.SetTailCall("lsm", tailCalls) - filterMap := program.MapBuilderProgram("filter_map", load) maps = append(maps, filterMap) From 4da5bc40764ee02c5f6feeb6a5fd4319a11366f4 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 19 Aug 2024 13:13:05 +0000 Subject: [PATCH 33/35] tetragon: Load tail calls directly in genericuprobe program Signed-off-by: Jiri Olsa --- bpf/process/bpf_generic_uprobe.c | 32 +++++++++++++++++++++------- pkg/sensors/tracing/genericuprobe.go | 3 --- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/bpf/process/bpf_generic_uprobe.c b/bpf/process/bpf_generic_uprobe.c index 33306eeffce..36c7cbc542e 100644 --- a/bpf/process/bpf_generic_uprobe.c +++ b/bpf/process/bpf_generic_uprobe.c @@ -24,12 +24,28 @@ struct { __type(value, struct msg_generic_kprobe); } process_call_heap SEC(".maps"); +int generic_uprobe_setup_event(void *ctx); +int generic_uprobe_process_event(void *ctx); +int generic_uprobe_process_filter(void *ctx); +int generic_uprobe_filter_arg(void *ctx); +int generic_uprobe_actions(void *ctx); +int generic_uprobe_output(void *ctx); + struct { __uint(type, BPF_MAP_TYPE_PROG_ARRAY); __uint(max_entries, 13); __uint(key_size, sizeof(__u32)); - __uint(value_size, sizeof(__u32)); -} uprobe_calls SEC(".maps"); + __array(values, int(void *)); +} uprobe_calls SEC(".maps") = { + .values = { + [0] = (void *)&generic_uprobe_setup_event, + [1] = (void *)&generic_uprobe_process_event, + [2] = (void *)&generic_uprobe_process_filter, + [3] = (void *)&generic_uprobe_filter_arg, + [4] = (void *)&generic_uprobe_actions, + [5] = (void *)&generic_uprobe_output, + }, +}; struct filter_map_value { unsigned char buf[FILTER_SIZE]; @@ -69,7 +85,7 @@ generic_uprobe_event(struct pt_regs *ctx) return generic_start_process_filter(ctx, &maps); } -__attribute__((section("uprobe/0"), used)) int +__attribute__((section("uprobe"), used)) int generic_uprobe_setup_event(void *ctx) { return generic_process_event_and_setup( @@ -78,7 +94,7 @@ generic_uprobe_setup_event(void *ctx) (struct bpf_map_def *)&config_map, 0); } -__attribute__((section("uprobe/1"), used)) int +__attribute__((section("uprobe"), used)) int generic_uprobe_process_event(void *ctx) { return generic_process_event(ctx, @@ -87,7 +103,7 @@ generic_uprobe_process_event(void *ctx) (struct bpf_map_def *)&config_map, 0); } -__attribute__((section("uprobe/2"), used)) int +__attribute__((section("uprobe"), used)) int generic_uprobe_process_filter(void *ctx) { int ret; @@ -104,7 +120,7 @@ generic_uprobe_process_filter(void *ctx) return PFILTER_REJECT; } -__attribute__((section("uprobe/3"), used)) int +__attribute__((section("uprobe"), used)) int generic_uprobe_filter_arg(void *ctx) { return filter_read_arg(ctx, (struct bpf_map_def *)&process_call_heap, @@ -114,13 +130,13 @@ generic_uprobe_filter_arg(void *ctx) true); } -__attribute__((section("uprobe/4"), used)) int +__attribute__((section("uprobe"), used)) int generic_uprobe_actions(void *ctx) { return generic_actions(ctx, &maps); } -__attribute__((section("uprobe/5"), used)) int +__attribute__((section("uprobe"), used)) int generic_uprobe_output(void *ctx) { return generic_output(ctx, (struct bpf_map_def *)&process_call_heap, MSG_OP_GENERIC_UPROBE); diff --git a/pkg/sensors/tracing/genericuprobe.go b/pkg/sensors/tracing/genericuprobe.go index c748bd64b0c..84c3b8b3d7c 100644 --- a/pkg/sensors/tracing/genericuprobe.go +++ b/pkg/sensors/tracing/genericuprobe.go @@ -422,8 +422,6 @@ func createMultiUprobeSensor(sensorPath string, multiIDs []idtable.EntryID) ([]* maps = append(maps, configMap, tailCalls, filterMap) - load.SetTailCall("uprobe", tailCalls) - filterMap.SetMaxEntries(len(multiIDs)) configMap.SetMaxEntries(len(multiIDs)) return progs, maps, nil @@ -475,7 +473,6 @@ func createUprobeSensorFromEntry(uprobeEntry *genericUprobe, filterMap := program.MapBuilderProgram("filter_map", load) selMatchBinariesMap := program.MapBuilderProgram("tg_mb_sel_opts", load) maps = append(maps, configMap, tailCalls, filterMap, selMatchBinariesMap) - load.SetTailCall("uprobe", tailCalls) return progs, maps } From a788550f50f42edcc7bc23dbdd38459faf88caea Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 20 Aug 2024 07:48:20 +0000 Subject: [PATCH 34/35] tetragon: Remove install tail call machinery Signed-off-by: Jiri Olsa --- pkg/sensors/program/loader.go | 43 ---------------------------------- pkg/sensors/program/program.go | 10 -------- 2 files changed, 53 deletions(-) diff --git a/pkg/sensors/program/loader.go b/pkg/sensors/program/loader.go index fe95f12280d..0df39723da7 100644 --- a/pkg/sensors/program/loader.go +++ b/pkg/sensors/program/loader.go @@ -696,44 +696,6 @@ func slimVerifierError(errStr string) string { return errStr[:headEnd] + "\n...\n" + errStr[tailStart:] } -func installTailCalls(bpfDir string, spec *ebpf.CollectionSpec, coll *ebpf.Collection, load *Program) error { - // FIXME(JM): This should be replaced by using the cilium/ebpf prog array initialization. - - secToProgName := make(map[string]string) - for name, prog := range spec.Programs { - secToProgName[prog.SectionName] = name - } - - install := func(pinPath string, secPrefix string) error { - tailCallsMap, err := ebpf.LoadPinnedMap(filepath.Join(bpfDir, pinPath), nil) - if err != nil { - return nil - } - defer tailCallsMap.Close() - - for i := 0; i < 13; i++ { - secName := fmt.Sprintf("%s/%d", secPrefix, i) - if progName, ok := secToProgName[secName]; ok { - if prog, ok := coll.Programs[progName]; ok { - err := tailCallsMap.Update(uint32(i), uint32(prog.FD()), ebpf.UpdateAny) - if err != nil { - return fmt.Errorf("update of tail-call map '%s' failed: %w", pinPath, err) - } - } - } - } - return nil - } - - if load.TcMap != nil { - if err := install(load.TcMap.PinPath, load.TcPrefix); err != nil { - return err - } - } - - return nil -} - func doLoadProgram( bpfDir string, load *Program, @@ -857,11 +819,6 @@ func doLoadProgram( } defer coll.Close() - err = installTailCalls(bpfDir, spec, coll, load) - if err != nil { - return nil, fmt.Errorf("installing tail calls failed: %s", err) - } - for _, mapLoad := range load.MapLoad { pinPath := "" if pm, ok := load.PinMap[mapLoad.Name]; ok { diff --git a/pkg/sensors/program/program.go b/pkg/sensors/program/program.go index 835d7d7d1fb..f8b0efb992e 100644 --- a/pkg/sensors/program/program.go +++ b/pkg/sensors/program/program.go @@ -149,10 +149,6 @@ type Program struct { // Type information used for CO-RE relocations. KernelTypes *btf.Spec - // Tail call prefix/map - TcPrefix string - TcMap *Map - Link link.Link Prog *ebpf.Program @@ -175,12 +171,6 @@ func (p *Program) SetAttachData(d interface{}) *Program { return p } -func (p *Program) SetTailCall(prefix string, m *Map) *Program { - p.TcPrefix = prefix - p.TcMap = m - return p -} - func (p *Program) SetPolicy(policy string) *Program { p.Policy = policy return p From acd49312b688f7041466365a48ef19de77fc57f1 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 21 Aug 2024 11:14:44 +0000 Subject: [PATCH 35/35] tetragon: Allow to override execve tail calls Signed-off-by: Jiri Olsa --- bpf/process/bpf_execve_event.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bpf/process/bpf_execve_event.c b/bpf/process/bpf_execve_event.c index dee90be22bf..0a8649c02b5 100644 --- a/bpf/process/bpf_execve_event.c +++ b/bpf/process/bpf_execve_event.c @@ -13,11 +13,12 @@ #include "policy_filter.h" +char _license[] __attribute__((section("license"), used)) = "Dual BSD/GPL"; + +#ifndef OVERRIDE_TAILCALL int execve_rate(void *ctx); int execve_send(void *ctx); -char _license[] __attribute__((section("license"), used)) = "Dual BSD/GPL"; - struct { __uint(type, BPF_MAP_TYPE_PROG_ARRAY); __uint(max_entries, 2); @@ -29,6 +30,7 @@ struct { [1] = (void *)&execve_send, }, }; +#endif #include "data_event.h"