Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reorg to factor mac entries setup and add a max entries test #2587

Merged
merged 4 commits into from
Jul 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bpf/process/bpf_enforcer.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ struct enforcer_data {

struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 32768);
__uint(max_entries, 1);
__type(key, __u64);
__type(value, struct enforcer_data);
} enforcer_data SEC(".maps");
Expand Down
2 changes: 2 additions & 0 deletions pkg/sensors/tracing/enforcer.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,8 @@ func (kp *enforcerPolicy) createEnforcerSensor(
}

enforcerDataMap := enforcerMap(policyName, progs...)
enforcerDataMap.SetMaxEntries(enforcerMapMaxEntries)

maps = append(maps, enforcerDataMap)

if ok := kp.enforcerAdd(name, kh); !ok {
Expand Down
80 changes: 52 additions & 28 deletions pkg/sensors/tracing/generickprobe.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ const (
stackTraceMapMaxEntries = 32768
ratelimitMapMaxEntries = 32768
fdInstallMapMaxEntries = 32000
enforcerMapMaxEntries = 32768
)

func kprobeCharBufErrorToString(e int32) string {
Expand Down Expand Up @@ -272,14 +273,12 @@ func filterMaps(load *program.Program, pinPath string, kprobeEntry *genericKprob
return maps
}

func createMultiKprobeSensor(sensorPath, policyName string, multiIDs []idtable.EntryID, enableFDInstall bool) ([]*program.Program, []*program.Map, error) {
func createMultiKprobeSensor(sensorPath, policyName string, multiIDs []idtable.EntryID, has hasMaps) ([]*program.Program, []*program.Map, error) {
var multiRetIDs []idtable.EntryID
var progs []*program.Program
var maps []*program.Map

data := &genericKprobeData{}
oneKprobeHasStackTrace := false
oneKprobeHasRatelimit := false

for _, id := range multiIDs {
gk, err := genericKprobeTableGet(id)
Expand All @@ -289,9 +288,10 @@ func createMultiKprobeSensor(sensorPath, policyName string, multiIDs []idtable.E
if gk.loadArgs.retprobe {
multiRetIDs = append(multiRetIDs, id)
}
oneKprobeHasStackTrace = oneKprobeHasStackTrace || gk.hasStackTrace
oneKprobeHasRatelimit = oneKprobeHasRatelimit || gk.hasRatelimit
gk.data = data

has.stackTrace = has.stackTrace || gk.hasStackTrace
has.rateLimit = has.rateLimit || gk.hasRatelimit
}

loadProgName := "bpf_multi_kprobe_v53.o"
Expand All @@ -316,7 +316,7 @@ func createMultiKprobeSensor(sensorPath, policyName string, multiIDs []idtable.E
progs = append(progs, load)

fdinstall := program.MapBuilderPin("fdinstall_map", sensors.PathJoin(sensorPath, "fdinstall_map"), load)
if enableFDInstall {
if has.fdInstall {
fdinstall.SetMaxEntries(fdInstallMapMaxEntries)
}
maps = append(maps, fdinstall)
Expand Down Expand Up @@ -345,7 +345,7 @@ func createMultiKprobeSensor(sensorPath, policyName string, multiIDs []idtable.E
maps = append(maps, matchBinariesPaths)

stackTraceMap := program.MapBuilderPin("stack_trace_map", sensors.PathJoin(pinPath, "stack_trace_map"), load)
if oneKprobeHasStackTrace {
if has.stackTrace {
stackTraceMap.SetMaxEntries(stackTraceMapMaxEntries)
}
maps = append(maps, stackTraceMap)
Expand All @@ -358,13 +358,16 @@ func createMultiKprobeSensor(sensorPath, policyName string, multiIDs []idtable.E

if kernels.EnableLargeProgs() {
ratelimitMap := program.MapBuilderPin("ratelimit_map", sensors.PathJoin(pinPath, "ratelimit_map"), load)
if oneKprobeHasRatelimit {
if has.rateLimit {
ratelimitMap.SetMaxEntries(ratelimitMapMaxEntries)
}
maps = append(maps, ratelimitMap)
}

enforcerDataMap := enforcerMap(policyName, load)
if has.enforcer {
enforcerDataMap.SetMaxEntries(enforcerMapMaxEntries)
}
maps = append(maps, enforcerDataMap)

filterMap.SetMaxEntries(len(multiIDs))
Expand Down Expand Up @@ -396,7 +399,7 @@ func createMultiKprobeSensor(sensorPath, policyName string, multiIDs []idtable.E
maps = append(maps, callHeap)

fdinstall := program.MapBuilderPin("fdinstall_map", sensors.PathJoin(sensorPath, "fdinstall_map"), loadret)
if enableFDInstall {
if has.fdInstall {
fdinstall.SetMaxEntries(fdInstallMapMaxEntries)
}
maps = append(maps, fdinstall)
Expand Down Expand Up @@ -552,6 +555,27 @@ func getKprobeSymbols(symbol string, syscall bool, lists []v1alpha1.ListSpec) ([
return []string{symbol}, syscall, nil
}

type hasMaps struct {
stackTrace bool
rateLimit bool
fdInstall bool
enforcer bool
}

func hasMapsSetup(spec *v1alpha1.TracingPolicySpec) hasMaps {
has := hasMaps{}
for _, kprobe := range spec.KProbes {
has.fdInstall = has.fdInstall || selectorsHaveFDInstall(kprobe.Selectors)
has.enforcer = has.enforcer || len(spec.Enforcers) != 0

// check for early break
if has.fdInstall && has.enforcer {
break
}
}
return has
}

func createGenericKprobeSensor(
spec *v1alpha1.TracingPolicySpec,
name string,
Expand Down Expand Up @@ -585,16 +609,6 @@ func createGenericKprobeSensor(
selMaps = &selectors.KernelSelectorMaps{}
}

// detect at the policy level if one kprobe uses the fdinstall feature since
// the map is shared amongst all kprobes
oneKprobeHasFDInstall := false
for _, kprobe := range kprobes {
if selectorsHaveFDInstall(kprobe.Selectors) {
oneKprobeHasFDInstall = true
break
}
}

in := addKprobeIn{
useMulti: useMulti,
sensorPath: name,
Expand All @@ -604,6 +618,8 @@ func createGenericKprobeSensor(
selMaps: selMaps,
}

has := hasMapsSetup(spec)

for i := range kprobes {
syms, syscall, err := getKprobeSymbols(kprobes[i].Call, kprobes[i].Syscall, lists)
if err != nil {
Expand All @@ -623,9 +639,9 @@ func createGenericKprobeSensor(
}

if useMulti {
progs, maps, err = createMultiKprobeSensor(in.sensorPath, in.policyName, ids, oneKprobeHasFDInstall)
progs, maps, err = createMultiKprobeSensor(in.sensorPath, in.policyName, ids, has)
} else {
progs, maps, err = createSingleKprobeSensor(in.sensorPath, ids, oneKprobeHasFDInstall)
progs, maps, err = createSingleKprobeSensor(in.sensorPath, ids, has)
}

if err != nil {
Expand Down Expand Up @@ -862,7 +878,7 @@ func addKprobe(funcName string, f *v1alpha1.KProbeSpec, in *addKprobeIn) (id idt
}

func createKprobeSensorFromEntry(kprobeEntry *genericKprobe, sensorPath string,
progs []*program.Program, maps []*program.Map, enableFDInstall bool) ([]*program.Program, []*program.Map) {
progs []*program.Program, maps []*program.Map, has hasMaps) ([]*program.Program, []*program.Map) {

loadProgName, loadProgRetName := kernels.GenericKprobeObjs()
isSecurityFunc := strings.HasPrefix(kprobeEntry.funcName, "security_")
Expand All @@ -884,7 +900,7 @@ func createKprobeSensorFromEntry(kprobeEntry *genericKprobe, sensorPath string,
progs = append(progs, load)

fdinstall := program.MapBuilderPin("fdinstall_map", sensors.PathJoin(sensorPath, "fdinstall_map"), load)
if enableFDInstall {
if has.fdInstall {
fdinstall.SetMaxEntries(fdInstallMapMaxEntries)
}
maps = append(maps, fdinstall)
Expand Down Expand Up @@ -921,7 +937,7 @@ func createKprobeSensorFromEntry(kprobeEntry *genericKprobe, sensorPath string,
// 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)
if kprobeEntry.hasStackTrace {
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.
stackTraceMap.SetMaxEntries(stackTraceMapMaxEntries)
Expand All @@ -936,7 +952,7 @@ func createKprobeSensorFromEntry(kprobeEntry *genericKprobe, sensorPath string,

if kernels.EnableLargeProgs() {
ratelimitMap := program.MapBuilderPin("ratelimit_map", sensors.PathJoin(pinPath, "ratelimit_map"), load)
if kprobeEntry.hasRatelimit {
if has.rateLimit {
// similarly as for stacktrace, we expand the max size only if
// needed to reduce the memory footprint when unused
ratelimitMap.SetMaxEntries(ratelimitMapMaxEntries)
Expand All @@ -945,6 +961,9 @@ func createKprobeSensorFromEntry(kprobeEntry *genericKprobe, sensorPath string,
}

enforcerDataMap := enforcerMap(kprobeEntry.policyName, load)
if has.enforcer {
enforcerDataMap.SetMaxEntries(enforcerMapMaxEntries)
}
maps = append(maps, enforcerDataMap)

if kprobeEntry.loadArgs.retprobe {
Expand Down Expand Up @@ -978,7 +997,7 @@ func createKprobeSensorFromEntry(kprobeEntry *genericKprobe, sensorPath string,
maps = append(maps, callHeap)

fdinstall := program.MapBuilderPin("fdinstall_map", sensors.PathJoin(sensorPath, "fdinstall_map"), loadret)
if enableFDInstall {
if has.fdInstall {
fdinstall.SetMaxEntries(fdInstallMapMaxEntries)
}
maps = append(maps, fdinstall)
Expand All @@ -994,7 +1013,7 @@ func createKprobeSensorFromEntry(kprobeEntry *genericKprobe, sensorPath string,
return progs, maps
}

func createSingleKprobeSensor(sensorPath string, ids []idtable.EntryID, enableFDInstall bool) ([]*program.Program, []*program.Map, error) {
func createSingleKprobeSensor(sensorPath string, ids []idtable.EntryID, has hasMaps) ([]*program.Program, []*program.Map, error) {
var progs []*program.Program
var maps []*program.Map

Expand All @@ -1004,7 +1023,12 @@ func createSingleKprobeSensor(sensorPath string, ids []idtable.EntryID, enableFD
return nil, nil, err
}
gk.data = &genericKprobeData{}
progs, maps = createKprobeSensorFromEntry(gk, sensorPath, progs, maps, enableFDInstall)

// setup per kprobe map config
has.stackTrace = gk.hasStackTrace
has.rateLimit = gk.hasRatelimit

progs, maps = createKprobeSensorFromEntry(gk, sensorPath, progs, maps, has)
}

return progs, maps, nil
Expand Down
16 changes: 13 additions & 3 deletions pkg/sensors/tracing/generictracepoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -360,13 +360,14 @@ func createGenericTracepoint(

// createGenericTracepointSensor will create a sensor that can be loaded based on a generic tracepoint configuration
func createGenericTracepointSensor(
spec *v1alpha1.TracingPolicySpec,
name string,
confs []v1alpha1.TracepointSpec,
policyID policyfilter.PolicyID,
policyName string,
lists []v1alpha1.ListSpec,
customHandler eventhandler.Handler,
) (*sensors.Sensor, error) {
confs := spec.Tracepoints
lists := spec.Lists

tracepoints := make([]*genericTracepoint, 0, len(confs))
for i := range confs {
Expand All @@ -386,6 +387,10 @@ func createGenericTracepointSensor(
progName = "bpf_generic_tracepoint_v53.o"
}

has := hasMaps{
enforcer: len(spec.Enforcers) != 0,
}

maps := []*program.Map{}
progs := make([]*program.Program, 0, len(tracepoints))
for _, tp := range tracepoints {
Expand All @@ -405,11 +410,13 @@ func createGenericTracepointSensor(
return nil, fmt.Errorf("failed to initialize tracepoint kernel selectors: %w", err)
}

has.fdInstall = selectorsHaveFDInstall(tp.Spec.Selectors)

prog0.LoaderData = tp.tableIdx
progs = append(progs, prog0)

fdinstall := program.MapBuilderPin("fdinstall_map", sensors.PathJoin(pinPath, "fdinstall_map"), prog0)
if selectorsHaveFDInstall(tp.Spec.Selectors) {
if has.fdInstall {
fdinstall.SetMaxEntries(fdInstallMapMaxEntries)
}
maps = append(maps, fdinstall)
Expand Down Expand Up @@ -490,6 +497,9 @@ func createGenericTracepointSensor(
maps = append(maps, matchBinariesPaths)

enforcerDataMap := enforcerMap(policyName, prog0)
if has.enforcer {
enforcerDataMap.SetMaxEntries(enforcerMapMaxEntries)
}
maps = append(maps, enforcerDataMap)

selMatchBinariesMap := program.MapBuilderPin("tg_mb_sel_opts", sensors.PathJoin(pinPath, "tg_mb_sel_opts"), prog0)
Expand Down
Loading
Loading