Class: SeccompTools::Syscall
- Inherits:
-
Object
- Object
- SeccompTools::Syscall
- Defined in:
- lib/seccomp-tools/syscall.rb
Overview
Record syscall number, arguments, return value.
Constant Summary collapse
- ABI =
Syscall arguments offset of
struct userin 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 }, riscv64: { number: 136, args: [80, 88, 96, 104, 112, 120], ret: 80, SYS_prctl: 167, SYS_seccomp: 277 }, # Most software invokes syscalls through "svc 0", in which case the syscall number is in r1. # However, it's also possible to use "svc NR": this case is not handled here. s390x: { number: 24, args: [32, 40, 48, 56, 64, 72], ret: 32, SYS_prctl: 172, SYS_seccomp: 348 } }.freeze
Instance Attribute Summary collapse
-
#abi ⇒ {Symbol => Integer, Array<Integer>}
readonly
The ABI entry of this syscall's architecture.
-
#args ⇒ Array<Integer>
readonly
Syscall arguments, in register order.
-
#number ⇒ Integer
readonly
Syscall number.
-
#pid ⇒ Integer
readonly
Id of the traced process.
-
#ret ⇒ Integer
readonly
Syscall return value.
Class Method Summary collapse
-
.strict_bpf(arch) ⇒ String
Constructs a BPF program equivalent to what
SECCOMP_MODE_STRICTenforces: only read, write, exit, and sigreturn are allowed, while any other syscall kills the thread.
Instance Method Summary collapse
-
#arch ⇒ Symbol?
Architecture of this syscall, i.e.
-
#dump_bpf ⇒ String
Dumps the BPF of the filter being installed.
-
#filter_mode? ⇒ Boolean
Is this a +seccomp(SECCOMP_SET_MODE_FILTER, ..)+/+prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, ..)+ syscall?.
-
#initialize(pid) ⇒ Syscall
constructor
Instantiate a Syscall object.
-
#set_seccomp? ⇒ Boolean
Is this a seccomp installation syscall?.
-
#strict_mode? ⇒ Boolean
Is this a +seccomp(SECCOMP_SET_MODE_STRICT, ..)+/+prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT)+ syscall?.
Constructor Details
#initialize(pid) ⇒ Syscall
Instantiate a SeccompTools::Syscall object.
Reads the syscall number, arguments and return value of pid through ptrace, so the process
must already be stopped and attached.
44 45 46 47 48 49 50 51 52 |
# File 'lib/seccomp-tools/syscall.rb', line 44 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
#abi ⇒ {Symbol => Integer, Array<Integer>} (readonly)
Returns The ABI entry of this syscall's architecture.
28 29 30 |
# File 'lib/seccomp-tools/syscall.rb', line 28 def abi @abi end |
#args ⇒ Array<Integer> (readonly)
Returns Syscall arguments, in register order.
32 33 34 |
# File 'lib/seccomp-tools/syscall.rb', line 32 def args @args end |
#number ⇒ Integer (readonly)
Returns Syscall number.
30 31 32 |
# File 'lib/seccomp-tools/syscall.rb', line 30 def number @number end |
#pid ⇒ Integer (readonly)
Returns Id of the traced process.
25 26 27 |
# File 'lib/seccomp-tools/syscall.rb', line 25 def pid @pid end |
#ret ⇒ Integer (readonly)
Returns Syscall return value.
34 35 36 |
# File 'lib/seccomp-tools/syscall.rb', line 34 def ret @ret end |
Class Method Details
.strict_bpf(arch) ⇒ String
Constructs a BPF program equivalent to what SECCOMP_MODE_STRICT enforces: only read, write,
exit, and sigreturn are allowed, while any other syscall kills the thread.
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/seccomp-tools/syscall.rb', line 89 def self.strict_bpf(arch) # Required lazily because the assembler's scanner refers to {ABI} at load time. require 'seccomp-tools/asm/asm' # The kernel checks sigreturn on architectures that have it and rt_sigreturn on the others. sigreturn = Const::Syscall.const_get(arch.to_s.upcase)[:sigreturn] ? :sigreturn : :rt_sigreturn Asm.asm(<<-EOS, arch: arch) A = sys_number A == read ? ok : next A == write ? ok : next A == exit ? ok : next A == #{sigreturn} ? ok : next return KILL ok: return ALLOW EOS end |
Instance Method Details
#arch ⇒ Symbol?
Architecture of this syscall, i.e. of the traced process.
126 127 128 |
# File 'lib/seccomp-tools/syscall.rb', line 126 def arch @arch ||= Util.process_arch(pid) end |
#dump_bpf ⇒ String
Dumps the BPF of the filter being installed.
Only meaningful when #set_seccomp? is true. In filter mode args[2] points to a
struct sock_fprog in the traced process, whose BPF bytes are read out. Strict mode installs
no BPF, so an equivalent filter built by strict_bpf is returned instead.
114 115 116 117 118 119 120 121 |
# File 'lib/seccomp-tools/syscall.rb', line 114 def dump_bpf return self.class.strict_bpf(arch) if strict_mode? 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 |
#filter_mode? ⇒ Boolean
Is this a +seccomp(SECCOMP_SET_MODE_FILTER, ..)+/+prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, ..)+ syscall?
67 68 69 70 71 |
# File 'lib/seccomp-tools/syscall.rb', line 67 def filter_mode? 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 |
#set_seccomp? ⇒ Boolean
Is this a seccomp installation syscall?
Both SECCOMP_MODE_FILTER and SECCOMP_MODE_STRICT installations are recognized, invoked
through either seccomp or prctl(PR_SET_SECCOMP, ...).
60 61 62 |
# File 'lib/seccomp-tools/syscall.rb', line 60 def set_seccomp? filter_mode? || strict_mode? end |
#strict_mode? ⇒ Boolean
Is this a +seccomp(SECCOMP_SET_MODE_STRICT, ..)+/+prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT)+ syscall?
76 77 78 79 80 |
# File 'lib/seccomp-tools/syscall.rb', line 76 def strict_mode? return true if number == abi[:SYS_seccomp] && args[0] == Const::BPF::SECCOMP_SET_MODE_STRICT number == abi[:SYS_prctl] && args[0] == Const::BPF::PR_SET_SECCOMP && args[1] == Const::BPF::SECCOMP_MODE_STRICT end |