From c8940e7caa69edbc6e8a6474a3fe5fdd9390ea50 Mon Sep 17 00:00:00 2001 From: criyle Date: Sun, 30 Jun 2019 23:13:56 -0700 Subject: [PATCH] add support to arm64 --- README.md | 8 +- runconfig/config.go | 213 +++++++++++++++++++++++++++++++++++++ runconfig/config_amd64.go | 205 +---------------------------------- runconfig/config_arm.go | 213 ++----------------------------------- runconfig/config_arm64.go | 14 +++ runconfig/config_loader.go | 5 +- runprogram/handle.go | 3 + tracee/tracee_fork.go | 4 +- tracer/context.go | 3 +- tracer/context_amd64.go | 10 +- tracer/context_arm.go | 17 +-- tracer/context_arm64.go | 60 +++++++++++ tracer/context_helper.go | 4 + tracer/ptrace.go | 40 +++++++ tracer/tracer_track.go | 4 +- 15 files changed, 372 insertions(+), 431 deletions(-) create mode 100644 runconfig/config.go create mode 100644 runconfig/config_arm64.go create mode 100644 tracer/context_arm64.go create mode 100644 tracer/ptrace.go diff --git a/README.md b/README.md index 65efee8..02a3360 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Default file access action: + check file read / write: `open`, `openat` + check file read: `readlink`, `readlinkat` + check file write: `unlink`, `unlinkat`, `chmod`, `rename` -+ check file access: `stat`, `lstat`, `access` ++ check file access: `stat`, `lstat`, `access`, `faccessat` + check file exec: `execve` Packages: @@ -32,10 +32,12 @@ Executable: Configuations: + run_program/config.go: all configs toward running specs +Features: ++ Percise resource limits (s -> ms, mb -> kb) ++ More architectures (arm32, arm64, x86) + TODO: + allow multiple traced programs + allow pipes -+ Percise resource limits (s -> ms, mb -> kb) -+ More architectures (arm32, x86) + ... diff --git a/runconfig/config.go b/runconfig/config.go new file mode 100644 index 0000000..5038e50 --- /dev/null +++ b/runconfig/config.go @@ -0,0 +1,213 @@ +package runconfig + +// This file includes configs for the run program settings + +var ( + // default read permission files + defaultReadableFiles = []string{ + "/etc/ld.so.nohwcap", + "/etc/ld.so.preload", + "/etc/ld.so.cache", + "/usr/lib/locale/locale-archive", + "/proc/self/exe", + "/etc/timezone", + "/usr/share/zoneinfo/", + "/dev/random", + "/dev/urandom", + "/proc/meminfo", + "/etc/localtime", + } + + // default write permission files + defaultWritableFiles = []string{"/dev/null"} + + // default allowed safe syscalls + defaultSyscallAllows = []string{ + // file access through fd + "read", + "write", + "readv", + "writev", + "close", + "fstat", + "lseek", + "dup", + "dup2", + "dup3", + "ioctl", + "fcntl", + "fadvise64", + + // memory action + "mmap", + "mprotect", + "munmap", + "brk", + "mremap", + "msync", + "mincore", + "madvise", + + // signal action + "rt_sigaction", + "rt_sigprocmask", + "rt_sigreturn", + "rt_sigpending", + "sigaltstack", + + // get current work dir + "getcwd", + + // process exit + "exit", + "exit_group", + + // others + "arch_prctl", + + "gettimeofday", + "getrlimit", + "getrusage", + "times", + "time", + "clock_gettime", + + "restart_syscall", + } + + // default syscalls to trace + defaultSyscallTraces = []string{ + // should be traced + "execve", + + // file open + "open", + "openat", + + // file delete + "unlink", + "unlinkat", + + // soft link + "readlink", + "readlinkat", + + // permission check + "lstat", + "stat", + "access", + "faccessat", + } + + // process related syscall if allowProc enabled + defaultProcSyscalls = []string{"clone", "fork", "vfork", "nanosleep", "execve"} + + // config for different type of program + // workpath and arg0 have additional read / stat permission + runprogramConfig = map[string]ProgramConfig{ + "python2.7": ProgramConfig{ + Syscall: SyscallConfig{ + ExtraAllow: []string{ + "futex", "getdents", "getdents64", "prlimit64", "getpid", "sysinfo", + }, + ExtraCount: map[string]int{ + "set_tid_address": 1, + "set_robust_list": 1, + }, + }, + FileAccess: FileAccessConfig{ + ExtraRead: []string{ + "/usr/bin/python2.7", + "/usr/lib/python2.7/", + "/usr/bin/lib/python2.7/", + "/usr/local/lib/python2.7/", + "/usr/lib/pymodules/python2.7/", + "/usr/bin/Modules/", + "/usr/bin/pybuilddir.txt", + "/usr/lib/locale/", + "./answer.code", + }, + ExtraStat: []string{ + "/usr", "/usr/bin", + }, + }, + RunCommand: []string{"/usr/bin/python2.7", "-E", "-s", "-B"}, + }, + "python3": ProgramConfig{ + Syscall: SyscallConfig{ + ExtraAllow: []string{ + "futex", "getdents", "getdents64", "prlimit64", "getpid", "sysinfo", "getrandom", + }, + ExtraCount: map[string]int{ + "set_tid_address": 1, + "set_robust_list": 1, + }, + }, + FileAccess: FileAccessConfig{ + ExtraRead: []string{ + "/usr/bin/python3", + "/usr/lib/python3/", + "/usr/bin/python3.6", + "/usr/lib/python3.6/", + "/usr/bin/lib/python3.6/", + "/usr/local/lib/python3.6/", + "/usr/bin/pyvenv.cfg", + "/usr/pyvenv.cfg", + "/usr/bin/Modules", + "/usr/bin/pybuilddir.txt", + "/usr/lib/dist-python", + "/usr/lib/locale/", + "./answer.code", + }, + ExtraStat: []string{ + "/usr", "/usr/bin", "/usr/lib", "/usr/lib/python36.zip", + }, + }, + RunCommand: []string{"/usr/bin/python3", "-I", "-B"}, + }, + "compiler": ProgramConfig{ + Syscall: SyscallConfig{ + ExtraAllow: []string{ + "gettid", "set_tid_address", "set_robust_list", "futex", + "getpid", "vfork", "fork", "clone", "execve", "wait4", + "clock_gettime", "clock_getres", + "setrlimit", "pipe", + "getdents64", "getdents", + "umask", "rename", "chmod", "mkdir", + "chdir", "fchdir", + "ftruncate", + "sched_getaffinity", "sched_yield", + "uname", "sysinfo", + "prlimit64", "getrandom", + }, + ExtraBan: []string{"socket", "connect", "geteuid", "getuid"}, + }, + FileAccess: FileAccessConfig{ + ExtraWrite: []string{ + "/tmp/", "./", + }, + ExtraRead: []string{ + "./", + "../runtime/", + "/etc/oracle/java/usagetracker.properties", + "/usr/", + "/lib/", + "/lib64/", + "/bin/", + "/sbin/", + "/sys/devices/system/cpu/", + "/proc/", + "/etc/timezone", + "/etc/fpc-2.6.2.cfg.d/", + "/etc/fpc.cfg", + "/*", + "/", // system_root + }, + ExtraBan: []string{ + "/etc/nsswitch.conf", + "/etc/passwd", + }, + }, + }, + } +) diff --git a/runconfig/config_amd64.go b/runconfig/config_amd64.go index 05401d5..9583b95 100644 --- a/runconfig/config_amd64.go +++ b/runconfig/config_amd64.go @@ -3,211 +3,12 @@ package runconfig // This file includes configs for the run program settings var ( - // default read permission files - defaultReadableFiles = []string{ - "/etc/ld.so.nohwcap", - "/etc/ld.so.preload", - "/etc/ld.so.cache", + archReadableFiles = []string{ "/lib/x86_64-linux-gnu/", "/usr/lib/x86_64-linux-gnu/", - "/usr/lib/locale/locale-archive", - "/proc/self/exe", - "/etc/timezone", - "/usr/share/zoneinfo/", - "/dev/random", - "/dev/urandom", - "/proc/meminfo", - "/etc/localtime", } - // default write permission files - defaultWritableFiles = []string{"/dev/null"} + archSyscallAllows = []string{} - // default allowed safe syscalls - defaultSyscallAllows = []string{ - // file access through fd - "read", - "write", - "readv", - "writev", - "close", - "fstat", - "lseek", - "dup", - "dup2", - "dup3", - "ioctl", - "fcntl", - - // memory action - "mmap", - "mprotect", - "munmap", - "brk", - "mremap", - "msync", - "mincore", - "madvise", - - // signal action - "rt_sigaction", - "rt_sigprocmask", - "rt_sigreturn", - "rt_sigpending", - "sigaltstack", - - // get current work dir - "getcwd", - - // process exit - "exit", - "exit_group", - - // others - "arch_prctl", - - "gettimeofday", - "getrlimit", - "getrusage", - "times", - "time", - "clock_gettime", - - "restart_syscall", - } - - // default syscalls to trace - defaultSyscallTraces = []string{ - // should be traced - "execve", - - // file open - "open", - "openat", - - // file delete - "unlink", - "unlinkat", - - // soft link - "readlink", - "readlinkat", - - // permission check - "lstat", - "stat", - "access", - } - - // process related syscall if allowProc enabled - defaultProcSyscalls = []string{"clone", "fork", "vfork", "nanosleep", "execve"} - - // config for different type of program - // workpath and arg0 have additional read / stat permission - runprogramConfig = map[string]ProgramConfig{ - "python2.7": ProgramConfig{ - Syscall: SyscallConfig{ - ExtraAllow: []string{ - "futex", "getdents", "getdents64", "prlimit64", "getpid", "sysinfo", - }, - ExtraCount: map[string]int{ - "set_tid_address": 1, - "set_robust_list": 1, - }, - }, - FileAccess: FileAccessConfig{ - ExtraRead: []string{ - "/usr/bin/python2.7", - "/usr/lib/python2.7/", - "/usr/bin/lib/python2.7/", - "/usr/local/lib/python2.7/", - "/usr/lib/pymodules/python2.7/", - "/usr/bin/Modules/", - "/usr/bin/pybuilddir.txt", - "/usr/lib/locale/", - "./answer.code", - }, - ExtraStat: []string{ - "/usr", "/usr/bin", - }, - }, - RunCommand: []string{"/usr/bin/python2.7", "-E", "-s", "-B"}, - }, - "python3": ProgramConfig{ - Syscall: SyscallConfig{ - ExtraAllow: []string{ - "futex", "getdents", "getdents64", "prlimit64", "getpid", "sysinfo", "getrandom", - }, - ExtraCount: map[string]int{ - "set_tid_address": 1, - "set_robust_list": 1, - }, - }, - FileAccess: FileAccessConfig{ - ExtraRead: []string{ - "/usr/bin/python3", - "/usr/lib/python3/", - "/usr/bin/python3.6", - "/usr/lib/python3.6/", - "/usr/bin/lib/python3.6/", - "/usr/local/lib/python3.6/", - "/usr/bin/pyvenv.cfg", - "/usr/pyvenv.cfg", - "/usr/bin/Modules", - "/usr/bin/pybuilddir.txt", - "/usr/lib/dist-python", - "/usr/lib/locale/", - "./answer.code", - }, - ExtraStat: []string{ - "/usr", "/usr/bin", "/usr/lib", "/usr/lib/python36.zip", - }, - }, - RunCommand: []string{"/usr/bin/python3", "-I", "-B"}, - }, - "compiler": ProgramConfig{ - Syscall: SyscallConfig{ - ExtraAllow: []string{ - "gettid", "set_tid_address", "set_robust_list", "futex", - "getpid", "vfork", "fork", "clone", "execve", "wait4", - "clock_gettime", "clock_getres", - "setrlimit", "pipe", - "getdents64", "getdents", - "umask", "rename", "chmod", "mkdir", - "chdir", "fchdir", - "ftruncate", - "sched_getaffinity", "sched_yield", - "uname", "sysinfo", - "prlimit64", "getrandom", - }, - ExtraBan: []string{"socket", "connect", "geteuid", "getuid"}, - }, - FileAccess: FileAccessConfig{ - ExtraWrite: []string{ - "/tmp/", "./", - }, - ExtraRead: []string{ - "./", - "../runtime/", - "/etc/oracle/java/usagetracker.properties", - "/usr/", - "/lib/", - "/lib64/", - "/bin/", - "/sbin/", - "/sys/devices/system/cpu/", - "/proc/", - "/etc/timezone", - "/etc/fpc-2.6.2.cfg.d/", - "/etc/fpc.cfg", - "/*", - "/", // system_root - }, - ExtraBan: []string{ - "/etc/nsswitch.conf", - "/etc/passwd", - }, - }, - }, - } + archSyscallTraces = []string{} ) diff --git a/runconfig/config_arm.go b/runconfig/config_arm.go index 90d3a99..71ba370 100644 --- a/runconfig/config_arm.go +++ b/runconfig/config_arm.go @@ -3,221 +3,24 @@ package runconfig // This file includes configs for the run program settings var ( - // default read permission files - defaultReadableFiles = []string{ - "/etc/ld.so.nohwcap", - "/etc/ld.so.preload", - "/etc/ld.so.cache", - "/lib/arm-linux-gnueabihf/", // 32-bit - "/usr/lib/arm-linux-gnueabihf/", // 32-bit - "/usr/lib/locale/locale-archive", - "/proc/self/exe", - "/etc/timezone", - "/usr/share/zoneinfo/", - "/dev/random", - "/dev/urandom", - "/proc/meminfo", - "/etc/localtime", + archReadableFiles = []string{ + "/lib/arm-linux-gnueabihf/", + "/usr/lib/arm-linux-gnueabihf/", } - // default write permission files - defaultWritableFiles = []string{"/dev/null"} - - // default allowed safe syscalls - defaultSyscallAllows = []string{ - // file access through fd - "read", - "write", - "readv", - "writev", - "close", - "fstat", + archSyscallAllows = []string{ "fstat64", // 32-bit - "lseek", "_llseek", // 32-bit - "dup", - "dup2", - "dup3", - "ioctl", - "fcntl", "fcntl64", // 32-bit - - // memory action - "mmap", - "mmap2", // 32-bit - "mprotect", - "munmap", - "brk", - "mremap", - "msync", - "mincore", - "madvise", - - // signal action - "rt_sigaction", - "rt_sigprocmask", - "rt_sigreturn", - "rt_sigpending", - "sigaltstack", - - // get current work dir - "getcwd", - - // process exit - "exit", - "exit_group", - - // others - "arch_prctl", - - "gettimeofday", - "getrlimit", - "getrusage", - "times", - "time", - "clock_gettime", - - "restart_syscall", - + "mmap2", // 32-bit // arch "uname", "set_tls", + "arm_fadvise64_64", } - // default syscalls to trace - defaultSyscallTraces = []string{ - // should be traced - "execve", - - // file open - "open", - "openat", - - // file delete - "unlink", - "unlinkat", - - // soft link - "readlink", - "readlinkat", - - // permission check - "lstat", + archSyscallTraces = []string{ "lstat64", // 32-bit - "stat", - "stat64", // 32-bit - "access", - } - - // process related syscall if allowProc enabled - defaultProcSyscalls = []string{"clone", "fork", "vfork", "nanosleep", "execve"} - - // config for different type of program - // workpath and arg0 have additional read / stat permission - runprogramConfig = map[string]ProgramConfig{ - "python2.7": ProgramConfig{ - Syscall: SyscallConfig{ - ExtraAllow: []string{ - "futex", "getdents", "getdents64", "prlimit64", "getpid", "sysinfo", - }, - ExtraCount: map[string]int{ - "set_tid_address": 1, - "set_robust_list": 1, - }, - }, - FileAccess: FileAccessConfig{ - ExtraRead: []string{ - "/usr/bin/python2.7", - "/usr/lib/python2.7/", - "/usr/bin/lib/python2.7/", - "/usr/local/lib/python2.7/", - "/usr/lib/pymodules/python2.7/", - "/usr/bin/Modules/", - "/usr/bin/pybuilddir.txt", - "/usr/lib/locale/", - "./answer.code", - }, - ExtraStat: []string{ - "/usr", "/usr/bin", - }, - }, - RunCommand: []string{"/usr/bin/python2.7", "-E", "-s", "-B"}, - }, - "python3": ProgramConfig{ - Syscall: SyscallConfig{ - ExtraAllow: []string{ - "futex", "getdents", "getdents64", "prlimit64", "getpid", "sysinfo", "getrandom", - }, - ExtraCount: map[string]int{ - "set_tid_address": 1, - "set_robust_list": 1, - }, - }, - FileAccess: FileAccessConfig{ - ExtraRead: []string{ - "/usr/bin/python3", - "/usr/lib/python3/", - "/usr/bin/python3.6", - "/usr/lib/python3.6/", - "/usr/bin/lib/python3.6/", - "/usr/local/lib/python3.6/", - "/usr/bin/pyvenv.cfg", - "/usr/pyvenv.cfg", - "/usr/bin/Modules", - "/usr/bin/pybuilddir.txt", - "/usr/lib/dist-python", - "/usr/lib/locale/", - "./answer.code", - }, - ExtraStat: []string{ - "/usr", "/usr/bin", "/usr/lib", "/usr/lib/python36.zip", - }, - }, - RunCommand: []string{"/usr/bin/python3", "-I", "-B"}, - }, - "compiler": ProgramConfig{ - Syscall: SyscallConfig{ - ExtraAllow: []string{ - "gettid", "set_tid_address", "set_robust_list", "futex", - "getpid", "vfork", "fork", "clone", "execve", "wait4", - "clock_gettime", "clock_getres", - "setrlimit", "pipe", - "getdents64", "getdents", - "umask", "rename", "chmod", "mkdir", - "chdir", "fchdir", - "ftruncate", - "sched_getaffinity", "sched_yield", - "uname", "sysinfo", - "prlimit64", "getrandom", - }, - ExtraBan: []string{"socket", "connect", "geteuid", "getuid"}, - }, - FileAccess: FileAccessConfig{ - ExtraWrite: []string{ - "/tmp/", "./", - }, - ExtraRead: []string{ - "./", - "../runtime/", - "/etc/oracle/java/usagetracker.properties", - "/usr/", - "/lib/", - "/lib64/", - "/bin/", - "/sbin/", - "/sys/devices/system/cpu/", - "/proc/", - "/etc/timezone", - "/etc/fpc-2.6.2.cfg.d/", - "/etc/fpc.cfg", - "/*", - "/", // system_root - }, - ExtraBan: []string{ - "/etc/nsswitch.conf", - "/etc/passwd", - }, - }, - }, + "stat64", // 32-bit } ) diff --git a/runconfig/config_arm64.go b/runconfig/config_arm64.go new file mode 100644 index 0000000..bb5a3ed --- /dev/null +++ b/runconfig/config_arm64.go @@ -0,0 +1,14 @@ +package runconfig + +// This file includes configs for the run program settings + +var ( + archReadableFiles = []string{ + "/lib/aarch64-linux-gnu/", + "/usr/lib/aarch64-linux-gnu/", + } + + archSyscallAllows = []string{} + + archSyscallTraces = []string{} +) diff --git a/runconfig/config_loader.go b/runconfig/config_loader.go index 4e814b8..ff6f3cd 100644 --- a/runconfig/config_loader.go +++ b/runconfig/config_loader.go @@ -5,11 +5,12 @@ func GetConf(pType, workPath string, args, addRead, addWrite []string, allowProc var ( fs = NewFileSets() sc = NewSyscallCounter() - allow = append([]string{}, defaultSyscallAllows...) - trace = append([]string{}, defaultSyscallTraces...) + allow = append(append([]string{}, defaultSyscallAllows...), archSyscallAllows...) + trace = append(append([]string{}, defaultSyscallTraces...), archSyscallTraces...) ) fs.Readable.AddRange(defaultReadableFiles, workPath) + fs.Readable.AddRange(archReadableFiles, workPath) fs.Writable.AddRange(defaultWritableFiles, workPath) fs.AddFilePermission(args[0], FilePermRead) fs.AddFilePermission(workPath, FilePermRead) diff --git a/runprogram/handle.go b/runprogram/handle.go index 6253e21..845da89 100644 --- a/runprogram/handle.go +++ b/runprogram/handle.go @@ -79,6 +79,8 @@ func (h *tracerHandler) Handle(ctx *tracer.Context) tracer.TraceAction { case "access": action = h.checkStat(ctx, ctx.Arg0()) + case "faccessat": + action = h.checkStat(ctx, ctx.Arg1()) case "stat", "stat64": action = h.checkStat(ctx, ctx.Arg0()) @@ -100,6 +102,7 @@ func (h *tracerHandler) Handle(ctx *tracer.Context) tracer.TraceAction { case TraceAllow: return tracer.TraceAllow case TraceBan: + h.Debug("") return softBanSyscall(ctx) default: return tracer.TraceKill diff --git a/tracee/tracee_fork.go b/tracee/tracee_fork.go index 9ec4100..ec333a6 100644 --- a/tracee/tracee_fork.go +++ b/tracee/tracee_fork.go @@ -116,7 +116,7 @@ func (r *Runner) Start() (int, error) { // Pass 1: fd[i] < i => nextfd for i := 0; i < len(fd); i++ { if fd[i] >= 0 && fd[i] < int(i) { - _, _, err1 = syscall.RawSyscall(syscall.SYS_DUP2, uintptr(fd[i]), uintptr(nextfd), 0) + _, _, err1 = syscall.RawSyscall(syscall.SYS_DUP3, uintptr(fd[i]), uintptr(nextfd), 0) if err1 != 0 { goto childerror } @@ -141,7 +141,7 @@ func (r *Runner) Start() (int, error) { } continue } - _, _, err1 = syscall.RawSyscall(syscall.SYS_DUP2, uintptr(fd[i]), uintptr(i), 0) + _, _, err1 = syscall.RawSyscall(syscall.SYS_DUP3, uintptr(fd[i]), uintptr(i), 0) if err1 != 0 { goto childerror } diff --git a/tracer/context.go b/tracer/context.go index e19e72c..708f85e 100644 --- a/tracer/context.go +++ b/tracer/context.go @@ -27,7 +27,8 @@ func init() { func getTrapContext(pid int) (*Context, error) { var regs syscall.PtraceRegs - err := syscall.PtraceGetRegs(pid, ®s) + //err := syscall.PtraceGetRegs(pid, ®s) + err := ptraceGetRegSet(pid, ®s) if err != nil { return nil, err } diff --git a/tracer/context_amd64.go b/tracer/context_amd64.go index b2c6129..f87d330 100644 --- a/tracer/context_amd64.go +++ b/tracer/context_amd64.go @@ -51,11 +51,9 @@ func (c *Context) skipSyscall() error { return syscall.PtraceSetRegs(c.Pid, &c.regs) } -func getIovecs(base *byte, l int) []unix.Iovec { - return []unix.Iovec{ - unix.Iovec{ - Base: base, - Len: uint64(l), - }, +func getIovec(base *byte, l int) unix.Iovec { + return unix.Iovec{ + Base: base, + Len: uint64(l), } } diff --git a/tracer/context_arm.go b/tracer/context_arm.go index a85e4f1..5305ce0 100644 --- a/tracer/context_arm.go +++ b/tracer/context_arm.go @@ -47,15 +47,16 @@ func (c *Context) SetReturnValue(retval int) { } func (c *Context) skipSyscall() error { - c.regs.Uregs[7] = ^uint32(0) //-1 - return syscall.PtraceSetRegs(c.Pid, &c.regs) + err := syscall.PtraceSetRegs(c.Pid, &c.regs) + if err != nil { + return err + } + return ptraceArmSetSyscall(c.Pid, -1) } -func getIovecs(base *byte, l int) []unix.Iovec { - return []unix.Iovec{ - unix.Iovec{ - Base: base, - Len: uint32(l), - }, +func getIovec(base *byte, l int) unix.Iovec { + return unix.Iovec{ + Base: base, + Len: uint32(l), } } diff --git a/tracer/context_arm64.go b/tracer/context_arm64.go new file mode 100644 index 0000000..72ec1ce --- /dev/null +++ b/tracer/context_arm64.go @@ -0,0 +1,60 @@ +package tracer + +import ( + unix "golang.org/x/sys/unix" +) + +// SyscallNo get current syscall no +func (c *Context) SyscallNo() uint { + return uint(c.regs.Regs[8]) // R8 +} + +// Arg0 gets the arg0 for the current syscall +func (c *Context) Arg0() uint { + return uint(c.regs.Regs[0]) //R0 +} + +// Arg1 gets the arg1 for the current syscall +func (c *Context) Arg1() uint { + return uint(c.regs.Regs[1]) // R1 +} + +// Arg2 gets the arg2 for the current syscall +func (c *Context) Arg2() uint { + return uint(c.regs.Regs[2]) // R2 +} + +// Arg3 gets the arg3 for the current syscall +func (c *Context) Arg3() uint { + return uint(c.regs.Regs[3]) // R3 +} + +// Arg4 gets the arg4 for the current syscall +func (c *Context) Arg4() uint { + return uint(c.regs.Regs[4]) // R4 +} + +// Arg5 gets the arg5 for the current syscall +func (c *Context) Arg5() uint { + return uint(c.regs.Regs[5]) //R5 +} + +// SetReturnValue set the return value if skip the syscall +func (c *Context) SetReturnValue(retval int) { + c.regs.Regs[0] = uint64(retval) // R0 +} + +func (c *Context) skipSyscall() error { + err := ptraceSetRegSet(c.Pid, &c.regs) + if err != nil { + return err + } + return ptraceArm64SetSyscall(c.Pid, -1) +} + +func getIovec(base *byte, l int) unix.Iovec { + return unix.Iovec{ + Base: base, + Len: uint64(l), + } +} diff --git a/tracer/context_helper.go b/tracer/context_helper.go index 296bab4..81db2e2 100644 --- a/tracer/context_helper.go +++ b/tracer/context_helper.go @@ -31,6 +31,10 @@ func vmRead(pid int, addr uintptr, buff []byte) (int, error) { return int(n), err } +func getIovecs(base *byte, l int) []unix.Iovec { + return []unix.Iovec{getIovec(base, l)} +} + func vmReadStr(pid int, addr uintptr, buff []byte) error { // Deal with unaligned addr n := 0 diff --git a/tracer/ptrace.go b/tracer/ptrace.go new file mode 100644 index 0000000..79c0bc7 --- /dev/null +++ b/tracer/ptrace.go @@ -0,0 +1,40 @@ +package tracer + +import ( + "syscall" + "unsafe" +) + +const ( + NT_PRSTATUS = 1 + NT_ARM_SYSTEM_CALL = 0x404 + + PTRACE_SET_SYSCALL = 23 +) + +func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) { + _, _, e1 := syscall.Syscall6(syscall.SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0) + if e1 != 0 { + err = e1 + } + return +} + +func ptraceGetRegSet(pid int, regs *syscall.PtraceRegs) error { + iov := getIovec((*byte)(unsafe.Pointer(regs)), int(unsafe.Sizeof(*regs))) + return ptrace(syscall.PTRACE_GETREGSET, pid, NT_PRSTATUS, uintptr(unsafe.Pointer(&iov))) +} + +func ptraceSetRegSet(pid int, regs *syscall.PtraceRegs) error { + iov := getIovec((*byte)(unsafe.Pointer(regs)), int(unsafe.Sizeof(*regs))) + return ptrace(syscall.PTRACE_SETREGSET, pid, NT_PRSTATUS, uintptr(unsafe.Pointer(&iov))) +} + +func ptraceArm64SetSyscall(pid int, syscallNo int) error { + iov := getIovec((*byte)(unsafe.Pointer(&syscallNo)), int(unsafe.Sizeof(syscallNo))) + return ptrace(syscall.PTRACE_SETREGSET, pid, NT_ARM_SYSTEM_CALL, uintptr(unsafe.Pointer(&iov))) +} + +func ptraceArmSetSyscall(pid int, syscallNo int) error { + return ptrace(PTRACE_SET_SYSCALL, pid, 0, uintptr(syscallNo)) +} diff --git a/tracer/tracer_track.go b/tracer/tracer_track.go index a3e7305..340d0b8 100644 --- a/tracer/tracer_track.go +++ b/tracer/tracer_track.go @@ -203,14 +203,14 @@ func handleTrap(handler Handler, pid int) error { handler.Debug("seccomp traced") msg, err := unix.PtraceGetEventMsg(pid) if err != nil { - handler.Debug(err) + handler.Debug("PtraceGetEventMsg failed:", err) return err } switch int16(msg) { case MsgDisallow: ctx, err := getTrapContext(pid) if err != nil { - handler.Debug(err) + handler.Debug("getTrapContext failed:", err) return err } syscallName, err := handler.GetSyscallName(ctx)