seccomp-tools 1.1.0 → 1.5.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.
- 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
|