seccomp-tools 1.4.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +105 -17
  3. data/ext/ptrace/ptrace.c +56 -4
  4. data/lib/seccomp-tools/asm/asm.rb +8 -6
  5. data/lib/seccomp-tools/asm/compiler.rb +130 -224
  6. data/lib/seccomp-tools/asm/sasm.tab.rb +780 -0
  7. data/lib/seccomp-tools/asm/sasm.y +175 -0
  8. data/lib/seccomp-tools/asm/scalar.rb +129 -0
  9. data/lib/seccomp-tools/asm/scanner.rb +163 -0
  10. data/lib/seccomp-tools/asm/statement.rb +32 -0
  11. data/lib/seccomp-tools/asm/token.rb +29 -0
  12. data/lib/seccomp-tools/bpf.rb +31 -7
  13. data/lib/seccomp-tools/cli/asm.rb +3 -3
  14. data/lib/seccomp-tools/cli/base.rb +4 -4
  15. data/lib/seccomp-tools/cli/disasm.rb +27 -3
  16. data/lib/seccomp-tools/cli/dump.rb +4 -2
  17. data/lib/seccomp-tools/cli/emu.rb +1 -4
  18. data/lib/seccomp-tools/const.rb +37 -3
  19. data/lib/seccomp-tools/consts/sys_nr/aarch64.rb +284 -0
  20. data/lib/seccomp-tools/consts/sys_nr/amd64.rb +5 -1
  21. data/lib/seccomp-tools/consts/sys_nr/i386.rb +14 -14
  22. data/lib/seccomp-tools/consts/sys_nr/s390x.rb +365 -0
  23. data/lib/seccomp-tools/disasm/context.rb +2 -2
  24. data/lib/seccomp-tools/disasm/disasm.rb +16 -9
  25. data/lib/seccomp-tools/dumper.rb +12 -3
  26. data/lib/seccomp-tools/emulator.rb +5 -9
  27. data/lib/seccomp-tools/error.rb +31 -0
  28. data/lib/seccomp-tools/instruction/alu.rb +1 -1
  29. data/lib/seccomp-tools/instruction/base.rb +1 -1
  30. data/lib/seccomp-tools/instruction/jmp.rb +28 -10
  31. data/lib/seccomp-tools/instruction/ld.rb +5 -3
  32. data/lib/seccomp-tools/syscall.rb +23 -13
  33. data/lib/seccomp-tools/templates/asm.s390x.asm +26 -0
  34. data/lib/seccomp-tools/util.rb +3 -1
  35. data/lib/seccomp-tools/version.rb +1 -1
  36. metadata +38 -9
  37. data/lib/seccomp-tools/asm/tokenizer.rb +0 -169
