diff --git a/pkg/sensors/program/map.go b/pkg/sensors/program/map.go index b33f6f73882..5a092d67273 100644 --- a/pkg/sensors/program/map.go +++ b/pkg/sensors/program/map.go @@ -26,6 +26,13 @@ func MapBuilder(name string, ld *Program) *Map { return &Map{name, name, ld, Idle(), nil} } +func MapBuilderPinManyProgs(name, pin string, lds ...*Program) *Map { + for _, ld := range lds { + ld.PinMap[name] = pin + } + return &Map{name, pin, lds[0], Idle(), nil} +} + func MapBuilderPin(name, pin string, ld *Program) *Map { ld.PinMap[name] = pin return &Map{name, pin, ld, Idle(), nil} diff --git a/pkg/sensors/tracing/enforcer.go b/pkg/sensors/tracing/enforcer.go index 3abbf132158..67b4d644b64 100644 --- a/pkg/sensors/tracing/enforcer.go +++ b/pkg/sensors/tracing/enforcer.go @@ -50,9 +50,9 @@ 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(policyName string, load ...*program.Program) *program.Map { + return program.MapBuilderPinManyProgs(enforcerDataMapName, + fmt.Sprintf("%s_%s", enforcerDataMapName, policyName), load...) } func (kp *enforcerPolicy) enforcerGet(name string) (*enforcerHandler, bool) { @@ -315,7 +315,7 @@ func (kp *enforcerPolicy) createEnforcerSensor( return nil, fmt.Errorf("unexpected override method: %d", overrideMethod) } - enforcerDataMap := enforcerMap(policyName, load) + enforcerDataMap := enforcerMap(policyName, progs...) maps = append(maps, enforcerDataMap) if ok := kp.enforcerAdd(name, kh); !ok { diff --git a/pkg/sensors/tracing/enforcer_test.go b/pkg/sensors/tracing/enforcer_test.go index 1b7943ce75f..35fb044ced9 100644 --- a/pkg/sensors/tracing/enforcer_test.go +++ b/pkg/sensors/tracing/enforcer_test.go @@ -134,6 +134,60 @@ func TestEnforcerOverride(t *testing.T) { }) } +func TestEnforcerOverrideManySyscalls(t *testing.T) { + testEnforcerCheckSkip(t) + + test := testutils.RepoRootPath("contrib/tester-progs/getcpu") + builder := func() *EnforcerSpecBuilder { + return NewEnforcerSpecBuilder("enforcer-override"). + WithSyscallList("sys_getcpu", "sys_sethostname"). + WithMatchBinaries(test). + WithOverrideValue(-17) // EEXIST + } + + tpChecker := ec.NewProcessTracepointChecker(""). + WithArgs(ec.NewKprobeArgumentListMatcher(). + WithOperator(lc.Ordered). + WithValues( + ec.NewKprobeArgumentChecker().WithSizeArg(unix.SYS_GETCPU), + )). + WithAction(tetragon.KprobeAction_KPROBE_ACTION_NOTIFYENFORCER) + + checker := ec.NewUnorderedEventChecker(tpChecker) + + checkerFunc := func(_ error, rc int) { + if rc != int(syscall.EEXIST) { + t.Fatalf("Wrong exit code %d expected %d", rc, int(syscall.EEXIST)) + } + } + + t.Run("override_helper", func(t *testing.T) { + if !bpf.HasOverrideHelper() { + t.Skip("override_helper not supported") + } + + t.Run("multi kprobe", func(t *testing.T) { + if !bpf.HasKprobeMulti() { + t.Skip("no multi-kprobe support") + } + yaml := builder().WithOverrideReturn().WithMultiKprobe().MustYAML() + testEnforcer(t, yaml, test, "", checker, checkerFunc) + }) + + t.Run("kprobe (no multi)", func(t *testing.T) { + yaml := builder().WithOverrideReturn().WithoutMultiKprobe().MustYAML() + testEnforcer(t, yaml, test, "", checker, checkerFunc) + }) + }) + t.Run("fmod_ret", func(t *testing.T) { + if !bpf.HasModifyReturn() { + t.Skip("fmod_ret not supported") + } + yaml := builder().WithFmodRet().MustYAML() + testEnforcer(t, yaml, test, "", checker, checkerFunc) + }) +} + func TestEnforcerSignal(t *testing.T) { testEnforcerCheckSkip(t)