@@ -2,9 +2,10 @@ package integration
22
33import (
44 "context"
5+ "io/ioutil"
56 "os"
6- "os/exec"
77 "strings"
8+ "syscall"
89 "testing"
910 "time"
1011
@@ -16,49 +17,23 @@ import (
1617 "github.com/stretchr/testify/require"
1718)
1819
19- // // small set of actions to trigger a magic write event
20- // func checkMagicwrite(t *testing.T, gotOutput *[]trace.Event) {
21- // // create a temp dir for testing
22- // d, err := ioutil.TempDir("", "Test_MagicWrite-dir-*")
23- // require.NoError(t, err)
24-
25- // // cp a file to trigger
26- // f, err := os.CreateTemp(d, "Test_MagicWrite-file-*")
27- // require.NoError(t, err)
28- // defer func() {
29- // os.Remove(d)
30- // }()
31-
32- // f.WriteString(`foo.bar.baz`)
33- // f.Close()
34-
35- // cpCmd := exec.Command("cp", f.Name(), filepath.Join(d+filepath.Base(f.Name())+"-new"))
36- // fmt.Println("executing: ", cpCmd.String())
37- // cpCmd.Stdout = os.Stdout
38- // assert.NoError(t, cpCmd.Run())
39-
40- // waitForTraceeOutput(t, gotOutput, time.Now(), true)
41-
42- // // check tracee output
43- // expect := []byte{102, 111, 111, 46, 98, 97, 114, 46, 98, 97, 122}
44- // fail := true
45- // for _, evt := range *gotOutput {
46- // arg := events.GetArg(&evt, "bytes")
47- // argVal, ok := arg.Value.([]byte)
48- // require.Equal(t, true, ok)
49- // ok = assert.ElementsMatch(t, argVal, expect)
50- // if ok {
51- // fail = false
52- // }
53- // }
54- // if fail {
55- // t.Fail()
56- // }
57- // }
20+ // small set of actions to trigger a magic write event
21+ func checkMagicwrite (t * testing.T , gotOutput * []trace.Event ) {
22+
23+ _ , err := forkAndExecFunction (doMagicWrite )
24+ require .NoError (t , err )
25+
26+ waitForTraceeOutput (t , gotOutput , time .Now (), true )
27+
28+ // check tracee output
29+ for _ , evt := range * gotOutput {
30+ assert .Equal (t , []byte (evt .EventName ), []byte ("magic_write" ))
31+ }
32+ }
5833
5934// execute a ls command
6035func checkExeccommand (t * testing.T , gotOutput * []trace.Event ) {
61- err := exec . Command ( "/usr/bin/ls" ). Run ( )
36+ _ , err := forkAndExecFunction ( doLs )
6237 require .NoError (t , err )
6338
6439 waitForTraceeOutput (t , gotOutput , time .Now (), true )
@@ -77,8 +52,7 @@ func checkExeccommand(t *testing.T, gotOutput *[]trace.Event) {
7752func checkPidnew (t * testing.T , gotOutput * []trace.Event ) {
7853 traceePid := os .Getpid ()
7954
80- // run a command
81- err := exec .Command ("/usr/bin/ls" ).Run ()
55+ _ , err := forkAndExecFunction (doLs )
8256 require .NoError (t , err )
8357
8458 waitForTraceeOutput (t , gotOutput , time .Now (), true )
@@ -97,7 +71,7 @@ func checkPidnew(t *testing.T, gotOutput *[]trace.Event) {
9771
9872// only capture uids of 0 that are run by comm ls
9973func checkUidZero (t * testing.T , gotOutput * []trace.Event ) {
100- err := exec . Command ( "/usr/bin/ls" ). Run ( )
74+ _ , err := forkAndExecFunction ( doLs )
10175 require .NoError (t , err )
10276
10377 waitForTraceeOutput (t , gotOutput , time .Now (), true )
@@ -117,7 +91,7 @@ func checkUidZero(t *testing.T, gotOutput *[]trace.Event) {
11791
11892// trigger ls from uid 0 (tests run as root) and check if empty
11993func checkUidNonZero (t * testing.T , gotOutput * []trace.Event ) {
120- err := exec . Command ( "/usr/bin/ls" ). Run ( )
94+ _ , err := forkAndExecFunction ( doLs )
12195 require .NoError (t , err )
12296
12397 waitForTraceeOutput (t , gotOutput , time .Now (), false )
@@ -128,7 +102,7 @@ func checkUidNonZero(t *testing.T, gotOutput *[]trace.Event) {
128102
129103// check that execve event is called
130104func checkExecve (t * testing.T , gotOutput * []trace.Event ) {
131- err := exec . Command ( "/usr/bin/ls" ). Run ( )
105+ _ , err := forkAndExecFunction ( doLs )
132106 require .NoError (t , err )
133107
134108 waitForTraceeOutput (t , gotOutput , time .Now (), true )
@@ -150,7 +124,7 @@ func checkExecve(t *testing.T, gotOutput *[]trace.Event) {
150124
151125// check for filesystem set when ls is invoked
152126func checkSetFs (t * testing.T , gotOutput * []trace.Event ) {
153- err := exec . Command ( "/usr/bin/ls" ). Run ( )
127+ _ , err := forkAndExecFunction ( doLs )
154128 require .NoError (t , err )
155129
156130 waitForTraceeOutput (t , gotOutput , time .Now (), true )
@@ -171,11 +145,9 @@ func checkSetFs(t *testing.T, gotOutput *[]trace.Event) {
171145}
172146
173147func checkNewContainers (t * testing.T , gotOutput * []trace.Event ) {
174- containerIdBytes , err := exec . Command ( "docker" , "run" , "-d" , "--rm" , "alpine" ). Output ( )
148+ containerIdBytes , err := forkAndExecFunction ( doDockerRun )
175149 require .NoError (t , err )
176-
177150 containerId := strings .TrimSuffix (string (containerIdBytes ), "\n " )
178-
179151 containerIds := []string {}
180152 for _ , evt := range * gotOutput {
181153 containerIds = append (containerIds , evt .ContainerID )
@@ -202,11 +174,11 @@ func Test_EventFilters(t *testing.T) {
202174 filterArgs []string
203175 eventFunc func (* testing.T , * []trace.Event )
204176 }{
205- // {
206- // name: "do a file write",
207- // filterArgs: []string{"event=magic_write"},
208- // eventFunc: checkMagicwrite,
209- // },
177+ {
178+ name : "do a file write" ,
179+ filterArgs : []string {"event=magic_write" },
180+ eventFunc : checkMagicwrite ,
181+ },
210182 {
211183 name : "execute a command" ,
212184 filterArgs : []string {"comm=ls" },
@@ -291,3 +263,37 @@ func Test_EventFilters(t *testing.T) {
291263 })
292264 }
293265}
266+
267+ type testFunc string
268+
269+ const (
270+ doMagicWrite testFunc = "do_magic_write"
271+ doLs testFunc = "do_ls"
272+ doDockerRun testFunc = "do_docker_run"
273+ )
274+
275+ // forkAndExecFunction runs a function in `tester.sh` in it's own system process.
276+ // This is so Tracee running in the current pid can pick the command up.
277+ // It returns the output of the process and a possible error.
278+ func forkAndExecFunction (funcName testFunc ) ([]byte , error ) {
279+ tmpFile , err := os .CreateTemp ("/tmp" , "tracee-test*" )
280+ if err != nil {
281+ return nil , err
282+ }
283+ _ , err = syscall .ForkExec ("./tester.sh" , []string {"./tester.sh" , string (funcName ), tmpFile .Name ()},
284+ & syscall.ProcAttr {
285+ Files : []uintptr {0 , 1 , 2 , tmpFile .Fd ()},
286+ })
287+ if err != nil {
288+ return nil , err
289+ }
290+
291+ // ForkExec doesn't block, wait for output
292+ time .Sleep (time .Second )
293+
294+ output , err := ioutil .ReadAll (tmpFile )
295+ if err != nil {
296+ return nil , err
297+ }
298+ return output , nil
299+ }
0 commit comments