diff --git a/docs/data/tetragon_flags.yaml b/docs/data/tetragon_flags.yaml index 835f0919802..69664680a74 100644 --- a/docs/data/tetragon_flags.yaml +++ b/docs/data/tetragon_flags.yaml @@ -92,6 +92,8 @@ options: - name: event-queue-size default_value: "10000" usage: Set the size of the internal event queue. + - name: execve-map-entries + usage: Set entries for execve_map table (default 32768) - name: export-aggregation-buffer-size default_value: "10000" usage: Aggregator channel buffer size diff --git a/pkg/option/config.go b/pkg/option/config.go index 2b57b0f761d..7ea60a2ad48 100644 --- a/pkg/option/config.go +++ b/pkg/option/config.go @@ -109,6 +109,8 @@ type config struct { EventCacheRetryDelay int CompatibilitySyscall64SizeType bool + + ExecveMapEntries string } var ( diff --git a/pkg/option/flags.go b/pkg/option/flags.go index a2c8117cef9..ceb989284e9 100644 --- a/pkg/option/flags.go +++ b/pkg/option/flags.go @@ -117,6 +117,8 @@ const ( KeyEventCacheRetryDelay = "event-cache-retry-delay" KeyCompatibilitySyscall64SizeType = "enable-compatibility-syscall64-size-type" + + KeyExecveMapEntries = "execve-map-entries" ) type UsernameMetadaCode int @@ -250,6 +252,7 @@ func ReadAndSetFlags() error { Config.CompatibilitySyscall64SizeType = viper.GetBool(KeyCompatibilitySyscall64SizeType) + Config.ExecveMapEntries = viper.GetString(KeyExecveMapEntries) return nil } @@ -416,4 +419,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, "", "Set entries for execve_map table (default 32768)") } diff --git a/pkg/sensors/base/base.go b/pkg/sensors/base/base.go index f080fde22a5..300dc41cc08 100644 --- a/pkg/sensors/base/base.go +++ b/pkg/sensors/base/base.go @@ -5,16 +5,23 @@ 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 ( @@ -77,6 +84,55 @@ 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 setupExecveMap() { + entry := int(unsafe.Sizeof(execvemap.ExecveValue{})) + + get := func(str string) int { + // default value + if str == "" { + 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 + } + + entries := get(option.Config.ExecveMapEntries) + ExecveMap.SetMaxEntries(entries) + + logger.GetLogger(). + WithField("size", strutils.SizeWithSuffix(entries*entry)). + WithField("config", option.Config.ExecveMapEntries). + Infof("Set execve_map entries %d", entries) + +} + func setupSensor() { // exit program function ks, err := ksyms.KernelSymbols() @@ -97,7 +153,7 @@ func setupSensor() { } logger.GetLogger().Infof("Exit probe on %s", Exit.Attach) - ExecveMap.SetMaxEntries(execveMapMaxEntries) + setupExecveMap() } func GetExecveMap() *program.Map {