seccomp-tools 1.6.1 → 1.7.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 +4 -4
- data/CHANGELOG.md +153 -0
- data/LICENSE +21 -0
- data/README.md +267 -46
- data/completions/_seccomp-tools +83 -0
- data/completions/seccomp-tools.bash +59 -0
- data/completions/seccomp-tools.fish +52 -0
- data/ext/ptrace/ptrace.c +2 -2
- data/lib/seccomp-tools/asm/asm.rb +9 -4
- data/lib/seccomp-tools/asm/compiler.rb +39 -9
- data/lib/seccomp-tools/asm/sasm.tab.rb +31 -21
- data/lib/seccomp-tools/asm/sasm.y +15 -7
- data/lib/seccomp-tools/asm/scalar.rb +50 -7
- data/lib/seccomp-tools/asm/scanner.rb +40 -8
- data/lib/seccomp-tools/asm/statement.rb +14 -5
- data/lib/seccomp-tools/asm/token.rb +19 -1
- data/lib/seccomp-tools/audit/catalog.rb +66 -0
- data/lib/seccomp-tools/audit/checks/arch_unchecked.rb +41 -0
- data/lib/seccomp-tools/audit/checks/dangerous_allow.rb +34 -0
- data/lib/seccomp-tools/audit/checks/orw_chain.rb +41 -0
- data/lib/seccomp-tools/audit/checks/permissive_default.rb +29 -0
- data/lib/seccomp-tools/audit/checks/syscall_alt_gap.rb +44 -0
- data/lib/seccomp-tools/audit/checks/x32_guard.rb +46 -0
- data/lib/seccomp-tools/audit/checks.rb +42 -0
- data/lib/seccomp-tools/audit/finding.rb +25 -0
- data/lib/seccomp-tools/audit/policy.rb +126 -0
- data/lib/seccomp-tools/audit/report.rb +98 -0
- data/lib/seccomp-tools/audit.rb +48 -0
- data/lib/seccomp-tools/bpf.rb +27 -17
- data/lib/seccomp-tools/cli/asm.rb +7 -3
- data/lib/seccomp-tools/cli/audit.rb +86 -0
- data/lib/seccomp-tools/cli/base.rb +51 -8
- data/lib/seccomp-tools/cli/cli.rb +10 -6
- data/lib/seccomp-tools/cli/completion.rb +40 -0
- data/lib/seccomp-tools/cli/disasm.rb +10 -6
- data/lib/seccomp-tools/cli/dump.rb +37 -52
- data/lib/seccomp-tools/cli/dumpable.rb +79 -0
- data/lib/seccomp-tools/cli/emu.rb +32 -9
- data/lib/seccomp-tools/cli/explain.rb +51 -0
- data/lib/seccomp-tools/cli/filter_input.rb +130 -0
- data/lib/seccomp-tools/const.rb +98 -15
- data/lib/seccomp-tools/consts/sys_nr/amd64.rb +1 -1
- data/lib/seccomp-tools/consts/sys_nr/riscv64.rb +332 -0
- data/lib/seccomp-tools/disasm/disasm.rb +31 -13
- data/lib/seccomp-tools/dumper.rb +67 -35
- data/lib/seccomp-tools/emulator.rb +41 -16
- data/lib/seccomp-tools/error.rb +4 -2
- data/lib/seccomp-tools/explain/analysis.rb +67 -0
- data/lib/seccomp-tools/explain/path_facts.rb +110 -0
- data/lib/seccomp-tools/explain/qword.rb +204 -0
- data/lib/seccomp-tools/explain/renderer.rb +128 -0
- data/lib/seccomp-tools/explain/summary.rb +218 -0
- data/lib/seccomp-tools/explain/verdict.rb +44 -0
- data/lib/seccomp-tools/explain.rb +38 -0
- data/lib/seccomp-tools/instruction/alu.rb +14 -9
- data/lib/seccomp-tools/instruction/base.rb +39 -10
- data/lib/seccomp-tools/instruction/jmp.rb +50 -23
- data/lib/seccomp-tools/instruction/ld.rb +46 -21
- data/lib/seccomp-tools/instruction/ldx.rb +4 -3
- data/lib/seccomp-tools/instruction/misc.rb +11 -9
- data/lib/seccomp-tools/instruction/ret.rb +12 -6
- data/lib/seccomp-tools/instruction/st.rb +15 -6
- data/lib/seccomp-tools/instruction/stx.rb +4 -3
- data/lib/seccomp-tools/logger.rb +15 -2
- data/lib/seccomp-tools/symbolic/constraint.rb +80 -0
- data/lib/seccomp-tools/symbolic/executor.rb +210 -0
- data/lib/seccomp-tools/symbolic/expr.rb +185 -0
- data/lib/seccomp-tools/symbolic/state.rb +82 -0
- data/lib/seccomp-tools/syscall.rb +74 -22
- data/lib/seccomp-tools/util.rb +70 -11
- data/lib/seccomp-tools/version.rb +1 -1
- data/lib/seccomp-tools.rb +10 -1
- metadata +83 -11
- data/lib/seccomp-tools/disasm/context.rb +0 -171
data/lib/seccomp-tools/util.rb
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module SeccompTools
|
|
4
|
-
#
|
|
4
|
+
# Utility methods shared across the library: architecture detection and terminal colorizing.
|
|
5
5
|
module Util
|
|
6
6
|
module_function
|
|
7
7
|
|
|
8
8
|
# Get currently supported architectures.
|
|
9
|
+
#
|
|
10
|
+
# Derived from the syscall tables shipped under +consts/sys_nr/+.
|
|
9
11
|
# @return [Array<Symbol>]
|
|
10
|
-
#
|
|
12
|
+
# Architecture names, sorted.
|
|
11
13
|
def supported_archs
|
|
12
14
|
@supported_archs ||= Dir.glob(File.join(__dir__, 'consts', 'sys_nr', '*.rb'))
|
|
13
15
|
.map { |f| File.basename(f, '.rb').to_sym }
|
|
@@ -16,23 +18,57 @@ module SeccompTools
|
|
|
16
18
|
|
|
17
19
|
# Detect system architecture.
|
|
18
20
|
# @return [Symbol]
|
|
21
|
+
# One of {supported_archs}, or +:unknown+ if the host CPU is not supported.
|
|
19
22
|
def system_arch
|
|
20
23
|
case RbConfig::CONFIG['host_cpu']
|
|
21
24
|
when /x86_64/ then :amd64
|
|
22
25
|
when /i386/ then :i386
|
|
23
26
|
when /aarch64/ then :aarch64
|
|
27
|
+
when /riscv64/ then :riscv64
|
|
24
28
|
when /s390x/ then :s390x
|
|
25
29
|
else :unknown
|
|
26
30
|
end
|
|
27
31
|
end
|
|
28
32
|
|
|
33
|
+
# ELF +e_machine+ values (the halfword at offset 18) of the architectures seccomp-tools supports,
|
|
34
|
+
# as they are laid out in the file - so the big-endian s390x reads the other way around. The keys
|
|
35
|
+
# are binary strings (+.b+) to match what is read off the file: this source is UTF-8, where a
|
|
36
|
+
# literal such as +"\xb7\x00"+ would never compare equal to those bytes.
|
|
37
|
+
ELF_MACHINE = {
|
|
38
|
+
"\x03\x00".b => :i386,
|
|
39
|
+
"\x3e\x00".b => :amd64,
|
|
40
|
+
"\xb7\x00".b => :aarch64,
|
|
41
|
+
"\xf3\x00".b => :riscv64,
|
|
42
|
+
"\x00\x16".b => :s390x
|
|
43
|
+
}.freeze
|
|
44
|
+
|
|
45
|
+
# The architecture a running process was built for, read from the ELF header of its executable.
|
|
46
|
+
#
|
|
47
|
+
# Filters dumped from another process are numbered for *its* architecture, so this is what makes
|
|
48
|
+
# the syscall names right when it differs from the host.
|
|
49
|
+
# @param [Integer] pid
|
|
50
|
+
# Process identifier.
|
|
51
|
+
# @return [Symbol?]
|
|
52
|
+
# One of {supported_archs}, or +nil+ when the executable cannot be read (no +/proc+, the
|
|
53
|
+
# process is gone, permission denied) or its machine type is not one we know.
|
|
54
|
+
def process_arch(pid)
|
|
55
|
+
File.open("/proc/#{pid}/exe", 'rb') do |f|
|
|
56
|
+
f.pos = 18
|
|
57
|
+
ELF_MACHINE[f.read(2)]
|
|
58
|
+
end
|
|
59
|
+
rescue SystemCallError
|
|
60
|
+
nil
|
|
61
|
+
end
|
|
62
|
+
|
|
29
63
|
# Enable colorize.
|
|
64
|
+
#
|
|
65
|
+
# Colors are still only emitted when the output is a tty, see {colorize_enabled?}.
|
|
30
66
|
# @return [void]
|
|
31
67
|
def enable_color!
|
|
32
68
|
@disable_color = false
|
|
33
69
|
end
|
|
34
70
|
|
|
35
|
-
# Disable colorize.
|
|
71
|
+
# Disable colorize, {colorize} becomes a no-op regardless of the output being a tty.
|
|
36
72
|
# @return [void]
|
|
37
73
|
def disable_color!
|
|
38
74
|
@disable_color = true
|
|
@@ -40,28 +76,35 @@ module SeccompTools
|
|
|
40
76
|
|
|
41
77
|
# Is colorize enabled?
|
|
42
78
|
# @return [Boolean]
|
|
79
|
+
# +true+ only if colors have not been disabled by {disable_color!} and +$stdout+ is a tty.
|
|
43
80
|
def colorize_enabled?
|
|
44
81
|
!@disable_color && $stdout.tty?
|
|
45
82
|
end
|
|
46
83
|
|
|
47
84
|
# color code of light yellow
|
|
48
85
|
LIGHT_YELLOW = "\e[38;5;230m"
|
|
49
|
-
# Color codes for pretty print.
|
|
86
|
+
# Color codes for pretty print. +error+, +warn+ and +info+ are severities rather than parts of a
|
|
87
|
+
# filter, shading from alarming to quiet; {SeccompTools::Logger} colors its own levels by the
|
|
88
|
+
# same names.
|
|
50
89
|
COLOR_CODE = {
|
|
51
90
|
esc_m: "\e[0m",
|
|
52
91
|
syscall: "\e[38;5;120m", # light green
|
|
53
92
|
arch: LIGHT_YELLOW,
|
|
54
93
|
args: LIGHT_YELLOW,
|
|
55
94
|
gray: "\e[2m",
|
|
56
|
-
error: "\e[38;5;196m" # heavy red
|
|
95
|
+
error: "\e[38;5;196m", # heavy red
|
|
96
|
+
warn: LIGHT_YELLOW,
|
|
97
|
+
info: "\e[38;5;110m" # light blue
|
|
57
98
|
}.freeze
|
|
58
|
-
#
|
|
59
|
-
#
|
|
60
|
-
#
|
|
99
|
+
# Wrap contents with terminal color codes.
|
|
100
|
+
#
|
|
101
|
+
# Returns +s+ unchanged when {colorize_enabled?} is +false+.
|
|
102
|
+
# @param [#to_s] s
|
|
103
|
+
# Contents to be wrapped.
|
|
61
104
|
# @param [Symbol?] t
|
|
62
|
-
#
|
|
105
|
+
# Which kind of color to use, valid symbols are the keys of {Util::COLOR_CODE}.
|
|
63
106
|
# @return [String]
|
|
64
|
-
#
|
|
107
|
+
# +s+ wrapped with color codes.
|
|
65
108
|
def colorize(s, t: nil)
|
|
66
109
|
s = s.to_s
|
|
67
110
|
return s unless colorize_enabled?
|
|
@@ -71,13 +114,29 @@ module SeccompTools
|
|
|
71
114
|
"#{color}#{s.sub(cc[:esc_m], cc[:esc_m] + color)}#{cc[:esc_m]}"
|
|
72
115
|
end
|
|
73
116
|
|
|
117
|
+
# Does the file at +path+ start with the ELF magic bytes?
|
|
118
|
+
#
|
|
119
|
+
# Used to tell an executable apart from a raw BPF blob.
|
|
120
|
+
# @param [String] path
|
|
121
|
+
# Path to the file to check.
|
|
122
|
+
# @return [Boolean]
|
|
123
|
+
# +false+ when the file cannot be read.
|
|
124
|
+
def elf?(path)
|
|
125
|
+
File.binread(path, 4) == "\x7fELF".b
|
|
126
|
+
rescue SystemCallError
|
|
127
|
+
false
|
|
128
|
+
end
|
|
129
|
+
|
|
74
130
|
# Get content of filename under directory templates/.
|
|
75
131
|
#
|
|
76
132
|
# @param [String] filename
|
|
77
|
-
#
|
|
133
|
+
# Basename of a file under +lib/seccomp-tools/templates/+.
|
|
78
134
|
#
|
|
79
135
|
# @return [String]
|
|
80
136
|
# Content of the file.
|
|
137
|
+
#
|
|
138
|
+
# @raise [Errno::ENOENT]
|
|
139
|
+
# If no such template exists.
|
|
81
140
|
def template(filename)
|
|
82
141
|
File.binread(File.join(__dir__, 'templates', filename))
|
|
83
142
|
end
|
data/lib/seccomp-tools.rb
CHANGED
|
@@ -2,7 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
# @author david942j
|
|
4
4
|
|
|
5
|
-
#
|
|
5
|
+
# Toolkit for working with seccomp BPF filters.
|
|
6
|
+
#
|
|
7
|
+
# The library entry points are {Asm.asm} to compile assembly into raw BPF, {Disasm.disasm} to turn
|
|
8
|
+
# raw BPF back into readable assembly, {Dumper.dump} to capture the filters a process installs, and
|
|
9
|
+
# {Emulator} to run a filter against a hypothetical syscall.
|
|
10
|
+
#
|
|
11
|
+
# @example
|
|
12
|
+
# raw = SeccompTools::Asm.asm("return ALLOW\n", arch: :amd64)
|
|
13
|
+
# SeccompTools::Disasm.disasm(raw, arch: :amd64, display_bpf: false)
|
|
14
|
+
# #=> "0000: return ALLOW\n"
|
|
6
15
|
module SeccompTools
|
|
7
16
|
end
|
|
8
17
|
|
metadata
CHANGED
|
@@ -1,15 +1,28 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: seccomp-tools
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- david942j
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: ostruct
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0'
|
|
19
|
+
type: :development
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0'
|
|
13
26
|
- !ruby/object:Gem::Dependency
|
|
14
27
|
name: rake
|
|
15
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -72,14 +85,14 @@ dependencies:
|
|
|
72
85
|
requirements:
|
|
73
86
|
- - "~>"
|
|
74
87
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: '0
|
|
88
|
+
version: '1.0'
|
|
76
89
|
type: :development
|
|
77
90
|
prerelease: false
|
|
78
91
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
92
|
requirements:
|
|
80
93
|
- - "~>"
|
|
81
94
|
- !ruby/object:Gem::Version
|
|
82
|
-
version: '0
|
|
95
|
+
version: '1.0'
|
|
83
96
|
- !ruby/object:Gem::Dependency
|
|
84
97
|
name: yard
|
|
85
98
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -94,6 +107,20 @@ dependencies:
|
|
|
94
107
|
- - "~>"
|
|
95
108
|
- !ruby/object:Gem::Version
|
|
96
109
|
version: '0.9'
|
|
110
|
+
- !ruby/object:Gem::Dependency
|
|
111
|
+
name: logger
|
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
|
113
|
+
requirements:
|
|
114
|
+
- - ">="
|
|
115
|
+
- !ruby/object:Gem::Version
|
|
116
|
+
version: '0'
|
|
117
|
+
type: :runtime
|
|
118
|
+
prerelease: false
|
|
119
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
120
|
+
requirements:
|
|
121
|
+
- - ">="
|
|
122
|
+
- !ruby/object:Gem::Version
|
|
123
|
+
version: '0'
|
|
97
124
|
- !ruby/object:Gem::Dependency
|
|
98
125
|
name: os
|
|
99
126
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -114,6 +141,20 @@ dependencies:
|
|
|
114
141
|
- - ">="
|
|
115
142
|
- !ruby/object:Gem::Version
|
|
116
143
|
version: 1.1.1
|
|
144
|
+
- !ruby/object:Gem::Dependency
|
|
145
|
+
name: racc
|
|
146
|
+
requirement: !ruby/object:Gem::Requirement
|
|
147
|
+
requirements:
|
|
148
|
+
- - "~>"
|
|
149
|
+
- !ruby/object:Gem::Version
|
|
150
|
+
version: '1.8'
|
|
151
|
+
type: :runtime
|
|
152
|
+
prerelease: false
|
|
153
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
154
|
+
requirements:
|
|
155
|
+
- - "~>"
|
|
156
|
+
- !ruby/object:Gem::Version
|
|
157
|
+
version: '1.8'
|
|
117
158
|
description: |
|
|
118
159
|
Provide useful tools to analyze seccomp rules.
|
|
119
160
|
Visit https://github.com/david942j/seccomp-tools for more details.
|
|
@@ -125,8 +166,13 @@ extensions:
|
|
|
125
166
|
- ext/ptrace/extconf.rb
|
|
126
167
|
extra_rdoc_files: []
|
|
127
168
|
files:
|
|
169
|
+
- CHANGELOG.md
|
|
170
|
+
- LICENSE
|
|
128
171
|
- README.md
|
|
129
172
|
- bin/seccomp-tools
|
|
173
|
+
- completions/_seccomp-tools
|
|
174
|
+
- completions/seccomp-tools.bash
|
|
175
|
+
- completions/seccomp-tools.fish
|
|
130
176
|
- ext/ptrace/extconf.rb
|
|
131
177
|
- ext/ptrace/ptrace.c
|
|
132
178
|
- lib/seccomp-tools.rb
|
|
@@ -138,24 +184,48 @@ files:
|
|
|
138
184
|
- lib/seccomp-tools/asm/scanner.rb
|
|
139
185
|
- lib/seccomp-tools/asm/statement.rb
|
|
140
186
|
- lib/seccomp-tools/asm/token.rb
|
|
187
|
+
- lib/seccomp-tools/audit.rb
|
|
188
|
+
- lib/seccomp-tools/audit/catalog.rb
|
|
189
|
+
- lib/seccomp-tools/audit/checks.rb
|
|
190
|
+
- lib/seccomp-tools/audit/checks/arch_unchecked.rb
|
|
191
|
+
- lib/seccomp-tools/audit/checks/dangerous_allow.rb
|
|
192
|
+
- lib/seccomp-tools/audit/checks/orw_chain.rb
|
|
193
|
+
- lib/seccomp-tools/audit/checks/permissive_default.rb
|
|
194
|
+
- lib/seccomp-tools/audit/checks/syscall_alt_gap.rb
|
|
195
|
+
- lib/seccomp-tools/audit/checks/x32_guard.rb
|
|
196
|
+
- lib/seccomp-tools/audit/finding.rb
|
|
197
|
+
- lib/seccomp-tools/audit/policy.rb
|
|
198
|
+
- lib/seccomp-tools/audit/report.rb
|
|
141
199
|
- lib/seccomp-tools/bpf.rb
|
|
142
200
|
- lib/seccomp-tools/cli/asm.rb
|
|
201
|
+
- lib/seccomp-tools/cli/audit.rb
|
|
143
202
|
- lib/seccomp-tools/cli/base.rb
|
|
144
203
|
- lib/seccomp-tools/cli/cli.rb
|
|
204
|
+
- lib/seccomp-tools/cli/completion.rb
|
|
145
205
|
- lib/seccomp-tools/cli/disasm.rb
|
|
146
206
|
- lib/seccomp-tools/cli/dump.rb
|
|
207
|
+
- lib/seccomp-tools/cli/dumpable.rb
|
|
147
208
|
- lib/seccomp-tools/cli/emu.rb
|
|
209
|
+
- lib/seccomp-tools/cli/explain.rb
|
|
210
|
+
- lib/seccomp-tools/cli/filter_input.rb
|
|
148
211
|
- lib/seccomp-tools/const.rb
|
|
149
212
|
- lib/seccomp-tools/consts/sys_arg.rb
|
|
150
213
|
- lib/seccomp-tools/consts/sys_nr/aarch64.rb
|
|
151
214
|
- lib/seccomp-tools/consts/sys_nr/amd64.rb
|
|
152
215
|
- lib/seccomp-tools/consts/sys_nr/i386.rb
|
|
216
|
+
- lib/seccomp-tools/consts/sys_nr/riscv64.rb
|
|
153
217
|
- lib/seccomp-tools/consts/sys_nr/s390x.rb
|
|
154
|
-
- lib/seccomp-tools/disasm/context.rb
|
|
155
218
|
- lib/seccomp-tools/disasm/disasm.rb
|
|
156
219
|
- lib/seccomp-tools/dumper.rb
|
|
157
220
|
- lib/seccomp-tools/emulator.rb
|
|
158
221
|
- lib/seccomp-tools/error.rb
|
|
222
|
+
- lib/seccomp-tools/explain.rb
|
|
223
|
+
- lib/seccomp-tools/explain/analysis.rb
|
|
224
|
+
- lib/seccomp-tools/explain/path_facts.rb
|
|
225
|
+
- lib/seccomp-tools/explain/qword.rb
|
|
226
|
+
- lib/seccomp-tools/explain/renderer.rb
|
|
227
|
+
- lib/seccomp-tools/explain/summary.rb
|
|
228
|
+
- lib/seccomp-tools/explain/verdict.rb
|
|
159
229
|
- lib/seccomp-tools/instruction/alu.rb
|
|
160
230
|
- lib/seccomp-tools/instruction/base.rb
|
|
161
231
|
- lib/seccomp-tools/instruction/instruction.rb
|
|
@@ -167,6 +237,10 @@ files:
|
|
|
167
237
|
- lib/seccomp-tools/instruction/st.rb
|
|
168
238
|
- lib/seccomp-tools/instruction/stx.rb
|
|
169
239
|
- lib/seccomp-tools/logger.rb
|
|
240
|
+
- lib/seccomp-tools/symbolic/constraint.rb
|
|
241
|
+
- lib/seccomp-tools/symbolic/executor.rb
|
|
242
|
+
- lib/seccomp-tools/symbolic/expr.rb
|
|
243
|
+
- lib/seccomp-tools/symbolic/state.rb
|
|
170
244
|
- lib/seccomp-tools/syscall.rb
|
|
171
245
|
- lib/seccomp-tools/templates/asm.amd64.asm
|
|
172
246
|
- lib/seccomp-tools/templates/asm.c
|
|
@@ -174,7 +248,6 @@ files:
|
|
|
174
248
|
- lib/seccomp-tools/templates/asm.s390x.asm
|
|
175
249
|
- lib/seccomp-tools/util.rb
|
|
176
250
|
- lib/seccomp-tools/version.rb
|
|
177
|
-
homepage:
|
|
178
251
|
licenses:
|
|
179
252
|
- MIT
|
|
180
253
|
metadata:
|
|
@@ -182,7 +255,7 @@ metadata:
|
|
|
182
255
|
documentation_uri: https://www.rubydoc.info/github/david942j/seccomp-tools/master
|
|
183
256
|
homepage_uri: https://github.com/david942j/seccomp-tools
|
|
184
257
|
source_code_uri: https://github.com/david942j/seccomp-tools
|
|
185
|
-
|
|
258
|
+
rubygems_mfa_required: 'true'
|
|
186
259
|
rdoc_options: []
|
|
187
260
|
require_paths:
|
|
188
261
|
- lib
|
|
@@ -190,15 +263,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
190
263
|
requirements:
|
|
191
264
|
- - ">="
|
|
192
265
|
- !ruby/object:Gem::Version
|
|
193
|
-
version: '
|
|
266
|
+
version: '3.1'
|
|
194
267
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
195
268
|
requirements:
|
|
196
269
|
- - ">="
|
|
197
270
|
- !ruby/object:Gem::Version
|
|
198
271
|
version: '0'
|
|
199
272
|
requirements: []
|
|
200
|
-
rubygems_version: 3.
|
|
201
|
-
signing_key:
|
|
273
|
+
rubygems_version: 3.6.9
|
|
202
274
|
specification_version: 4
|
|
203
275
|
summary: seccomp-tools
|
|
204
276
|
test_files: []
|
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module SeccompTools
|
|
4
|
-
module Disasm
|
|
5
|
-
# @private
|
|
6
|
-
#
|
|
7
|
-
# Context for disassembler to analyze.
|
|
8
|
-
#
|
|
9
|
-
# This class maintains:
|
|
10
|
-
# * if +reg/mem+ can be one of +data[*]+
|
|
11
|
-
# * if +data[0]+ (i.e. sys_number) is a known value
|
|
12
|
-
class Context
|
|
13
|
-
# @private
|
|
14
|
-
#
|
|
15
|
-
# Records the type and value.
|
|
16
|
-
class Value
|
|
17
|
-
attr_reader :val # @return [Integer]
|
|
18
|
-
|
|
19
|
-
# @param [:imm, :data, :mem] rel
|
|
20
|
-
# @param [Integer?] val
|
|
21
|
-
def initialize(rel: :imm, val: nil)
|
|
22
|
-
@rel = rel
|
|
23
|
-
@val = val
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
# @return [Boolean]
|
|
27
|
-
def data?
|
|
28
|
-
@rel == :data
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# @return [Boolean]
|
|
32
|
-
def imm?
|
|
33
|
-
@rel == :imm && @val.is_a?(Integer)
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
# Defines hash function.
|
|
37
|
-
# @return [Integer]
|
|
38
|
-
def hash
|
|
39
|
-
@rel.hash ^ @val.hash
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
# Defines +eql?+.
|
|
43
|
-
#
|
|
44
|
-
# @param [Context::Value] other
|
|
45
|
-
# @return [Boolean]
|
|
46
|
-
def eql?(other)
|
|
47
|
-
@val == other.val && @rel == other.instance_variable_get(:@rel)
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
# @return [{Integer, Symbol => Context::Value}] Records reg and mem values.
|
|
52
|
-
attr_reader :values
|
|
53
|
-
# @return [Array<Integer?>] Records the known value of data.
|
|
54
|
-
attr_reader :known_data
|
|
55
|
-
|
|
56
|
-
# Instantiate a {Context} object.
|
|
57
|
-
# @param [{Integer, Symbol => Context::Value?}] values
|
|
58
|
-
# Value to be set to +reg/mem+.
|
|
59
|
-
# @param [Array<Integer?>] known_data
|
|
60
|
-
# Records which index of data is known.
|
|
61
|
-
# It's used for tracking when the syscall number is known, which can be used to display argument names of the
|
|
62
|
-
# syscall.
|
|
63
|
-
def initialize(values: {}, known_data: [])
|
|
64
|
-
@values = values
|
|
65
|
-
16.times { |i| @values[i] ||= Value.new(rel: :mem, val: i) } # make @values always has all keys
|
|
66
|
-
@values[:a] ||= Value.new
|
|
67
|
-
@values[:x] ||= Value.new
|
|
68
|
-
@known_data = known_data
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
# Is used for the ld/ldx instructions.
|
|
72
|
-
#
|
|
73
|
-
# @param [#downcase, :a, :x] reg
|
|
74
|
-
# Register to be set
|
|
75
|
-
# @return [void]
|
|
76
|
-
def load(reg, rel: nil, val: nil)
|
|
77
|
-
reg = reg.downcase.to_sym
|
|
78
|
-
values[reg] = if rel == :mem
|
|
79
|
-
values[val]
|
|
80
|
-
else
|
|
81
|
-
Value.new(rel: rel, val: val)
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
# Is used for the st/stx instructions.
|
|
86
|
-
#
|
|
87
|
-
# @param [Integer] idx
|
|
88
|
-
# Index of +mem+ array.
|
|
89
|
-
# @param [#downcase, :a, :x] reg
|
|
90
|
-
# Register.
|
|
91
|
-
#
|
|
92
|
-
# @return [void]
|
|
93
|
-
def store(idx, reg)
|
|
94
|
-
raise RangeError, "Expect 0 <= idx < 16, got #{idx}." unless idx.between?(0, 15)
|
|
95
|
-
|
|
96
|
-
values[idx] = values[reg.downcase.to_sym]
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
# Hints context that current value of register A equals to +val+.
|
|
100
|
-
#
|
|
101
|
-
# @param [Integer, :x] val
|
|
102
|
-
# An immediate value or the symbol x.
|
|
103
|
-
# @return [self]
|
|
104
|
-
# Returns the object itself.
|
|
105
|
-
def eql!(val)
|
|
106
|
-
tap do
|
|
107
|
-
# only cares when A is fetched from data
|
|
108
|
-
next unless a.data?
|
|
109
|
-
next known_data[a.val] = val if val.is_a?(Integer)
|
|
110
|
-
# A == X, we can handle these cases:
|
|
111
|
-
# * X is an immi
|
|
112
|
-
# * X is a known data
|
|
113
|
-
next unless x.data? || x.imm?
|
|
114
|
-
next known_data[a.val] = x.val if x.imm?
|
|
115
|
-
|
|
116
|
-
known_data[a.val] = known_data[x.val]
|
|
117
|
-
end
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
# Implements a deep dup.
|
|
121
|
-
# @return [Context]
|
|
122
|
-
def dup
|
|
123
|
-
Context.new(values: values.dup, known_data: known_data.dup)
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
# Register A.
|
|
127
|
-
# @return [Context::Value]
|
|
128
|
-
def a
|
|
129
|
-
values[:a]
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
# Register X.
|
|
133
|
-
# @return [Context::Value]
|
|
134
|
-
def x
|
|
135
|
-
values[:x]
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
# For conveniently get instance variable.
|
|
139
|
-
# @param [String, Symbol, Integer] key
|
|
140
|
-
# @return [Context::Value]
|
|
141
|
-
def [](key)
|
|
142
|
-
return values[key] if key.is_a?(Integer) # mem
|
|
143
|
-
|
|
144
|
-
values[key.downcase.to_sym]
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
# For conveniently set an instance variable.
|
|
148
|
-
# @param [#downcase, :a, :x] reg
|
|
149
|
-
# Can be +'A', 'a', :a, 'X', 'x', :x+.
|
|
150
|
-
# @param [Value] val
|
|
151
|
-
# Value to set.
|
|
152
|
-
# @return [void]
|
|
153
|
-
def []=(reg, val)
|
|
154
|
-
values[reg.downcase.to_sym] = val
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
# For +Set+ to compare two {Context} objects.
|
|
158
|
-
# @param [Context] other
|
|
159
|
-
# @return [Boolean]
|
|
160
|
-
def eql?(other)
|
|
161
|
-
values.eql?(other.values) && known_data.eql?(other.known_data)
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
# For +Set+ to get the hash value.
|
|
165
|
-
# @return [Integer]
|
|
166
|
-
def hash
|
|
167
|
-
values.hash ^ known_data.hash
|
|
168
|
-
end
|
|
169
|
-
end
|
|
170
|
-
end
|
|
171
|
-
end
|