Skip to content

Commit

Permalink
enforcer: fix multiple prog issue with fmod_ret
Browse files Browse the repository at this point in the history
When using fmod_ret, we need to load multiple programs -- one for each
attach point we want to enforce.

In the current implementation, each program would use its own map which
means that the enforcer notification worked only for a single program.

This patch fixes the code so that all programs use the same map. It also
adds a test.

Signed-off-by: Kornilios Kourtis <[email protected]>
  • Loading branch information
kkourt committed Jun 7, 2024
1 parent a14d31d commit 7bf5502
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 4 deletions.
7 changes: 7 additions & 0 deletions pkg/sensors/program/map.go
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down
8 changes: 4 additions & 4 deletions pkg/sensors/tracing/enforcer.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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 {
Expand Down
54 changes: 54 additions & 0 deletions pkg/sensors/tracing/enforcer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down

0 comments on commit 7bf5502

Please sign in to comment.