@@ -0,0 +1,365 @@
1
+ # frozen_string_literal: true
2
+
3
+ {
4
+ exit: 1,
5
+ fork: 2,
6
+ read: 3,
7
+ write: 4,
8
+ open: 5,
9
+ close: 6,
10
+ restart_syscall: 7,
11
+ creat: 8,
12
+ link: 9,
13
+ unlink: 10,
14
+ execve: 11,
15
+ chdir: 12,
16
+ mknod: 14,
17
+ chmod: 15,
18
+ lseek: 19,
19
+ getpid: 20,
20
+ mount: 21,
21
+ umount: 22,
22
+ ptrace: 26,
23
+ alarm: 27,
24
+ pause: 29,
25
+ utime: 30,
26
+ access: 33,
27
+ nice: 34,
28
+ sync: 36,
29
+ kill: 37,
30
+ rename: 38,
31
+ mkdir: 39,
32
+ rmdir: 40,
33
+ dup: 41,
34
+ pipe: 42,
35
+ times: 43,
36
+ brk: 45,
37
+ signal: 48,
38
+ acct: 51,
39
+ umount2: 52,
40
+ ioctl: 54,
41
+ fcntl: 55,
42
+ setpgid: 57,
43
+ umask: 60,
44
+ chroot: 61,
45
+ ustat: 62,
46
+ dup2: 63,
47
+ getppid: 64,
48
+ getpgrp: 65,
49
+ setsid: 66,
50
+ sigaction: 67,
51
+ sigsuspend: 72,
52
+ sigpending: 73,
53
+ sethostname: 74,
54
+ setrlimit: 75,
55
+ getrusage: 77,
56
+ gettimeofday: 78,
57
+ settimeofday: 79,
58
+ symlink: 83,
59
+ readlink: 85,
60
+ uselib: 86,
61
+ swapon: 87,
62
+ reboot: 88,
63
+ readdir: 89,
64
+ mmap: 90,
65
+ munmap: 91,
66
+ truncate: 92,
67
+ ftruncate: 93,
68
+ fchmod: 94,
69
+ getpriority: 96,
70
+ setpriority: 97,
71
+ statfs: 99,
72
+ fstatfs: 100,
73
+ socketcall: 102,
74
+ syslog: 103,
75
+ setitimer: 104,
76
+ getitimer: 105,
77
+ stat: 106,
78
+ lstat: 107,
79
+ fstat: 108,
80
+ lookup_dcookie: 110,
81
+ vhangup: 111,
82
+ idle: 112,
83
+ wait4: 114,
84
+ swapoff: 115,
85
+ sysinfo: 116,
86
+ ipc: 117,
87
+ fsync: 118,
88
+ sigreturn: 119,
89
+ clone: 120,
90
+ setdomainname: 121,
91
+ uname: 122,
92
+ adjtimex: 124,
93
+ mprotect: 125,
94
+ sigprocmask: 126,
95
+ create_module: 127,
96
+ init_module: 128,
97
+ delete_module: 129,
98
+ get_kernel_syms: 130,
99
+ quotactl: 131,
100
+ getpgid: 132,
101
+ fchdir: 133,
102
+ bdflush: 134,
103
+ sysfs: 135,
104
+ personality: 136,
105
+ afs_syscall: 137,
106
+ getdents: 141,
107
+ select: 142,
108
+ flock: 143,
109
+ msync: 144,
110
+ readv: 145,
111
+ writev: 146,
112
+ getsid: 147,
113
+ fdatasync: 148,
114
+ _sysctl: 149,
115
+ mlock: 150,
116
+ munlock: 151,
117
+ mlockall: 152,
118
+ munlockall: 153,
119
+ sched_setparam: 154,
120
+ sched_getparam: 155,
121
+ sched_setscheduler: 156,
122
+ sched_getscheduler: 157,
123
+ sched_yield: 158,
124
+ sched_get_priority_max: 159,
125
+ sched_get_priority_min: 160,
126
+ sched_rr_get_interval: 161,
127
+ nanosleep: 162,
128
+ mremap: 163,
129
+ query_module: 167,
130
+ poll: 168,
131
+ nfsservctl: 169,
132
+ prctl: 172,
133
+ rt_sigreturn: 173,
134
+ rt_sigaction: 174,
135
+ rt_sigprocmask: 175,
136
+ rt_sigpending: 176,
137
+ rt_sigtimedwait: 177,
138
+ rt_sigqueueinfo: 178,
139
+ rt_sigsuspend: 179,
140
+ pread64: 180,
141
+ pwrite64: 181,
142
+ getcwd: 183,
143
+ capget: 184,
144
+ capset: 185,
145
+ sigaltstack: 186,
146
+ sendfile: 187,
147
+ getpmsg: 188,
148
+ putpmsg: 189,
149
+ vfork: 190,
150
+ getrlimit: 191,
151
+ lchown: 198,
152
+ getuid: 199,
153
+ getgid: 200,
154
+ geteuid: 201,
155
+ getegid: 202,
156
+ setreuid: 203,
157
+ setregid: 204,
158
+ getgroups: 205,
159
+ setgroups: 206,
160
+ fchown: 207,
161
+ setresuid: 208,
162
+ getresuid: 209,
163
+ setresgid: 210,
164
+ getresgid: 211,
165
+ chown: 212,
166
+ setuid: 213,
167
+ setgid: 214,
168
+ setfsuid: 215,
169
+ setfsgid: 216,
170
+ pivot_root: 217,
171
+ mincore: 218,
172
+ madvise: 219,
173
+ getdents64: 220,
174
+ readahead: 222,
175
+ setxattr: 224,
176
+ lsetxattr: 225,
177
+ fsetxattr: 226,
178
+ getxattr: 227,
179
+ lgetxattr: 228,
180
+ fgetxattr: 229,
181
+ listxattr: 230,
182
+ llistxattr: 231,
183
+ flistxattr: 232,
184
+ removexattr: 233,
185
+ lremovexattr: 234,
186
+ fremovexattr: 235,
187
+ gettid: 236,
188
+ tkill: 237,
189
+ futex: 238,
190
+ sched_setaffinity: 239,
191
+ sched_getaffinity: 240,
192
+ tgkill: 241,
193
+ io_setup: 243,
194
+ io_destroy: 244,
195
+ io_getevents: 245,
196
+ io_submit: 246,
197
+ io_cancel: 247,
198
+ exit_group: 248,
199
+ epoll_create: 249,
200
+ epoll_ctl: 250,
201
+ epoll_wait: 251,
202
+ set_tid_address: 252,
203
+ fadvise64: 253,
204
+ timer_create: 254,
205
+ timer_settime: 255,
206
+ timer_gettime: 256,
207
+ timer_getoverrun: 257,
208
+ timer_delete: 258,
209
+ clock_settime: 259,
210
+ clock_gettime: 260,
211
+ clock_getres: 261,
212
+ clock_nanosleep: 262,
213
+ statfs64: 265,
214
+ fstatfs64: 266,
215
+ remap_file_pages: 267,
216
+ mbind: 268,
217
+ get_mempolicy: 269,
218
+ set_mempolicy: 270,
219
+ mq_open: 271,
220
+ mq_unlink: 272,
221
+ mq_timedsend: 273,
222
+ mq_timedreceive: 274,
223
+ mq_notify: 275,
224
+ mq_getsetattr: 276,
225
+ kexec_load: 277,
226
+ add_key: 278,
227
+ request_key: 279,
228
+ keyctl: 280,
229
+ waitid: 281,
230
+ ioprio_set: 282,
231
+ ioprio_get: 283,
232
+ inotify_init: 284,
233
+ inotify_add_watch: 285,
234
+ inotify_rm_watch: 286,
235
+ migrate_pages: 287,
236
+ openat: 288,
237
+ mkdirat: 289,
238
+ mknodat: 290,
239
+ fchownat: 291,
240
+ futimesat: 292,
241
+ newfstatat: 293,
242
+ unlinkat: 294,
243
+ renameat: 295,
244
+ linkat: 296,
245
+ symlinkat: 297,
246
+ readlinkat: 298,
247
+ fchmodat: 299,
248
+ faccessat: 300,
249
+ pselect6: 301,
250
+ ppoll: 302,
251
+ unshare: 303,
252
+ set_robust_list: 304,
253
+ get_robust_list: 305,
254
+ splice: 306,
255
+ sync_file_range: 307,
256
+ tee: 308,
257
+ vmsplice: 309,
258
+ move_pages: 310,
259
+ getcpu: 311,
260
+ epoll_pwait: 312,
261
+ utimes: 313,
262
+ fallocate: 314,
263
+ utimensat: 315,
264
+ signalfd: 316,
265
+ timerfd: 317,
266
+ eventfd: 318,
267
+ timerfd_create: 319,
268
+ timerfd_settime: 320,
269
+ timerfd_gettime: 321,
270
+ signalfd4: 322,
271
+ eventfd2: 323,
272
+ inotify_init1: 324,
273
+ pipe2: 325,
274
+ dup3: 326,
275
+ epoll_create1: 327,
276
+ preadv: 328,
277
+ pwritev: 329,
278
+ rt_tgsigqueueinfo: 330,
279
+ perf_event_open: 331,
280
+ fanotify_init: 332,
281
+ fanotify_mark: 333,
282
+ prlimit64: 334,
283
+ name_to_handle_at: 335,
284
+ open_by_handle_at: 336,
285
+ clock_adjtime: 337,
286
+ syncfs: 338,
287
+ setns: 339,
288
+ process_vm_readv: 340,
289
+ process_vm_writev: 341,
290
+ s390_runtime_instr: 342,
291
+ kcmp: 343,
292
+ finit_module: 344,
293
+ sched_setattr: 345,
294
+ sched_getattr: 346,
295
+ renameat2: 347,
296
+ seccomp: 348,
297
+ getrandom: 349,
298
+ memfd_create: 350,
299
+ bpf: 351,
300
+ s390_pci_mmio_write: 352,
301
+ s390_pci_mmio_read: 353,
302
+ execveat: 354,
303
+ userfaultfd: 355,
304
+ membarrier: 356,
305
+ recvmmsg: 357,
306
+ sendmmsg: 358,
307
+ socket: 359,
308
+ socketpair: 360,
309
+ bind: 361,
310
+ connect: 362,
311
+ listen: 363,
312
+ accept4: 364,
313
+ getsockopt: 365,
314
+ setsockopt: 366,
315
+ getsockname: 367,
316
+ getpeername: 368,
317
+ sendto: 369,
318
+ sendmsg: 370,
319
+ recvfrom: 371,
320
+ recvmsg: 372,
321
+ shutdown: 373,
322
+ mlock2: 374,
323
+ copy_file_range: 375,
324
+ preadv2: 376,
325
+ pwritev2: 377,
326
+ s390_guarded_storage: 378,
327
+ statx: 379,
328
+ s390_sthyi: 380,
329
+ kexec_file_load: 381,
330
+ io_pgetevents: 382,
331
+ rseq: 383,
332
+ pkey_mprotect: 384,
333
+ pkey_alloc: 385,
334
+ pkey_free: 386,
335
+ semtimedop: 392,
336
+ semget: 393,
337
+ semctl: 394,
338
+ shmget: 395,
339
+ shmctl: 396,
340
+ shmat: 397,
341
+ shmdt: 398,
342
+ msgget: 399,
343
+ msgsnd: 400,
344
+ msgrcv: 401,
345
+ msgctl: 402,
346
+ pidfd_send_signal: 424,
347
+ io_uring_setup: 425,
348
+ io_uring_enter: 426,
349
+ io_uring_register: 427,
350
+ open_tree: 428,
351
+ move_mount: 429,
352
+ fsopen: 430,
353
+ fsconfig: 431,
354
+ fsmount: 432,
355
+ fspick: 433,
356
+ pidfd_open: 434,
357
+ clone3: 435,
358
+ close_range: 436,
359
+ openat2: 437,
360
+ pidfd_getfd: 438,
361
+ faccessat2: 439,
362
+ process_madvise: 440,
363
+ epoll_pwait2: 441,
364
+ mount_setattr: 442
365
+ }
@@ -58,7 +58,7 @@ module SeccompTools
58
58
  # Value to be set to +reg/mem+.
