seccomp-tools 1.1.0 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +112 -30
- data/bin/seccomp-tools +1 -0
- data/ext/ptrace/extconf.rb +2 -0
- data/ext/ptrace/ptrace.c +107 -5
- data/lib/seccomp-tools.rb +5 -0
- data/lib/seccomp-tools/asm/asm.rb +5 -2
- data/lib/seccomp-tools/asm/compiler.rb +96 -18
- data/lib/seccomp-tools/asm/tokenizer.rb +25 -8
- data/lib/seccomp-tools/bpf.rb +7 -4
- data/lib/seccomp-tools/cli/asm.rb +16 -6
- data/lib/seccomp-tools/cli/base.rb +10 -4
- data/lib/seccomp-tools/cli/cli.rb +9 -6
- data/lib/seccomp-tools/cli/disasm.rb +6 -2
- data/lib/seccomp-tools/cli/dump.rb +37 -6
- data/lib/seccomp-tools/cli/emu.rb +41 -22
- data/lib/seccomp-tools/const.rb +47 -16
- data/lib/seccomp-tools/consts/sys_arg.rb +432 -0
- data/lib/seccomp-tools/consts/sys_nr/aarch64.rb +284 -0
- data/lib/seccomp-tools/consts/{amd64.rb → sys_nr/amd64.rb} +6 -1
- data/lib/seccomp-tools/consts/{i386.rb → sys_nr/i386.rb} +18 -15
- data/lib/seccomp-tools/disasm/context.rb +125 -34
- data/lib/seccomp-tools/disasm/disasm.rb +5 -2
- data/lib/seccomp-tools/dumper.rb +75 -8
- data/lib/seccomp-tools/emulator.rb +19 -8
- data/lib/seccomp-tools/instruction/alu.rb +7 -2
- data/lib/seccomp-tools/instruction/base.rb +5 -3
- data/lib/seccomp-tools/instruction/instruction.rb +2 -0
- data/lib/seccomp-tools/instruction/jmp.rb +28 -14
- data/lib/seccomp-tools/instruction/ld.rb +28 -12
- data/lib/seccomp-tools/instruction/ldx.rb +2 -0
- data/lib/seccomp-tools/instruction/misc.rb +2 -0
- data/lib/seccomp-tools/instruction/ret.rb +14 -2
- data/lib/seccomp-tools/instruction/st.rb +4 -2
- data/lib/seccomp-tools/instruction/stx.rb +2 -0
- data/lib/seccomp-tools/logger.rb +40 -0
- data/lib/seccomp-tools/syscall.rb +24 -13
- data/lib/seccomp-tools/templates/asm.amd64.asm +26 -0
- data/lib/seccomp-tools/templates/asm.c +17 -0
- data/lib/seccomp-tools/templates/asm.i386.asm +33 -0
- data/lib/seccomp-tools/util.rb +24 -3
- data/lib/seccomp-tools/version.rb +3 -1
- metadata +51 -44
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'set'
|
2
4
|
|
3
5
|
require 'seccomp-tools/bpf'
|
@@ -28,10 +30,11 @@ module SeccompTools
|
|
28
30
|
code.contexts = ctxs
|
29
31
|
code.disasm
|
30
32
|
end.join("\n")
|
31
|
-
|
33
|
+
<<-EOS
|
32
34
|
line CODE JT JF K
|
33
35
|
=================================
|
34
|
-
|
36
|
+
#{dis}
|
37
|
+
EOS
|
35
38
|
end
|
36
39
|
|
37
40
|
# Convert raw bpf string to array of {BPF}.
|
data/lib/seccomp-tools/dumper.rb
CHANGED
@@ -1,10 +1,19 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'os'
|
4
|
+
|
5
|
+
require 'seccomp-tools/logger'
|
6
|
+
require 'seccomp-tools/ptrace' if OS.linux?
|
2
7
|
require 'seccomp-tools/syscall'
|
3
8
|
|
4
9
|
module SeccompTools
|
5
10
|
# Dump seccomp-bpf using ptrace of binary.
|
6
|
-
# Currently only support x86_64.
|
11
|
+
# Currently only support x86_64 and aarch64.
|
7
12
|
module Dumper
|
13
|
+
# Whether the dumper is supported.
|
14
|
+
# Dumper works based on ptrace, so we need the platform be Linux.
|
15
|
+
SUPPORTED = OS.linux?
|
16
|
+
|
8
17
|
module_function
|
9
18
|
|
10
19
|
# Main bpf dump function.
|
@@ -32,6 +41,8 @@ module SeccompTools
|
|
32
41
|
# @todo
|
33
42
|
# +timeout+ option.
|
34
43
|
def dump(*args, limit: 1, &block)
|
44
|
+
return [] unless SUPPORTED
|
45
|
+
|
35
46
|
pid = fork { handle_child(*args) }
|
36
47
|
Handler.new(pid).handle(limit, &block)
|
37
48
|
end
|
@@ -54,6 +65,8 @@ module SeccompTools
|
|
54
65
|
# Child will be killed when number of calling +prctl(SET_SECCOMP)+ reaches +limit+.
|
55
66
|
# @yieldparam [String] bpf
|
56
67
|
# Seccomp bpf in raw bytes.
|
68
|
+
# @yieldparam [Symbol] arch
|
69
|
+
# Architecture, either :i386 or :amd64.
|
57
70
|
# @return [Array<Object>, Array<String>]
|
58
71
|
# Return the block returned. If block is not given, array of raw bytes will be returned.
|
59
72
|
def handle(limit, &block)
|
@@ -74,7 +87,8 @@ module SeccompTools
|
|
74
87
|
end
|
75
88
|
!limit.zero?
|
76
89
|
end
|
77
|
-
syscalls.
|
90
|
+
syscalls.each_key { |cpid| Process.kill('KILL', cpid) if alive?(cpid) }
|
91
|
+
Process.waitall
|
78
92
|
collect
|
79
93
|
end
|
80
94
|
|
@@ -95,9 +109,9 @@ module SeccompTools
|
|
95
109
|
cont = yield(child)
|
96
110
|
end
|
97
111
|
Ptrace.syscall(child, 0, 0) unless status.exited?
|
98
|
-
|
112
|
+
cont
|
99
113
|
rescue Errno::ECHILD
|
100
|
-
|
114
|
+
false
|
101
115
|
end
|
102
116
|
|
103
117
|
# @return [SeccompTools::Syscall]
|
@@ -119,11 +133,64 @@ module SeccompTools
|
|
119
133
|
def handle_child(*args)
|
120
134
|
Ptrace.traceme_and_stop
|
121
135
|
exec(*args)
|
122
|
-
rescue # exec fail
|
123
|
-
|
124
|
-
$stderr.puts("Failed to execute #{args.join(' ')}")
|
136
|
+
rescue # rubocop:disable Style/RescueStandardError # exec fail
|
137
|
+
Logger.error("Failed to execute #{args.join(' ')}")
|
125
138
|
exit(1)
|
126
139
|
end
|
127
140
|
end
|
141
|
+
|
142
|
+
# Dump installed seccomp-bpf of an existing process using PTRACE_SECCOMP_GET_FILTER.
|
143
|
+
#
|
144
|
+
# Dump the installed seccomp-bpf from a running process. This is achieved by the ptrace command
|
145
|
+
# PTRACE_SECCOMP_GET_FILTER, which needs CAP_SYS_ADMIN capability.
|
146
|
+
#
|
147
|
+
# @param [Integer] pid
|
148
|
+
# Target process identifier.
|
149
|
+
# @param [Integer] limit
|
150
|
+
# Number of filters to dump. Negative number for unlimited.
|
151
|
+
# @yieldparam [String] bpf
|
152
|
+
# Seccomp bpf in raw bytes.
|
153
|
+
# @yieldparam [Symbol] arch
|
154
|
+
# Architecture of the target process (always nil right now).
|
155
|
+
# @return [Array<Object>, Array<String>]
|
156
|
+
# Return the block returned. If block is not given, array of raw bytes will be returned.
|
157
|
+
# @raise [Errno::ESRCH]
|
158
|
+
# Raises when the target process does not exist.
|
159
|
+
# @raise [Errno::EPERM]
|
160
|
+
# Raises the error if not allowed to attach.
|
161
|
+
# @raise [Errno::EACCES]
|
162
|
+
# Raises the error if not allowed to dump (e.g. no CAP_SYS_ADMIN).
|
163
|
+
# @example
|
164
|
+
# pid1 = Process.spawn('sleep inf')
|
165
|
+
# dump_by_pid(pid1, 1)
|
166
|
+
# # empty because there is no seccomp installed
|
167
|
+
# #=> []
|
168
|
+
# @example
|
169
|
+
# pid2 = Process.spawn('spec/binary/twctf-2016-diary')
|
170
|
+
# # give it some time to install the filter
|
171
|
+
# sleep(1)
|
172
|
+
# dump_by_pid(pid2, 1) { |c| c[0, 10] }
|
173
|
+
# #=> [" \x00\x00\x00\x00\x00\x00\x00\x15\x00"]
|
174
|
+
def dump_by_pid(pid, limit, &block)
|
175
|
+
return [] unless SUPPORTED
|
176
|
+
|
177
|
+
collect = []
|
178
|
+
Ptrace.attach_and_wait(pid)
|
179
|
+
begin
|
180
|
+
i = 0
|
181
|
+
while limit.negative? || i < limit
|
182
|
+
begin
|
183
|
+
bpf = Ptrace.seccomp_get_filter(pid, i)
|
184
|
+
rescue Errno::ENOENT, Errno::EINVAL
|
185
|
+
break
|
186
|
+
end
|
187
|
+
collect << (block.nil? ? bpf : yield(bpf, nil))
|
188
|
+
i += 1
|
189
|
+
end
|
190
|
+
ensure
|
191
|
+
Ptrace.detach(pid)
|
192
|
+
end
|
193
|
+
collect
|
194
|
+
end
|
128
195
|
end
|
129
196
|
end
|
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'seccomp-tools/const'
|
2
4
|
|
3
5
|
module SeccompTools
|
4
|
-
# For
|
6
|
+
# For emulating seccomp.
|
5
7
|
class Emulator
|
6
8
|
# Instantiate a {Emulator} object.
|
7
9
|
#
|
@@ -31,6 +33,7 @@ module SeccompTools
|
|
31
33
|
@values = { pc: 0, a: 0, x: 0 }
|
32
34
|
loop do
|
33
35
|
break if @values[:ret] # break when returned
|
36
|
+
|
34
37
|
yield(@values) if block_given?
|
35
38
|
inst = @instructions[pc]
|
36
39
|
op, *args = inst.symbolize
|
@@ -39,7 +42,7 @@ module SeccompTools
|
|
39
42
|
when :ld then ld(args[0], args[1]) # ld/ldx
|
40
43
|
when :st then st(args[0], args[1]) # st/stx
|
41
44
|
when :jmp then jmp(args[0]) # directly jmp
|
42
|
-
when :cmp then cmp(*args[0, 4]) # jmp with
|
45
|
+
when :cmp then cmp(*args[0, 4]) # jmp with comparison
|
43
46
|
when :alu then alu(args[0], args[1]) # alu
|
44
47
|
when :misc then misc(args[0]) # misc: txa/tax
|
45
48
|
end
|
@@ -55,10 +58,11 @@ module SeccompTools
|
|
55
58
|
end
|
56
59
|
|
57
60
|
def audit(arch)
|
58
|
-
type =
|
59
|
-
|
60
|
-
|
61
|
-
|
61
|
+
type = {
|
62
|
+
amd64: 'ARCH_X86_64',
|
63
|
+
i386: 'ARCH_I386',
|
64
|
+
aarch64: 'ARCH_AARCH64'
|
65
|
+
}[arch]
|
62
66
|
Const::Audit::ARCH[type]
|
63
67
|
end
|
64
68
|
|
@@ -79,6 +83,7 @@ module SeccompTools
|
|
79
83
|
|
80
84
|
def st(reg, index)
|
81
85
|
raise IndexError, "Expect 0 <= index < 16, got: #{index}" unless index.between?(0, 15)
|
86
|
+
|
82
87
|
set(:mem, index, get(reg))
|
83
88
|
end
|
84
89
|
|
@@ -86,10 +91,11 @@ module SeccompTools
|
|
86
91
|
set(:pc, get(:pc) + k + 1)
|
87
92
|
end
|
88
93
|
|
94
|
+
# Emulates cmp instruction.
|
89
95
|
def cmp(op, src, jt, jf)
|
90
96
|
src = get(:x) if src == :x
|
91
97
|
a = get(:a)
|
92
|
-
val = a.
|
98
|
+
val = a.__send__(op, src)
|
93
99
|
val = (val != 0) if val.is_a?(Integer) # handle & operator
|
94
100
|
j = val ? jt : jf
|
95
101
|
set(:pc, get(:pc) + j + 1)
|
@@ -100,7 +106,7 @@ module SeccompTools
|
|
100
106
|
set(:a, 2**32 - get(:a))
|
101
107
|
else
|
102
108
|
src = get(:x) if src == :x
|
103
|
-
set(:a, get(:a).
|
109
|
+
set(:a, get(:a).__send__(op, src))
|
104
110
|
end
|
105
111
|
end
|
106
112
|
|
@@ -115,10 +121,12 @@ module SeccompTools
|
|
115
121
|
if arg.size == 1
|
116
122
|
arg = arg.first
|
117
123
|
raise ArgumentError, "Invalid #{arg}" unless %i[a x pc ret].include?(arg)
|
124
|
+
|
118
125
|
@values[arg] = val & 0xffffffff
|
119
126
|
else
|
120
127
|
raise ArgumentError, arg.to_s unless arg.first == :mem
|
121
128
|
raise IndexError, "Invalid index: #{arg[1]}" unless arg[1].between?(0, 15)
|
129
|
+
|
122
130
|
@values[arg[1]] = val & 0xffffffff
|
123
131
|
end
|
124
132
|
end
|
@@ -127,15 +135,18 @@ module SeccompTools
|
|
127
135
|
if arg.size == 1
|
128
136
|
arg = arg.first
|
129
137
|
raise ArgumentError, "Invalid #{arg}" unless %i[a x pc ret].include?(arg)
|
138
|
+
|
130
139
|
undefined(arg.upcase) if @values[arg].nil?
|
131
140
|
return @values[arg]
|
132
141
|
end
|
133
142
|
return @values[arg[1]] if arg.first == :mem
|
143
|
+
|
134
144
|
data_of(arg[1])
|
135
145
|
end
|
136
146
|
|
137
147
|
def data_of(index)
|
138
148
|
raise IndexError, "Invalid index: #{index}" unless (index & 3).zero? && index.between?(0, 63)
|
149
|
+
|
139
150
|
index /= 4
|
140
151
|
case index
|
141
152
|
when 0 then @sys_nr || undefined('sys_number')
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'seccomp-tools/instruction/base'
|
2
4
|
|
3
5
|
module SeccompTools
|
@@ -21,6 +23,7 @@ module SeccompTools
|
|
21
23
|
# Decompile instruction.
|
22
24
|
def decompile
|
23
25
|
return 'A = -A' if op == :neg
|
26
|
+
|
24
27
|
"A #{op_sym}= #{src_str}"
|
25
28
|
end
|
26
29
|
|
@@ -28,6 +31,7 @@ module SeccompTools
|
|
28
31
|
# @return [[:alu, Symbol, (:x, Integer, nil)]]
|
29
32
|
def symbolize
|
30
33
|
return [:alu, :neg, nil] if op == :neg
|
34
|
+
|
31
35
|
[:alu, op_sym, src]
|
32
36
|
end
|
33
37
|
|
@@ -37,7 +41,7 @@ module SeccompTools
|
|
37
41
|
# @return [Array<(Integer, Context)>]
|
38
42
|
def branch(context)
|
39
43
|
ctx = context.dup
|
40
|
-
ctx[:a] =
|
44
|
+
ctx[:a] = Disasm::Context::Value.new
|
41
45
|
[[line + 1, ctx]]
|
42
46
|
end
|
43
47
|
|
@@ -55,9 +59,10 @@ module SeccompTools
|
|
55
59
|
|
56
60
|
def src_str
|
57
61
|
return 'X' if src == :x
|
62
|
+
|
58
63
|
case op
|
59
64
|
when :lsh, :rsh then src.to_s
|
60
|
-
else
|
65
|
+
else "0x#{src.to_s(16)}"
|
61
66
|
end
|
62
67
|
end
|
63
68
|
|
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'seccomp-tools/const'
|
2
4
|
|
3
5
|
module SeccompTools
|
4
6
|
# For instructions' class.
|
5
7
|
module Instruction
|
6
|
-
# Base class
|
8
|
+
# Base class of instructions.
|
7
9
|
class Base
|
8
10
|
include SeccompTools::Const::BPF
|
9
11
|
|
@@ -22,7 +24,7 @@ module SeccompTools
|
|
22
24
|
raise ArgumentError, "Line #{line} is invalid: #{msg}"
|
23
25
|
end
|
24
26
|
|
25
|
-
#
|
27
|
+
# Returns the possible branches after executing this instruction.
|
26
28
|
# @param [Context] _context
|
27
29
|
# Current context.
|
28
30
|
# @return [Array<(Integer, Context)>]
|
@@ -47,7 +49,7 @@ module SeccompTools
|
|
47
49
|
|
48
50
|
%i(code jt jf k arch line contexts).each do |sym|
|
49
51
|
define_method(sym) do
|
50
|
-
@bpf.
|
52
|
+
@bpf.__send__(sym)
|
51
53
|
end
|
52
54
|
end
|
53
55
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'seccomp-tools/const'
|
2
4
|
require 'seccomp-tools/instruction/base'
|
3
5
|
|
@@ -9,20 +11,21 @@ module SeccompTools
|
|
9
11
|
def decompile
|
10
12
|
return goto(k) if jop == :none
|
11
13
|
# if jt == 0 && jf == 0 => no-op # should not happen
|
12
|
-
# jt == 0 => if(!) goto jf
|
14
|
+
# jt == 0 => if(!) goto jf;
|
13
15
|
# jf == 0 => if() goto jt;
|
14
16
|
# otherwise => if () goto jt; else goto jf;
|
15
17
|
return '/* no-op */' if jt.zero? && jf.zero?
|
16
18
|
return goto(jt) if jt == jf
|
17
|
-
return if_str
|
18
|
-
|
19
|
-
if_str(
|
19
|
+
return if_str(neg: true) + goto(jf) if jt.zero?
|
20
|
+
|
21
|
+
if_str + goto(jt) + (jf.zero? ? '' : " else #{goto(jf)}")
|
20
22
|
end
|
21
23
|
|
22
24
|
# See {Instruction::Base#symbolize}.
|
23
25
|
# @return [[:cmp, Symbol, (:x, Integer), Integer, Integer], [:jmp, Integer]]
|
24
26
|
def symbolize
|
25
27
|
return [:jmp, k] if jop == :none
|
28
|
+
|
26
29
|
[:cmp, jop, src, jt, jf]
|
27
30
|
end
|
28
31
|
|
@@ -33,6 +36,8 @@ module SeccompTools
|
|
33
36
|
def branch(context)
|
34
37
|
return [[at(k), context]] if jop == :none
|
35
38
|
return [[at(jt), context]] if jt == jf
|
39
|
+
return [[at(jt), context.dup.eql!(src)], [at(jf), context]] if jop == :==
|
40
|
+
|
36
41
|
[[at(jt), context], [at(jf), context]]
|
37
42
|
end
|
38
43
|
|
@@ -51,19 +56,27 @@ module SeccompTools
|
|
51
56
|
|
52
57
|
def src_str
|
53
58
|
return 'X' if src == :x
|
59
|
+
|
54
60
|
# if A in all contexts are same
|
55
61
|
a = contexts.map(&:a).uniq
|
56
62
|
return k.to_s if a.size != 1
|
63
|
+
|
57
64
|
a = a[0]
|
58
|
-
return k.to_s
|
59
|
-
|
60
|
-
|
61
|
-
|
65
|
+
return k.to_s unless a.data?
|
66
|
+
|
67
|
+
hex = "0x#{k.to_s(16)}"
|
68
|
+
case a.val
|
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)
|
62
71
|
when 4 then Util.colorize(Const::Audit::ARCH.invert[k] || hex, t: :arch)
|
63
72
|
else hex
|
64
73
|
end
|
65
74
|
end
|
66
75
|
|
76
|
+
def sysname_by_k
|
77
|
+
Const::Syscall.const_get(arch.upcase.to_sym).invert[k]
|
78
|
+
end
|
79
|
+
|
67
80
|
def src
|
68
81
|
SRC.invert[code & 8] == :x ? :x : k
|
69
82
|
end
|
@@ -76,14 +89,15 @@ module SeccompTools
|
|
76
89
|
line + off + 1
|
77
90
|
end
|
78
91
|
|
79
|
-
def if_str(neg
|
92
|
+
def if_str(neg: false)
|
80
93
|
return "if (A #{jop} #{src_str}) " unless neg
|
81
94
|
return "if (!(A & #{src_str})) " if jop == :&
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
95
|
+
|
96
|
+
op = {
|
97
|
+
:>= => :<,
|
98
|
+
:> => :<=,
|
99
|
+
:== => :!=
|
100
|
+
}[jop]
|
87
101
|
"if (A #{op} #{src_str}) "
|
88
102
|
end
|
89
103
|
end
|
@@ -1,4 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'seccomp-tools/const'
|
1
4
|
require 'seccomp-tools/instruction/base'
|
5
|
+
require 'seccomp-tools/util'
|
2
6
|
|
3
7
|
module SeccompTools
|
4
8
|
module Instruction
|
@@ -6,10 +10,11 @@ module SeccompTools
|
|
6
10
|
class LD < Base
|
7
11
|
# Decompile instruction.
|
8
12
|
def decompile
|
9
|
-
ret = reg
|
13
|
+
ret = "#{reg} = "
|
10
14
|
_, _reg, type = symbolize
|
11
15
|
return ret + type[:val].to_s if type[:rel] == :immi
|
12
16
|
return ret + "mem[#{type[:val]}]" if type[:rel] == :mem
|
17
|
+
|
13
18
|
ret + seccomp_data_str
|
14
19
|
end
|
15
20
|
|
@@ -30,22 +35,17 @@ module SeccompTools
|
|
30
35
|
# Current context.
|
31
36
|
# @return [Array<(Integer, Context)>]
|
32
37
|
def branch(context)
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
when :immi then nil
|
37
|
-
when :mem then context[type[:val]]
|
38
|
-
when :data then type[:val]
|
39
|
-
end
|
40
|
-
[[line + 1, nctx]]
|
38
|
+
ctx = context.dup
|
39
|
+
ctx.load(reg, **load_val)
|
40
|
+
[[line + 1, ctx]]
|
41
41
|
end
|
42
42
|
|
43
43
|
private
|
44
44
|
|
45
45
|
def mode
|
46
46
|
@mode ||= MODE.invert[code & 0xe0]
|
47
|
-
# Seccomp doesn't support
|
48
|
-
invalid if @mode.nil? || @mode == :ind
|
47
|
+
# Seccomp doesn't support these modes
|
48
|
+
invalid if @mode.nil? || @mode == :ind || @mode == :msh
|
49
49
|
@mode
|
50
50
|
end
|
51
51
|
|
@@ -53,6 +53,7 @@ module SeccompTools
|
|
53
53
|
return { rel: :immi, val: k } if mode == :imm
|
54
54
|
return { rel: :immi, val: SIZEOF_SECCOMP_DATA } if mode == :len
|
55
55
|
return { rel: :mem, val: k } if mode == :mem
|
56
|
+
|
56
57
|
{ rel: :data, val: k }
|
57
58
|
end
|
58
59
|
|
@@ -71,9 +72,24 @@ module SeccompTools
|
|
71
72
|
else
|
72
73
|
idx = Array.new(12) { |i| i * 4 + 16 }.index(k)
|
73
74
|
return 'INVALID' if idx.nil?
|
74
|
-
|
75
|
+
|
76
|
+
args_name(idx)
|
75
77
|
end
|
76
78
|
end
|
79
|
+
|
80
|
+
def args_name(idx)
|
81
|
+
sys_nrs = contexts.map { |ctx| ctx.known_data[0] }.uniq
|
82
|
+
default = idx.even? ? "args[#{idx / 2}]" : "args[#{idx / 2}] >> 32"
|
83
|
+
return default if sys_nrs.size != 1 || sys_nrs.first.nil?
|
84
|
+
|
85
|
+
sys = Const::Syscall.const_get(arch.upcase.to_sym).invert[sys_nrs.first]
|
86
|
+
args = Const::SYS_ARG[sys]
|
87
|
+
return default if args.nil? || args[idx / 2].nil? # function prototype doesn't have that argument
|
88
|
+
|
89
|
+
comment = "# #{sys}(#{args.join(', ')})"
|
90
|
+
arg_name = Util.colorize(args[idx / 2], t: :args)
|
91
|
+
"#{idx.even? ? arg_name : "#{arg_name} >> 32"} #{Util.colorize(comment, t: :gray)}"
|
92
|
+
end
|
77
93
|
end
|
78
94
|
end
|
79
95
|
end
|