diff --git a/secutil/secutil_test.go b/secutil/secutil_test.go new file mode 100644 index 0000000..ba95b39 --- /dev/null +++ b/secutil/secutil_test.go @@ -0,0 +1,72 @@ +package secutil + +import ( + "testing" + + libseccomp "github.com/seccomp/libseccomp-golang" +) + +func TestBuildFilter(t *testing.T) { + defaultAction := libseccomp.ActKill + filter, err := buildFilterMock(defaultAction) + if err != nil { + t.Error("BuildFilter failed") + } + if d, e := filter.GetDefaultAction(); e != nil || d != defaultAction { + t.Error("DefaultAction does not match by BuildFilter") + } +} + +func TestFilterToBPF(t *testing.T) { + defaultAction := libseccomp.ActKill + filter, err := buildFilterMock(defaultAction) + if err != nil { + t.Error("BuildFilter failed") + } + prog, err := FilterToBPF(filter) + if err != nil || prog == nil || prog.Filter == nil { + t.Error("BuildFilter failed") + } +} + +func TestBuildFilterFail(t *testing.T) { + defaultAction := libseccomp.ActKill + defaultTrace := libseccomp.ActTrace + allow := []string{"fork"} + trace := []string{"execve"} + + allowf := append(allow, "fail") + filter, err := BuildFilter(defaultAction, defaultTrace, allowf, trace) + if err == nil || filter != nil { + t.Error("BuildFilter did not detect failure") + } + + tracef := append(trace, "fail") + filter, err = BuildFilter(defaultAction, defaultTrace, allow, tracef) + if err == nil || filter != nil { + t.Error("BuildFilter did not detect failure") + } + + filter, err = BuildFilter(libseccomp.ActInvalid, defaultTrace, allow, trace) + if err == nil || filter != nil { + t.Error("BuildFilter did not detect failure") + } +} + +func TestAddActionFail(t *testing.T) { + defaultAction := libseccomp.ActKill + filter, _ := libseccomp.NewFilter(defaultAction) + arch, _ := libseccomp.GetNativeArch() + filter.RemoveArch(arch) + err := addFilterAction(filter, "fork", defaultAction) + if err == nil { + t.Error("addFilterAction did not detect failure") + } +} + +func buildFilterMock(d libseccomp.ScmpAction) (*libseccomp.ScmpFilter, error) { + defaultTrace := libseccomp.ActTrace + allow := []string{"fork"} + trace := []string{"execve"} + return BuildFilter(d, defaultTrace, allow, trace) +} diff --git a/tracer/tracer_track.go b/tracer/tracer_track.go index 5c8c5b8..67468e8 100644 --- a/tracer/tracer_track.go +++ b/tracer/tracer_track.go @@ -38,9 +38,8 @@ func Trace(handler Handler, runners []Runner, limits ResLimit, timeout int64) (r ) results = make([]TraceResult, len(runners)) - // Ptrace require running at the same OS thread + // make this thread exit after trace, ensure no process escaped runtime.LockOSThread() - defer runtime.UnlockOSThread() // Starts all runners for i, r := range runners { @@ -124,7 +123,7 @@ func Trace(handler Handler, runners []Runner, limits ResLimit, timeout int64) (r case wstatus.Exited(): delete(traced, pid) println("process exited: ", pid, wstatus.ExitStatus()) - if idx, inside := pidmap[pid]; inside { + if inside { if execved[pid] { results[idx].ExitCode = wstatus.ExitStatus() if running--; running == 0 { @@ -139,7 +138,7 @@ func Trace(handler Handler, runners []Runner, limits ResLimit, timeout int64) (r case wstatus.Signaled(): sig := wstatus.Signal() println("ptrace signaled: ", sig) - if idx, inside := pidmap[pid]; inside { + if inside { switch sig { case unix.SIGXCPU: status = TraceCodeTLE @@ -159,11 +158,11 @@ func Trace(handler Handler, runners []Runner, limits ResLimit, timeout int64) (r if stopSig := wstatus.StopSignal(); stopSig == unix.SIGTRAP { switch trapCause := wstatus.TrapCause(); trapCause { case unix.PTRACE_EVENT_SECCOMP: - if execved[pid] { + if !inside || execved[pid] { // give the customized handle for syscall err := handleTrap(handler, pid) if err != nil { - if idx, inside := pidmap[pid]; inside { + if inside { results[idx].TraceStatus = TraceCodeBan } return results, err @@ -190,7 +189,7 @@ func Trace(handler Handler, runners []Runner, limits ResLimit, timeout int64) (r // Likely encountered SIGSEGV (segment violation) if stopSig != unix.SIGSTOP { println("ptrace unexpected stop signal: ", stopSig) - if idx, inside := pidmap[pid]; inside { + if inside { results[idx].TraceStatus = TraceCodeRE } return results, TraceCodeRE