Skip to content

Commit

Permalink
tetragon: Add execve-map-entries option
Browse files Browse the repository at this point in the history
Adding execve-map-entries option to setup entries of execve_map map.

Signed-off-by: Jiri Olsa <[email protected]>
  • Loading branch information
olsajiri committed Jan 23, 2025
1 parent 831862a commit 02d88da
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 3 deletions.
3 changes: 3 additions & 0 deletions docs/data/tetragon_flags.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions pkg/option/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ type config struct {
EventCacheRetryDelay int

CompatibilitySyscall64SizeType bool

ExecveMapEntries string
}

var (
Expand Down
5 changes: 5 additions & 0 deletions pkg/option/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ const (
KeyEventCacheRetryDelay = "event-cache-retry-delay"

KeyCompatibilitySyscall64SizeType = "enable-compatibility-syscall64-size-type"

KeyExecveMapEntries = "execve-map-entries"
)

type UsernameMetadaCode int
Expand Down Expand Up @@ -252,6 +254,7 @@ func ReadAndSetFlags() error {

Config.CompatibilitySyscall64SizeType = viper.GetBool(KeyCompatibilitySyscall64SizeType)

Config.ExecveMapEntries = viper.GetString(KeyExecveMapEntries)
return nil
}

Expand Down Expand Up @@ -419,4 +422,6 @@ func AddFlags(flags *pflag.FlagSet) {
flags.Int(KeyEventCacheRetryDelay, defaults.DefaultEventCacheRetryDelay, "Delay in seconds between event cache retries")

flags.Bool(KeyCompatibilitySyscall64SizeType, false, "syscall64 type will produce output of type size (compatibility flag, will be removed in v1.4)")

flags.String(KeyExecveMapEntries, "32768", "Set entries for execve_map table (entries/size/max)")
}
54 changes: 52 additions & 2 deletions pkg/sensors/base/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,27 @@ package base

import (
"log"
"os"
"strconv"
"strings"
"sync"
"testing"
"unsafe"

"github.com/cilium/tetragon/pkg/errmetrics"
"github.com/cilium/tetragon/pkg/ksyms"
"github.com/cilium/tetragon/pkg/logger"
"github.com/cilium/tetragon/pkg/mbset"
"github.com/cilium/tetragon/pkg/option"
"github.com/cilium/tetragon/pkg/sensors"
"github.com/cilium/tetragon/pkg/sensors/exec/config"
"github.com/cilium/tetragon/pkg/sensors/exec/execvemap"
"github.com/cilium/tetragon/pkg/sensors/program"
"github.com/cilium/tetragon/pkg/strutils"
)

const (
execveMapMaxEntries = 32768
ExecveMapMaxEntries = 32768
)

var (
Expand Down Expand Up @@ -77,6 +84,43 @@ var (
ErrMetricsMap = program.MapBuilder(errmetrics.MapName, Execve)
)

func readThreadsMax(path string) (int64, error) {
data, err := os.ReadFile(path)
if err != nil {
return 0, err
}
str := strings.TrimRight(string(data), "\n")
return strconv.ParseInt(str, 10, 32)
}

func GetExecveMapEntries(str string) int {
entry := int(unsafe.Sizeof(execvemap.ExecveValue{}))

if len(str) == 0 {
return ExecveMapMaxEntries
}
// pure number of entries
if val, err := strconv.Atoi(str); err == nil {
return val
}
// follow threads-max entries
if str == "max" {
if val, err := readThreadsMax("/proc/sys/kernel/threads-max"); err == nil {
return int(val)
}
logger.GetLogger().Warn("Failed to read /proc/sys/kernel/threads-max file, falling back to default")
return ExecveMapMaxEntries
}
// set entries based on size
size, err := strutils.ParseSize(str)
if err != nil {
logger.GetLogger().Warn("Failed to parse --execve-map-max value, falling back to default")
return ExecveMapMaxEntries
}
val := size / entry
return val
}

func setupSensor() {
// exit program function
ks, err := ksyms.KernelSymbols()
Expand All @@ -97,7 +141,13 @@ func setupSensor() {
}
logger.GetLogger().Infof("Exit probe on %s", Exit.Attach)

ExecveMap.SetMaxEntries(execveMapMaxEntries)
entries := GetExecveMapEntries(option.Config.ExecveMapEntries)
ExecveMap.SetMaxEntries(entries)

logger.GetLogger().
WithField("size", strutils.SizeWithSuffix(entries*int(unsafe.Sizeof(execvemap.ExecveValue{})))).
WithField("config", option.Config.ExecveMapEntries).
Infof("Set execve_map entries %d", entries)
}

func GetExecveMap() *program.Map {
Expand Down
16 changes: 15 additions & 1 deletion pkg/sensors/exec/procevents/proc_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,15 @@ func writeExecveMap(procs []procs) {
panic(err)
}
}

entries, ok := base.ExecveMap.GetMaxEntries()
if !ok {
logger.GetLogger().Warnf("Failed to get number of execve_map entries, using default.")
entries = base.ExecveMapMaxEntries
}
logger.GetLogger().Infof("Maximum execve_map entries %d, need to add %d.", entries, len(procs))
i := uint32(0)

for _, p := range procs {
k := &execvemap.ExecveKey{Pid: p.pid}
v := &execvemap.ExecveValue{}
Expand Down Expand Up @@ -365,6 +374,11 @@ func writeExecveMap(procs []procs) {
if err != nil {
logger.GetLogger().WithField("value", v).WithError(err).Warn("failed to put value in execve_map")
}

i++
if i == entries {
break
}
}
// In order for kprobe events from kernel ctx to not abort we need the
// execve lookup to map to a valid entry. So to simplify the kernel side
Expand All @@ -381,7 +395,7 @@ func writeExecveMap(procs []procs) {
})
m.Close()

updateExecveMapStats(int64(len(procs)))
updateExecveMapStats(int64(entries))
}

func pushEvents(ps []procs) {
Expand Down

0 comments on commit 02d88da

Please sign in to comment.