Class: SeccompTools::Dumper::Handler

Inherits:
Object
  • Object
show all
Defined in:
lib/seccomp-tools/dumper.rb

Overview

Do the tracer things.

Instance Method Summary collapse

Constructor Details

#initialize(pid) ⇒ Handler

Instantiate a SeccompTools::Dumper::Handler object.

Parameters:

  • pid (Integer)

    The process id after fork.



54
55
56
57
58
59
# File 'lib/seccomp-tools/dumper.rb', line 54

def initialize(pid)
  Process.waitpid(pid)
  opt = Ptrace::O_TRACESYSGOOD | Ptrace::O_TRACECLONE | Ptrace::O_TRACEFORK | Ptrace::O_TRACEVFORK
  Ptrace.setoptions(pid, 0, opt)
  Ptrace.syscall(pid, 0, 0)
end

Instance Method Details

#handle(limit) {|bpf, arch| ... } ⇒ Array<Object>, Array<String>

Tracer.

Parameters:

  • limit (Integer)

    Child will be killed when number of calling prctl(SET_SECCOMP) reaches limit.

Yield Parameters:

  • bpf (String)

    Seccomp bpf in raw bytes.

  • arch (Symbol)

    Architecture. See Syscall::ABI for supported architectures.

Returns:

  • (Array<Object>, Array<String>)

    Return the block returned. If block is not given, array of raw bytes will be returned.



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/seccomp-tools/dumper.rb', line 71

def handle(limit, &block)
  collect = []
  syscalls = {} # record last syscall
  loop while wait_syscall do |child|
    if syscalls[child].nil? # invoke syscall
      syscalls[child] = syscall(child)
      next true
    end
    # syscall finished
    sys = syscalls[child]
    syscalls[child] = nil
    if sys.set_seccomp? && syscall(child).ret.zero? # consider successful call only
      bpf = sys.dump_bpf
      collect << (block.nil? ? bpf : yield(bpf, sys.arch))
      limit -= 1
    end
    !limit.zero?
  end
  syscalls.each_key { |cpid| Process.kill('KILL', cpid) if alive?(cpid) }
  Process.waitall
  collect
end