add ability to skip syscall

This commit is contained in:
criyle 2019-03-31 21:43:40 -04:00
parent 05d7ca1edc
commit 15e5680512
3 changed files with 33 additions and 12 deletions

View File

@ -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)

View File

@ -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)
}

View File

@ -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 {