59
59
  # @param [Array<Integer?>] known_data
60
60
  # Records which index of data is known.
61
- # It's used for tracking if the syscall number is known, which can be used to display argument names of the
61
+ # It's used for tracking when the syscall number is known, which can be used to display argument names of the
62
62
  # syscall.
63
63
  def initialize(values: {}, known_data: [])
64
64
  @values = values
@@ -104,7 +104,7 @@ module SeccompTools
104
104
  # Returns the object itself.
105
105
  def eql!(val)
106
106
  tap do
107
- # only cares if A is fetched from data
107
+ # only cares when A is fetched from data
108
108
  next unless a.data?
109
109
  next known_data[a.val] = val if val.is_a?(Integer)
110
110
  # A == X, we can handle these cases:
@@ -7,20 +7,22 @@ require 'seccomp-tools/disasm/context'
7
7
  require 'seccomp-tools/util'
8
8
 
9
9
  module SeccompTools
10
- # Disassembler of seccomp bpf.
10
+ # Disassembler of seccomp BPF.
11
11
  module Disasm
12
12
  module_function
13
13
 
14
- # Disassemble bpf codes.
14
+ # Disassemble BPF codes.
15
15
  # @param [String] raw
16
- # The raw bpf bytes.
16
+ # The raw BPF bytes.
17
17
  # @param [Symbol] arch
