Skip to content

Commit

Permalink
tests: add test unlink opened file then fexecve()
Browse files Browse the repository at this point in the history
This adds another test that will open a binary, unlink inode
then exec to assert event is with inode.deleted

Signed-off-by: Djalal Harouni <tixxdz@gmail.com>
  • Loading branch information
tixxdz committed Oct 24, 2022
1 parent f93d878 commit 21301ee
Showing 1 changed file with 86 additions and 1 deletion.
87 changes: 86 additions & 1 deletion pkg/sensors/exec/exec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"context"
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
"strings"
Expand Down Expand Up @@ -591,7 +592,7 @@ func TestExecInodeNotDeleted(t *testing.T) {
assert.NoError(t, err)
}

func TestExecInodeDeleted(t *testing.T) {
func TestExecMemfdInodeDeleted(t *testing.T) {
var doneWG, readyWG sync.WaitGroup
defer doneWG.Wait()

Expand Down Expand Up @@ -649,3 +650,87 @@ func TestExecInodeDeleted(t *testing.T) {
err = jsonchecker.JsonTestCheck(t, checker)
assert.NoError(t, err)
}

func TestExecInodeDeleted(t *testing.T) {
var doneWG, readyWG sync.WaitGroup
defer doneWG.Wait()

ctx, cancel := context.WithTimeout(context.Background(), tus.Conf().CmdWaitTime)
defer cancel()

obs, err := observer.GetDefaultObserver(t, ctx, tus.Conf().TetragonLib)
if err != nil {
t.Fatalf("GetDefaultObserverWithFile error: %s", err)
}

baseDir := fmt.Sprintf("/tmp/tetragon-%s", t.Name())

// create directory
if err := os.MkdirAll(baseDir, 0755); err != nil {
if err := os.RemoveAll(baseDir); err != nil {
t.Fatalf("Failed to remove test dir: %s", err)
}
if err := os.MkdirAll(baseDir, 0755); err != nil {
t.Fatalf("Failed to create test directory: %s\n", err)
}
}

t.Cleanup(func() {
os.RemoveAll(baseDir)
})

testDir, err := ioutil.TempDir(baseDir, "*")
if err != nil {
log.Fatalf("Failed to create tmp dir '%s': %v", baseDir, err)
}
defer os.RemoveAll(testDir)

// Copy /bin/true
truePath := "/bin/true"
testTruePath := fmt.Sprintf("%s/true", testDir)

fmt.Printf("Copy: /usr/bin/cp -f " + truePath + " " + testTruePath + "\n")

if err := exec.Command("/usr/bin/cp", "-f", truePath, testTruePath).Run(); err != nil {
t.Fatalf("Failed to copy binary from '%s' to '%s': %s", truePath, testTruePath, err)
}

file, err := os.OpenFile(testTruePath, os.O_RDONLY, 0755)
if err != nil {
t.Fatalf("Failed to open binary '%s': %s", testTruePath, err)
}

defer file.Close()

// Drop inode reference
os.Remove(testTruePath)

// Let's just use plain old /proc method
// Should be same as glibc fexecve() =>
// execveat(fd, "", argv, envp, AT_EMPTY_PATH);
execPath := fmt.Sprintf("/proc/self/fd/%d", file.Fd())

observer.LoopEvents(ctx, t, &doneWG, &readyWG, obs)
readyWG.Wait()

// Execute from fd
strId := "tetragon-test-execfd-deleted-inode"
if err := exec.Command(execPath, strId).Run(); err != nil {
t.Fatalf("command failed: %s", err)
}

time.Sleep(1 * time.Second)

checker := ec.NewUnorderedEventChecker(
ec.NewProcessExecChecker().
WithProcess(ec.NewProcessChecker().
WithBinary(sm.Suffix(execPath)).
WithArguments(sm.Full(strId)).
WithInfo(ec.NewExecInfoChecker().
WithInode(ec.NewInodeChecker().
WithDeleted(true)))),
)

err = jsonchecker.JsonTestCheck(t, checker)
assert.NoError(t, err)
}

0 comments on commit 21301ee

Please sign in to comment.