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 ( import (
"log" "log"
"os" "os"
"syscall"
tracer "github.com/criyle/go-judger/tracer" tracer "github.com/criyle/go-judger/tracer"
libseccomp "github.com/seccomp/libseccomp-golang" libseccomp "github.com/seccomp/libseccomp-golang"
@ -17,6 +18,10 @@ func handle(ctx *tracer.Context) tracer.TraceAction {
fileptr := ctx.Arg0() fileptr := ctx.Arg0()
file := ctx.GetString(fileptr) file := ctx.GetString(fileptr)
log.Println("open: ", file) log.Println("open: ", file)
if file == "1" {
ctx.SetReturnValue(-int(syscall.EPERM))
return tracer.TraceBan
}
case "access": case "access":
fileptr := ctx.Arg0() fileptr := ctx.Arg0()
file := ctx.GetString(fileptr) file := ctx.GetString(fileptr)

View File

@ -43,3 +43,13 @@ func (c *Context) GetString(addr uint64) string {
syscall.PtracePeekData(c.pid, uintptr(addr), buff) syscall.PtracePeekData(c.pid, uintptr(addr), buff)
return string(buff[:clen(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: case unix.PTRACE_EVENT_SECCOMP:
if execved { if execved {
// give the customized handle for syscall // give the customized handle for syscall
act, err := r.handleTrap(pid) err := r.handleTrap(pid)
if err != nil { if err != nil {
return nil, err return nil, err
} }
switch act {
case TraceBan:
// TODO: action according to handler soft ban
case TraceKill:
return nil, TraceCodeBan
}
} }
case unix.PTRACE_EVENT_CLONE: case unix.PTRACE_EVENT_CLONE:
@ -219,7 +212,7 @@ func (r *Tracer) verify() {
} }
// handleTrap handles the seccomp trap including the custom handle // 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") r.println("Seccomp Traced")
msg, err := unix.PtraceGetEventMsg(pid) msg, err := unix.PtraceGetEventMsg(pid)
if err != nil { if err != nil {
@ -240,16 +233,29 @@ func (r *Tracer) handleTrap(pid int) (TraceAction, error) {
if r.TraceHandle != nil { if r.TraceHandle != nil {
ctx, err := getTrapContext(pid) ctx, err := getTrapContext(pid)
if err != nil { 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: default:
r.println("unknown message: ", msg) r.println("unknown message: ", msg)
} }
return TraceAllow, nil return nil
} }
func setPtraceOption(pid int) error { func setPtraceOption(pid int) error {