18
18
  # Architecture.
19
- def disasm(raw, arch: nil)
19
+ # @param [Boolean] display_bpf
20
+ # @param [Boolean] arg_infer
21
+ def disasm(raw, arch: nil, display_bpf: true, arg_infer: true)
20
22
  codes = to_bpf(raw, arch)
21
23
  contexts = Array.new(codes.size) { Set.new }
22
24
  contexts[0].add(Context.new)
23
- # all we care is if A is exactly one of data[*]
25
+ # all we care is whether A is data[*]
24
26
  dis = codes.zip(contexts).map do |code, ctxs|
25
27
  ctxs.each do |ctx|
26
28
  code.branch(ctx) do |pc, c|
@@ -28,15 +30,20 @@ module SeccompTools
28
30
  end
29
31
  end
30
32
  code.contexts = ctxs
31
- code.disasm
33
+ code.disasm(code: display_bpf, arg_infer: arg_infer)
32
34
  end.join("\n")
33
- <<-EOS + dis + "\n"
35
+ if display_bpf
36
+ <<-EOS
34
37
  line CODE JT JF K
35
38
  =================================
36
- EOS
39
+ #{dis}
40
+ EOS
41
+ else
42
+ "#{dis}\n"
43
+ end
37
44
  end
38
45
 
