diff --git a/runner/main.go b/runner/main.go index 52a9360..c9b9486 100644 --- a/runner/main.go +++ b/runner/main.go @@ -3,6 +3,7 @@ package main import ( "log" "os" + "syscall" tracer "github.com/criyle/go-judger/tracer" libseccomp "github.com/seccomp/libseccomp-golang" @@ -17,6 +18,10 @@ func handle(ctx *tracer.Context) tracer.TraceAction { fileptr := ctx.Arg0() file := ctx.GetString(fileptr) log.Println("open: ", file) + if file == "1" { + ctx.SetReturnValue(-int(syscall.EPERM)) + return tracer.TraceBan + } case "access": fileptr := ctx.Arg0() file := ctx.GetString(fileptr) diff --git a/tracer/context_amd64.go b/tracer/context_amd64.go index 45f9d31..4247b26 100644 --- a/tracer/context_amd64.go +++ b/tracer/context_amd64.go @@ -43,3 +43,13 @@ func (c *Context) GetString(addr uint64) string { syscall.PtracePeekData(c.pid, uintptr(addr), buff) return string(buff[:clen(buff)]) } + +// SetReturnValue set the return value if skip the syscall +func (c *Context) SetReturnValue(retval int) { + c.regs.Rax = uint64(retval) +} + +func (c *Context) skipSyscall() error { + c.regs.Orig_rax = uint64(1<<64 - 1) //-1 + return syscall.PtraceSetRegs(c.pid, &c.regs) +} diff --git a/tracer/tracer_track.go b/tracer/tracer_track.go index 5a45005..38f43a3 100644 --- a/tracer/tracer_track.go +++ b/tracer/tracer_track.go @@ -152,17 +152,10 @@ func (r *Tracer) StartTrace() (result *TraceResult, err error) { case unix.PTRACE_EVENT_SECCOMP: if execved { // give the customized handle for syscall - act, err := r.handleTrap(pid) + err := r.handleTrap(pid) if err != nil { return nil, err } - - switch act { - case TraceBan: - // TODO: action according to handler soft ban - case TraceKill: - return nil, TraceCodeBan - } } case unix.PTRACE_EVENT_CLONE: @@ -219,7 +212,7 @@ func (r *Tracer) verify() { } // handleTrap handles the seccomp trap including the custom handle -func (r *Tracer) handleTrap(pid int) (TraceAction, error) { +func (r *Tracer) handleTrap(pid int) error { r.println("Seccomp Traced") msg, err := unix.PtraceGetEventMsg(pid) if err != nil { @@ -240,16 +233,29 @@ func (r *Tracer) handleTrap(pid int) (TraceAction, error) { if r.TraceHandle != nil { ctx, err := getTrapContext(pid) if err != nil { - return TraceKill, err + return err + } + act := r.TraceHandle(ctx) + + switch act { + case TraceBan: + // https://www.kernel.org/doc/Documentation/prctl/seccomp_filter.txt + // Set the syscallno to -1 and return value into register + err := ctx.skipSyscall() + if err != nil { + return err + } + + case TraceKill: + return TraceCodeBan } - return r.TraceHandle(ctx), nil } default: r.println("unknown message: ", msg) } - return TraceAllow, nil + return nil } func setPtraceOption(pid int) error {