diff --git a/events/interfaces.go b/events/interfaces.go index 558a7946..07b1f068 100644 --- a/events/interfaces.go +++ b/events/interfaces.go @@ -50,6 +50,10 @@ type Helper interface { // The child runs the given action as a different program name. SpawnAs(name string, action string, args ...string) error + // SpawnAsWithSymlink works like SpawnAs, except that it does make a copy, + // but creates a symlink to the current event-generator binary. + SpawnAsWithSymlink(name string, action string, args ...string) error + // Spawned returns true if the action is running in a child process. Spawned() bool diff --git a/events/syscall/db_program_spawned_process.go b/events/syscall/db_program_spawned_process.go index 5aba5c70..3798b54d 100644 --- a/events/syscall/db_program_spawned_process.go +++ b/events/syscall/db_program_spawned_process.go @@ -25,5 +25,5 @@ var _ = events.Register( ) func DbProgramSpawnedProcess(h events.Helper) error { - return h.SpawnAs("mysqld", "helper.ExecLs") + return h.SpawnAsWithSymlink("mysqld", "helper.ExecLs") } diff --git a/events/syscall/non_sudo_setuid.go b/events/syscall/non_sudo_setuid.go index 3a19ee07..a2514f28 100644 --- a/events/syscall/non_sudo_setuid.go +++ b/events/syscall/non_sudo_setuid.go @@ -36,6 +36,6 @@ func NonSudoSetuid(h events.Helper) error { h.Log().WithError(err).Debug("ignore root setuid error") return nil } else { - return h.SpawnAs("child", "syscall.NonSudoSetuid") + return h.SpawnAsWithSymlink("child", "syscall.NonSudoSetuid") } } diff --git a/events/syscall/read_sensitive_file_trusted_after_startup.go b/events/syscall/read_sensitive_file_trusted_after_startup.go index 5204b655..d2611f8c 100644 --- a/events/syscall/read_sensitive_file_trusted_after_startup.go +++ b/events/syscall/read_sensitive_file_trusted_after_startup.go @@ -21,5 +21,5 @@ import ( var _ = events.Register(ReadSensitiveFileTrustedAfterStartup) func ReadSensitiveFileTrustedAfterStartup(h events.Helper) error { - return h.SpawnAs("httpd", "syscall.ReadSensitiveFileUntrusted", "--sleep", "6s") + return h.SpawnAsWithSymlink("httpd", "syscall.ReadSensitiveFileUntrusted", "--sleep", "6s") } diff --git a/events/syscall/run_shell_untrusted.go b/events/syscall/run_shell_untrusted.go index 8f84fad5..90dd8403 100644 --- a/events/syscall/run_shell_untrusted.go +++ b/events/syscall/run_shell_untrusted.go @@ -22,5 +22,5 @@ import ( var _ = events.Register(RunShellUntrusted) func RunShellUntrusted(h events.Helper) error { - return h.SpawnAs("httpd", "helper.RunShell") + return h.SpawnAsWithSymlink("httpd", "helper.RunShell") } diff --git a/events/syscall/system_procs_network_activity.go b/events/syscall/system_procs_network_activity.go index b74002d8..74274014 100644 --- a/events/syscall/system_procs_network_activity.go +++ b/events/syscall/system_procs_network_activity.go @@ -25,5 +25,5 @@ var _ = events.Register( ) func SystemProcsNetworkActivity(h events.Helper) error { - return h.SpawnAs("sha1sum", "helper.NetworkActivity") + return h.SpawnAsWithSymlink("sha1sum", "helper.NetworkActivity") } diff --git a/events/syscall/user_mgmt_binaries.go b/events/syscall/user_mgmt_binaries.go index 0fbd6435..6443429c 100644 --- a/events/syscall/user_mgmt_binaries.go +++ b/events/syscall/user_mgmt_binaries.go @@ -32,5 +32,5 @@ func UserMgmtBinaries(h events.Helper) error { Reason: "'User mgmt binaries' is excluded in containers", } } - return h.SpawnAs("vipw", "helper.ExecLs") + return h.SpawnAsWithSymlink("vipw", "helper.ExecLs") } diff --git a/pkg/runner/helper.go b/pkg/runner/helper.go index f097f6b6..556aede1 100644 --- a/pkg/runner/helper.go +++ b/pkg/runner/helper.go @@ -90,6 +90,39 @@ func (h *helper) SpawnAs(name string, action string, args ...string) error { } defer os.RemoveAll(tmpDir) + name = filepath.Join(tmpDir, name) + var data []byte + if data, err = os.ReadFile(h.runner.exePath); err != nil { + return err + } + if err = os.WriteFile(name, data, 0755); err != nil { + return err + } + + cmd := exec.Command(name, append(h.runner.exeArgs, fullArgs...)...) + + out := h.runner.log.Out + cmd.Stdout = out + cmd.Stderr = out + if err := cmd.Run(); err != nil { + return err + } + + return nil +} + +func (h *helper) SpawnAsWithSymlink(name string, action string, args ...string) error { + fullArgs := append([]string{fmt.Sprintf("^%s$", action)}, args...) + h.Log().WithField("args", strings.Join(fullArgs, " ")).Infof(`spawn as "%s"`, name) + if h.Spawned() { + return ErrChildSpawn + } + tmpDir, err := os.MkdirTemp(os.TempDir(), "falco-event-generator") + if err != nil { + return err + } + defer os.RemoveAll(tmpDir) + name = filepath.Join(tmpDir, name) if err := os.Symlink(h.runner.exePath, name); err != nil { return err