Class: SeccompTools::Syscall

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

Overview

Record syscall number, arguments, return value.

Constant Summary collapse

ABI =

Syscall arguments offset of struct user in different arch.

{
  amd64: { number: 120, args: [112, 104, 96, 56, 72, 44], ret: 80, SYS_prctl: 157, SYS_seccomp: 317 },
  i386: { number: 44, args: [0, 4, 8, 12, 16, 20], ret: 24, SYS_prctl: 172, SYS_seccomp: 354 },
  aarch64: { number: 64, args: [0, 8, 16, 24, 32, 40, 48], ret: 0, SYS_prctl: 167, SYS_seccomp: 277 }
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pid) ⇒ Syscall

Instantiate a SeccompTools::Syscall object.

Parameters:

  • pid (String)

    Process-id.

Raises:

  • (ArgumentError)


32
33
34
35
36
37
38
39
40
# File 'lib/seccomp-tools/syscall.rb', line 32

def initialize(pid)
  @pid = pid
  raise ArgumentError, "Only supports #{ABI.keys.join(', ')}" if ABI[arch].nil?

  @abi = ABI[arch]
  @number = peek(abi[:number])
  @args = abi[:args].map { |off| peek(off) }
  @ret = peek(abi[:ret])
end

Instance Attribute Details

#abiHash{Symbol => Integer, Array<Integer>} (readonly)

Returns See ABI.

Returns:

  • (Hash{Symbol => Integer, Array<Integer>})

    See ABI.



21
22
23
# File 'lib/seccomp-tools/syscall.rb', line 21

def abi
  @abi
end

#argsInteger (readonly)

Returns Syscall arguments.

Returns:

  • (Integer)

    Syscall arguments.



25
26
27
# File 'lib/seccomp-tools/syscall.rb', line 25

def args
  @args
end

#numberInteger (readonly)

Returns Syscall number.

Returns:

  • (Integer)

    Syscall number.



23
24
25
# File 'lib/seccomp-tools/syscall.rb', line 23

def number
  @number
end

#pidInteger (readonly)

Returns Process id.

Returns:

  • (Integer)

    Process id.



19
20
21
# File 'lib/seccomp-tools/syscall.rb', line 19

def pid
  @pid
end

#retInteger (readonly)

Returns Syscall return value.

Returns:

  • (Integer)

    Syscall return value.



27
28
29
# File 'lib/seccomp-tools/syscall.rb', line 27

def ret
  @ret
end

Instance Method Details

#archSymbol

Returns Architecture of this syscall.

Returns:

  • (Symbol)

    Architecture of this syscall.



64
65
66
67
68
69
70
71
72
73
# File 'lib/seccomp-tools/syscall.rb', line 64

def arch
  @arch ||= File.open("/proc/#{pid}/exe", 'rb') do |f|
    f.pos = 18
    case f.read(1).ord
    when 3 then :i386
    when 62 then :amd64
    when 183 then :aarch64
    end
  end
end

#dump_bpfString

Dump bpf byte from args[2].

Returns:

  • (String)


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

def dump_bpf
  addr = args[2]
  len = Ptrace.peekdata(pid, addr, 0) & 0xffff # len is unsigned short
  filter = Ptrace.peekdata(pid, addr + bits / 8, 0) & ((1 << bits) - 1)
  Array.new(len) { |i| Ptrace.peekdata(pid, filter + i * 8, 0) }.pack('Q*')
end

#set_seccomp?Boolean

Is this a seccomp(SECCOMP_MODE_FILTER, addr)/+prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, addr)+ syscall?

Returns:

  • (Boolean)

    true for is a seccomp installation syscall.



46
47
48
49
50
51
# File 'lib/seccomp-tools/syscall.rb', line 46

def set_seccomp?
  # TODO: handle SECCOMP_MODE_SET_STRICT / SECCOMP_MODE_STRICT
  return true if number == abi[:SYS_seccomp] && args[0] == Const::BPF::SECCOMP_SET_MODE_FILTER

  number == abi[:SYS_prctl] && args[0] == Const::BPF::PR_SET_SECCOMP && args[1] == Const::BPF::SECCOMP_MODE_FILTER
end