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.
- checksums.yaml +4 -4
- data/README.md +105 -17
- data/ext/ptrace/ptrace.c +56 -4
- data/lib/seccomp-tools/asm/asm.rb +8 -6
- data/lib/seccomp-tools/asm/compiler.rb +130 -224
- data/lib/seccomp-tools/asm/sasm.tab.rb +780 -0
- data/lib/seccomp-tools/asm/sasm.y +175 -0
- data/lib/seccomp-tools/asm/scalar.rb +129 -0
- data/lib/seccomp-tools/asm/scanner.rb +163 -0
- data/lib/seccomp-tools/asm/statement.rb +32 -0
- data/lib/seccomp-tools/asm/token.rb +29 -0
- data/lib/seccomp-tools/bpf.rb +31 -7
- data/lib/seccomp-tools/cli/asm.rb +3 -3
- data/lib/seccomp-tools/cli/base.rb +4 -4
- data/lib/seccomp-tools/cli/disasm.rb +27 -3
- data/lib/seccomp-tools/cli/dump.rb +4 -2
- data/lib/seccomp-tools/cli/emu.rb +1 -4
- data/lib/seccomp-tools/const.rb +37 -3
- data/lib/seccomp-tools/consts/sys_nr/aarch64.rb +284 -0
- data/lib/seccomp-tools/consts/sys_nr/amd64.rb +5 -1
- data/lib/seccomp-tools/consts/sys_nr/i386.rb +14 -14
- data/lib/seccomp-tools/consts/sys_nr/s390x.rb +365 -0
- data/lib/seccomp-tools/disasm/context.rb +2 -2
- data/lib/seccomp-tools/disasm/disasm.rb +16 -9
- data/lib/seccomp-tools/dumper.rb +12 -3
- data/lib/seccomp-tools/emulator.rb +5 -9
- data/lib/seccomp-tools/error.rb +31 -0
- data/lib/seccomp-tools/instruction/alu.rb +1 -1
- data/lib/seccomp-tools/instruction/base.rb +1 -1
- data/lib/seccomp-tools/instruction/jmp.rb +28 -10
- data/lib/seccomp-tools/instruction/ld.rb +5 -3
- data/lib/seccomp-tools/syscall.rb +23 -13
- data/lib/seccomp-tools/templates/asm.s390x.asm +26 -0
- data/lib/seccomp-tools/util.rb +3 -1
- data/lib/seccomp-tools/version.rb +1 -1
- metadata +38 -9
- data/lib/seccomp-tools/asm/tokenizer.rb +0 -169
@@ -1,7 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'os'
|
4
|
+
|
3
5
|
require 'seccomp-tools/const'
|
4
|
-
require 'seccomp-tools/ptrace'
|
6
|
+
require 'seccomp-tools/ptrace' if OS.linux?
|
5
7
|
|
6
8
|
module SeccompTools
|
7
9
|
# Record syscall number, arguments, return value.
|
@@ -9,12 +11,16 @@ module SeccompTools
|
|
9
11
|
# Syscall arguments offset of +struct user+ in different arch.
|
10
12
|
ABI = {
|
11
13
|
amd64: { number: 120, args: [112, 104, 96, 56, 72, 44], ret: 80, SYS_prctl: 157, SYS_seccomp: 317 },
|
12
|
-
i386: { number:
|
14
|
+
i386: { number: 44, args: [0, 4, 8, 12, 16, 20], ret: 24, SYS_prctl: 172, SYS_seccomp: 354 },
|
15
|
+
aarch64: { number: 64, args: [0, 8, 16, 24, 32, 40, 48], ret: 0, SYS_prctl: 167, SYS_seccomp: 277 },
|
16
|
+
# Most software invokes syscalls through "svc 0", in which case the syscall number is in r1.
|
17
|
+
# However, it's also possible to use "svc NR": this case is not handled here.
|
18
|
+
s390x: { number: 24, args: [32, 40, 48, 56, 64, 72], ret: 32, SYS_prctl: 172, SYS_seccomp: 348 }
|
13
19
|
}.freeze
|
14
20
|
|
15
21
|
# @return [Integer] Process id.
|
16
22
|
attr_reader :pid
|
17
|
-
# @return [
|
23
|
+
# @return [{Symbol => Integer, Array<Integer>}] See {ABI}.
|
18
24
|
attr_reader :abi
|
19
25
|
# @return [Integer] Syscall number.
|
20
26
|
attr_reader :number
|
@@ -60,25 +66,29 @@ module SeccompTools
|
|
60
66
|
# Architecture of this syscall.
|
61
67
|
def arch
|
62
68
|
@arch ||= File.open("/proc/#{pid}/exe", 'rb') do |f|
|
63
|
-
f.pos =
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
69
|
+
f.pos = 18
|
70
|
+
{
|
71
|
+
"\x03\x00" => :i386,
|
72
|
+
"\x3e\x00" => :amd64,
|
73
|
+
"\xb7\x00" => :aarch64,
|
74
|
+
"\x00\x16" => :s390x
|
75
|
+
}[f.read(2)]
|
68
76
|
end
|
69
77
|
end
|
70
78
|
|
71
79
|
private
|
72
80
|
|
73
81
|
def bits
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
82
|
+
{
|
83
|
+
i386: 32,
|
84
|
+
amd64: 64,
|
85
|
+
aarch64: 64,
|
86
|
+
s390x: 64
|
87
|
+
}[arch]
|
78
88
|
end
|
79
89
|
|
80
90
|
def peek(offset)
|
81
|
-
Ptrace.peekuser(pid, offset, 0)
|
91
|
+
Ptrace.peekuser(pid, offset, 0, bits)
|
82
92
|
end
|
83
93
|
end
|
84
94
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
.globl install_seccomp
|
2
|
+
install_seccomp:
|
3
|
+
lghi %r1, 172 /* __NR_prctl */
|
4
|
+
lghi %r2, 38 /* PR_SET_NO_NEW_PRIVS */
|
5
|
+
lghi %r3, 1
|
6
|
+
xgr %r4, %r4
|
7
|
+
xgr %r5, %r5
|
8
|
+
xgr %r6, %r6
|
9
|
+
svc 0
|
10
|
+
|
11
|
+
lghi %r1, 172 /* __NR_prctl */
|
12
|
+
lghi %r2, 22 /* PR_SET_SECCOMP */
|
13
|
+
lghi %r3, 2 /* SECCOMP_MODE_FILTER */
|
14
|
+
aghi %r15, -16 /* sizeof(struct sock_fprog) */
|
15
|
+
mvhhi 0(%r15), (_filter_end - _filter) >> 3 /* .len */
|
16
|
+
larl %r4, _filter
|
17
|
+
stg %r4, 8(%r15) /* .filter */
|
18
|
+
lgr %r4, %r15
|
19
|
+
svc 0
|
20
|
+
aghi %r15, 16
|
21
|
+
|
22
|
+
br %r14
|
23
|
+
|
24
|
+
_filter:
|
25
|
+
.ascii "<TO_BE_REPLACED>"
|
26
|
+
_filter_end:
|
data/lib/seccomp-tools/util.rb
CHANGED
@@ -20,6 +20,8 @@ module SeccompTools
|
|
20
20
|
case RbConfig::CONFIG['host_cpu']
|
21
21
|
when /x86_64/ then :amd64
|
22
22
|
when /i386/ then :i386
|
23
|
+
when /aarch64/ then :aarch64
|
24
|
+
when /s390x/ then :s390x
|
23
25
|
else :unknown
|
24
26
|
end
|
25
27
|
end
|
@@ -77,7 +79,7 @@ module SeccompTools
|
|
77
79
|
# @return [String]
|
78
80
|
# Content of the file.
|
79
81
|
def template(filename)
|
80
|
-
|
82
|
+
File.binread(File.join(__dir__, 'templates', filename))
|
81
83
|
end
|
82
84
|
end
|
83
85
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: seccomp-tools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- david942j
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-09-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -58,28 +58,28 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
61
|
+
version: '1'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
68
|
+
version: '1'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: simplecov
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 0.
|
75
|
+
version: '0.21'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 0.
|
82
|
+
version: '0.21'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: yard
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,6 +94,26 @@ dependencies:
|
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0.9'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: os
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '1.1'
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: 1.1.1
|
107
|
+
type: :runtime
|
108
|
+
prerelease: false
|
109
|
+
version_requirements: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - "~>"
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '1.1'
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: 1.1.1
|
97
117
|
description: |
|
98
118
|
Provide useful tools to analyze seccomp rules.
|
99
119
|
Visit https://github.com/david942j/seccomp-tools for more details.
|
@@ -112,7 +132,12 @@ files:
|
|
112
132
|
- lib/seccomp-tools.rb
|
113
133
|
- lib/seccomp-tools/asm/asm.rb
|
114
134
|
- lib/seccomp-tools/asm/compiler.rb
|
115
|
-
- lib/seccomp-tools/asm/
|
135
|
+
- lib/seccomp-tools/asm/sasm.tab.rb
|
136
|
+
- lib/seccomp-tools/asm/sasm.y
|
137
|
+
- lib/seccomp-tools/asm/scalar.rb
|
138
|
+
- lib/seccomp-tools/asm/scanner.rb
|
139
|
+
- lib/seccomp-tools/asm/statement.rb
|
140
|
+
- lib/seccomp-tools/asm/token.rb
|
116
141
|
- lib/seccomp-tools/bpf.rb
|
117
142
|
- lib/seccomp-tools/cli/asm.rb
|
118
143
|
- lib/seccomp-tools/cli/base.rb
|
@@ -122,12 +147,15 @@ files:
|
|
122
147
|
- lib/seccomp-tools/cli/emu.rb
|
123
148
|
- lib/seccomp-tools/const.rb
|
124
149
|
- lib/seccomp-tools/consts/sys_arg.rb
|
150
|
+
- lib/seccomp-tools/consts/sys_nr/aarch64.rb
|
125
151
|
- lib/seccomp-tools/consts/sys_nr/amd64.rb
|
126
152
|
- lib/seccomp-tools/consts/sys_nr/i386.rb
|
153
|
+
- lib/seccomp-tools/consts/sys_nr/s390x.rb
|
127
154
|
- lib/seccomp-tools/disasm/context.rb
|
128
155
|
- lib/seccomp-tools/disasm/disasm.rb
|
129
156
|
- lib/seccomp-tools/dumper.rb
|
130
157
|
- lib/seccomp-tools/emulator.rb
|
158
|
+
- lib/seccomp-tools/error.rb
|
131
159
|
- lib/seccomp-tools/instruction/alu.rb
|
132
160
|
- lib/seccomp-tools/instruction/base.rb
|
133
161
|
- lib/seccomp-tools/instruction/instruction.rb
|
@@ -143,6 +171,7 @@ files:
|
|
143
171
|
- lib/seccomp-tools/templates/asm.amd64.asm
|
144
172
|
- lib/seccomp-tools/templates/asm.c
|
145
173
|
- lib/seccomp-tools/templates/asm.i386.asm
|
174
|
+
- lib/seccomp-tools/templates/asm.s390x.asm
|
146
175
|
- lib/seccomp-tools/util.rb
|
147
176
|
- lib/seccomp-tools/version.rb
|
148
177
|
homepage:
|
@@ -161,14 +190,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
161
190
|
requirements:
|
162
191
|
- - ">="
|
163
192
|
- !ruby/object:Gem::Version
|
164
|
-
version: '2.
|
193
|
+
version: '2.6'
|
165
194
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
166
195
|
requirements:
|
167
196
|
- - ">="
|
168
197
|
- !ruby/object:Gem::Version
|
169
198
|
version: '0'
|
170
199
|
requirements: []
|
171
|
-
rubygems_version: 3.
|
200
|
+
rubygems_version: 3.1.6
|
172
201
|
signing_key:
|
173
202
|
specification_version: 4
|
174
203
|
summary: seccomp-tools
|
@@ -1,169 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'seccomp-tools/const'
|
4
|
-
require 'seccomp-tools/instruction/alu'
|
5
|
-
|
6
|
-
module SeccompTools
|
7
|
-
module Asm
|
8
|
-
# Fetch tokens from a string.
|
9
|
-
#
|
10
|
-
# Internal used by {Compiler}.
|
11
|
-
# @private
|
12
|
-
class Tokenizer
|
13
|
-
# a valid label
|
14
|
-
LABEL_REGEXP = /[A-Za-z_]\w*/.freeze
|
15
|
-
attr_accessor :cur
|
16
|
-
|
17
|
-
# @param [String] str
|
18
|
-
# @example
|
19
|
-
# Tokenizer.new('return ALLOW')
|
20
|
-
def initialize(str)
|
21
|
-
@str = str
|
22
|
-
@cur = @str.dup
|
23
|
-
end
|
24
|
-
|
25
|
-
# Fetch a token without raising errors.
|
26
|
-
def fetch(type)
|
27
|
-
fetch!(type)
|
28
|
-
rescue ArgumentError
|
29
|
-
nil
|
30
|
-
end
|
31
|
-
|
32
|
-
# Fetch a token. When expected token is not found,
|
33
|
-
# error with proper message would be raised.
|
34
|
-
#
|
35
|
-
# @param [String, Symbol] type
|
36
|
-
# @example
|
37
|
-
# tokenizer = Tokenizer.new('return ALLOW')
|
38
|
-
# tokenfizer.fetch!('return')
|
39
|
-
# #=> "return"
|
40
|
-
# tokenizer.fetch!(:ret)
|
41
|
-
# #=> 2147418112
|
42
|
-
def fetch!(type)
|
43
|
-
@last_match_size = 0
|
44
|
-
res = case type
|
45
|
-
when String then fetch_str(type) || raise_expected("token #{type.inspect}")
|
46
|
-
when :comparison then fetch_strs(COMPARISON).to_sym || raise_expected('a comparison operator')
|
47
|
-
when :sys_num_x then fetch_sys_num_arch_x || raise_expected("a syscall number or 'X'")
|
48
|
-
when :goto then fetch_number || fetch_label || raise_expected('a number or label name')
|
49
|
-
when :ret then fetch_return || raise(ArgumentError, <<-EOS)
|
50
|
-
Invalid return type: #{cur.inspect}.
|
51
|
-
EOS
|
52
|
-
when :ax then fetch_ax || raise_expected("'A' or 'X'")
|
53
|
-
when :ary then fetch_ary || raise_expected('data[<num>], mem[<num>], or args[<num>]')
|
54
|
-
when :alu_op then fetch_alu || raise_expected('an ALU operator')
|
55
|
-
else raise ArgumentError, "Unsupported type: #{type.inspect}"
|
56
|
-
end
|
57
|
-
slice!
|
58
|
-
res
|
59
|
-
end
|
60
|
-
|
61
|
-
private
|
62
|
-
|
63
|
-
COMPARISON = %w[== != <= >= < >].freeze
|
64
|
-
|
65
|
-
def fetch_strs(strs)
|
66
|
-
strs.find(&method(:fetch_str))
|
67
|
-
end
|
68
|
-
|
69
|
-
def fetch_str(str)
|
70
|
-
return nil unless cur.start_with?(str)
|
71
|
-
return nil if str =~ /\A[A-Za-z0-9_]+\Z/ && cur[str.size] =~ /[A-Za-z0-9_]/
|
72
|
-
|
73
|
-
@last_match_size = str.size
|
74
|
-
str
|
75
|
-
end
|
76
|
-
|
77
|
-
def fetch_ax
|
78
|
-
return :a if fetch_str('A')
|
79
|
-
return :x if fetch_str('X')
|
80
|
-
|
81
|
-
nil
|
82
|
-
end
|
83
|
-
|
84
|
-
def fetch_sys_num_arch_x
|
85
|
-
return :x if fetch_str('X')
|
86
|
-
|
87
|
-
fetch_number || fetch_syscall || fetch_arch
|
88
|
-
end
|
89
|
-
|
90
|
-
# Currently only supports 10-based decimal numbers.
|
91
|
-
def fetch_number
|
92
|
-
res = fetch_regexp(/^0x[0-9a-f]+/) || fetch_regexp(/^[0-9]+/)
|
93
|
-
return nil if res.nil?
|
94
|
-
|
95
|
-
Integer(res)
|
96
|
-
end
|
97
|
-
|
98
|
-
def fetch_syscall
|
99
|
-
sys = Const::Syscall::AMD64
|
100
|
-
sys = sys.merge(Const::Syscall::I386)
|
101
|
-
fetch_strs(sys.keys.map(&:to_s).sort_by(&:size).reverse)
|
102
|
-
end
|
103
|
-
|
104
|
-
def fetch_arch
|
105
|
-
fetch_strs(Const::Audit::ARCH.keys)
|
106
|
-
end
|
107
|
-
|
108
|
-
def fetch_regexp(regexp)
|
109
|
-
idx = cur =~ regexp
|
110
|
-
return nil if idx.nil? || idx != 0
|
111
|
-
|
112
|
-
match = cur.match(regexp)[0]
|
113
|
-
@last_match_size = match.size
|
114
|
-
match
|
115
|
-
end
|
116
|
-
|
117
|
-
def fetch_label
|
118
|
-
fetch_regexp(LABEL_REGEXP)
|
119
|
-
end
|
120
|
-
|
121
|
-
# Convert <type>(num) into return value according to {Const::ACTION}
|
122
|
-
# @return [Integer, :a]
|
123
|
-
def fetch_return
|
124
|
-
regexp = /(#{Const::BPF::ACTION.keys.join('|')})(\([0-9]{1,5}\))?/
|
125
|
-
action = fetch_regexp(regexp)
|
126
|
-
return fetch_str('A') && :a if action.nil?
|
127
|
-
|
128
|
-
# check if action contains '('the next bytes are (<num>)
|
129
|
-
ret_val = 0
|
130
|
-
if action.include?('(')
|
131
|
-
action, val = action.split('(')
|
132
|
-
ret_val = val.to_i
|
133
|
-
end
|
134
|
-
Const::BPF::ACTION[action.to_sym] | ret_val
|
135
|
-
end
|
136
|
-
|
137
|
-
def fetch_ary
|
138
|
-
support_name = %w[data mem args args_h]
|
139
|
-
regexp = /(#{support_name.join('|')})\[[0-9]{1,2}\]/
|
140
|
-
match = fetch_regexp(regexp)
|
141
|
-
return nil if match.nil?
|
142
|
-
|
143
|
-
res, val = match.split('[')
|
144
|
-
val = val.to_i
|
145
|
-
[res.to_sym, val]
|
146
|
-
end
|
147
|
-
|
148
|
-
def fetch_alu
|
149
|
-
ops = %w[+ - * / | & ^ << >>]
|
150
|
-
op = fetch_strs(ops)
|
151
|
-
return nil if op.nil?
|
152
|
-
|
153
|
-
Instruction::ALU::OP_SYM.invert[op.to_sym]
|
154
|
-
end
|
155
|
-
|
156
|
-
def slice!
|
157
|
-
ret = cur.slice!(0, @last_match_size)
|
158
|
-
cur.strip!
|
159
|
-
ret
|
160
|
-
end
|
161
|
-
|
162
|
-
def raise_expected(msg)
|
163
|
-
raise ArgumentError, <<-EOS
|
164
|
-
Expected #{msg} but found #{cur.split[0].inspect}.
|
165
|
-
EOS
|
166
|
-
end
|
167
|
-
end
|
168
|
-
end
|
169
|
-
end
|