39
- # Convert raw bpf string to array of {BPF}.
46
+ # Convert raw BPF string to array of {BPF}.
40
47
  # @param [String] raw
41
48
  # @param [Symbol] arch
42
49
  # @return [Array<BPF>]
@@ -1,13 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'os'
4
+
3
5
  require 'seccomp-tools/logger'
4
- require 'seccomp-tools/ptrace'
6
+ require 'seccomp-tools/ptrace' if OS.linux?
5
7
  require 'seccomp-tools/syscall'
6
8
 
7
9
  module SeccompTools
8
10
  # Dump seccomp-bpf using ptrace of binary.
9
- # Currently only support x86_64.
10
11
  module Dumper
12
+ # Whether the dumper is supported.
13
+ # Dumper works based on ptrace, so we need the platform be Linux.
14
+ SUPPORTED = OS.linux?
15
+
11
16
  module_function
12
17
 
13
18
  # Main bpf dump function.
@@ -35,6 +40,8 @@ module SeccompTools
35
40
  # @todo
36
41
  # +timeout+ option.
37
42
  def dump(*args, limit: 1, &block)
43
+ return [] unless SUPPORTED
44
+
38
45
  pid = fork { handle_child(*args) }
39
46
  Handler.new(pid).handle(limit, &block)
40
47
  end
@@ -58,7 +65,7 @@ module SeccompTools
58
65
  # @yieldparam [String] bpf
59
66
  # Seccomp bpf in raw bytes.
60
67
  # @yieldparam [Symbol] arch
61
- # Architecture, either :i386 or :amd64.
68
+ # Architecture. See {SeccompTools::Syscall::ABI} for supported architectures.
62
69
  # @return [Array<Object>, Array<String>]
63
70
  # Return the block returned. If block is not given, array of raw bytes will be returned.
64
71
  def handle(limit, &block)
@@ -164,6 +171,8 @@ module SeccompTools
164
171
  # dump_by_pid(pid2, 1) { |c| c[0, 10] }
165
172
  # #=> [" \x00\x00\x00\x00\x00\x00\x00\x15\x00"]
166
173
  def dump_by_pid(pid, limit, &block)
174
+ return [] unless SUPPORTED
175
+
167
176
  collect = []
168
177
  Ptrace.attach_and_wait(pid)
169
178
  begin
@@ -7,7 +7,7 @@ module SeccompTools
7
7
  class Emulator
8
8
  # Instantiate a {Emulator} object.
9
9
  #
10
- # All parameters except +instructions+ are optional, while a warning will be shown if unset data being accessed.
10
+ # All parameters except +instructions+ are optional. A warning is shown when uninitialized data is accessed.
11
11
  # @param [Array<Instruction::Base>] instructions
12
12
  # @param [Integer] sys_nr
13
13
  # Syscall number.
@@ -15,8 +15,8 @@ module SeccompTools
15
15
  # Syscall arguments
16
16
  # @param [Integer] instruction_pointer
17
17
  # Program counter address when this syscall invoked.
18
- # @param [Symbol] arch
19
- # If not given, use system architecture as default.
18
+ # @param [Symbol?] arch
19
+ # System architecture is used when this parameter is not provided.
20
20
  #
21
21
  # See {SeccompTools::Util.supported_archs} for list of supported architectures.
22
22
  def initialize(instructions, sys_nr: nil, args: [], instruction_pointer: nil, arch: nil)
@@ -28,7 +28,7 @@ module SeccompTools
28
28
  end
29
29
 
30
30
  # Run emulation!
31
- # @return [Hash{Symbol, Integer => Integer}]
31
+ # @return [{Symbol, Integer => Integer}]
32
32
  def run
33
33
  @values = { pc: 0, a: 0, x: 0 }
34
34
  loop do
@@ -58,11 +58,7 @@ module SeccompTools
58
58
  end
59
59
 
60
60
  def audit(arch)
61
- type = case arch
62
- when :amd64 then 'ARCH_X86_64'
63
- when :i386 then 'ARCH_I386'
64
- end
65
- Const::Audit::ARCH[type]
61
+ Const::Audit::ARCH[Const::Audit::ARCH_NAME[arch]]
66
62
  end
67
63
 
68
64
  def ret(num)
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SeccompTools
4
+ # Base error class.
5
+ class Error < StandardError
6
+ end
7
+
8
+ # Raised when unrecognized token(s) are found on compiling seccomp assembly.
9
+ class UnrecognizedTokenError < Error
10
+ end
11
+
12
+ # Raised when a referred label is defined no where on compiling seccomp assembly.
13
+ class UndefinedLabelError < Error
14
+ end
15
+
16
+ # Raised on RACC parsing error when compiling seccomp assembly.
17
+ class ParseError < Error
18
+ end
19
+
20
+ # Raised when a jump expression goes backward on compiling seccomp assembly.
21
+ class BackwardJumpError < Error
22
+ end
23
+
24
+ # Raised when a label is defined more than once on compiling seccomp assembly.
25
+ class DuplicateLabelError < Error
26
+ end
27
+
28
+ # Raised when a jump is longer than supported distance.
29
+ class LongJumpError < Error
30
+ end
31
+ end
@@ -62,7 +62,7 @@ module SeccompTools
62
62
 
63
63
  case op
64
64
  when :lsh, :rsh then src.to_s
65
- else '0x' + src.to_s(16)
65
+ else "0x#{src.to_s(16)}"
66
66
  end
67
67
  end
68
68
 
@@ -47,7 +47,7 @@ module SeccompTools
47
47
 
48
48
  private
49
49
 
50
- %i(code jt jf k arch line contexts).each do |sym|
50
+ %i(code jt jf k arch line contexts show_arg_infer?).each do |sym|
51
51
  define_method(sym) do
52
52
  @bpf.__send__(sym)
53
53
  end
@@ -16,9 +16,9 @@ module SeccompTools
16
16
  # otherwise => if () goto jt; else goto jf;
17
17
  return '/* no-op */' if jt.zero? && jf.zero?
18
18
  return goto(jt) if jt == jf
19
- return if_str(true) + goto(jf) if jt.zero?
19
+ return if_str(neg: true) + goto(jf) if jt.zero?
20
20
 
21
- if_str + goto(jt) + (jf.zero? ? '' : ' else ' + goto(jf))
21
+ if_str + goto(jt) + (jf.zero? ? '' : " else #{goto(jf)}")
22
22
  end
23
23
 
24
24
  # See {Instruction::Base#symbolize}.
@@ -64,14 +64,32 @@ module SeccompTools
64
64
  a = a[0]
65
65
  return k.to_s unless a.data?
66
66
 
67
- hex = '0x' + k.to_s(16)
67
+ hex = "0x#{k.to_s(16)}"
68
68
  case a.val
69
- when 0 then Util.colorize(Const::Syscall.const_get(arch.upcase.to_sym).invert[k] || hex, t: :syscall)
69
+ # interpret as syscalls only if it's an equality test
70
+ when 0 then Util.colorize(jop == :== ? sysname_by_k || hex : hex, t: :syscall)
70
71
  when 4 then Util.colorize(Const::Audit::ARCH.invert[k] || hex, t: :arch)
71
72
  else hex
72
73
  end
73
74
  end
74
75
 
76
+ def sysname_by_k
77
+ a = infer_arch || arch
78
+ name = Const::Syscall.const_get(a.upcase.to_sym).invert[k]
79
+ return name if name.nil?
80
+
81
+ a == arch ? name : "#{a}.#{name}"
82
+ end
83
+
84
+ # Infers the architecture from context.
85
+ # @return [Symbol?]
86
+ def infer_arch
87
+ arches = contexts.map { |ctx| ctx.known_data[4] }.uniq
88
+ return nil unless arches.size == 1 && !arches.first.nil?
89
+
90
+ Const::Audit::ARCH_NAME.invert[Const::Audit::ARCH.invert[arches.first]]
91
+ end
92
+
75
93
  def src
76
94
  SRC.invert[code & 8] == :x ? :x : k
77
95
  end
@@ -84,15 +102,15 @@ module SeccompTools
84
102
  line + off + 1
85
103
  end
86
104
 
87
- def if_str(neg = false)
105
+ def if_str(neg: false)
88
106
  return "if (A #{jop} #{src_str}) " unless neg
89
107
  return "if (!(A & #{src_str})) " if jop == :&
90
108
 
91
- op = case jop
92
- when :>= then :<
93
- when :> then :<=
94
- when :== then :!=
95
- end
109
+ op = {
110
+ :>= => :<,
111
+ :> => :<=,
112
+ :== => :!=
113
+ }[jop]
96
114
  "if (A #{op} #{src_str}) "
97
115
  end
98
116
  end
@@ -10,7 +10,7 @@ module SeccompTools
10
10
  class LD < Base
11
11
  # Decompile instruction.
12
12
  def decompile
13
- ret = reg + ' = '
13
+ ret = "#{reg} = "
14
14
  _, _reg, type = symbolize
15
15
  return ret + type[:val].to_s if type[:rel] == :immi
16
16
  return ret + "mem[#{type[:val]}]" if type[:rel] == :mem
@@ -78,8 +78,10 @@ module SeccompTools
78
78
  end
79
79
 
80
80
  def args_name(idx)
81
- sys_nrs = contexts.map { |ctx| ctx.known_data[0] }.uniq
82
81
  default = idx.even? ? "args[#{idx / 2}]" : "args[#{idx / 2}] >> 32"
82
+ return default unless show_arg_infer?
83
+
84
+ sys_nrs = contexts.map { |ctx| ctx.known_data[0] }.uniq
83
85
  return default if sys_nrs.size != 1 || sys_nrs.first.nil?
84
86
 
85
87
  sys = Const::Syscall.const_get(arch.upcase.to_sym).invert[sys_nrs.first]
@@ -88,7 +90,7 @@ module SeccompTools
88
90
 
89
91
  comment = "# #{sys}(#{args.join(', ')})"
90
92
  arg_name = Util.colorize(args[idx / 2], t: :args)
91
- (idx.even? ? arg_name : "#{arg_name} >> 32") + ' ' + Util.colorize(comment, t: :gray)
93
+ "#{idx.even? ? arg_name : "#{arg_name} >> 32"} #{Util.colorize(comment, t: :gray)}"
92
94
  end
93
95
  end
94
96
  end