seccomp-tools 1.1.1 → 1.2.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 +9 -7
- data/lib/seccomp-tools/asm/compiler.rb +12 -6
- data/lib/seccomp-tools/asm/tokenizer.rb +8 -4
- data/lib/seccomp-tools/bpf.rb +2 -1
- data/lib/seccomp-tools/cli/base.rb +1 -1
- data/lib/seccomp-tools/cli/dump.rb +1 -1
- data/lib/seccomp-tools/cli/emu.rb +25 -16
- data/lib/seccomp-tools/const.rb +17 -5
- data/lib/seccomp-tools/dumper.rb +5 -5
- data/lib/seccomp-tools/emulator.rb +3 -3
- data/lib/seccomp-tools/instruction/base.rb +1 -1
- data/lib/seccomp-tools/instruction/jmp.rb +3 -4
- data/lib/seccomp-tools/instruction/ret.rb +2 -2
- data/lib/seccomp-tools/syscall.rb +5 -3
- data/lib/seccomp-tools/util.rb +3 -1
- data/lib/seccomp-tools/version.rb +1 -1
- metadata +9 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5c6965417440352f339d587caf0ee612604d7d0e
|
4
|
+
data.tar.gz: 294d2c627f26b1bf03581675d35412d13296f27b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cfc63e0881c0cb4c7852051a4a0b98f93935523674582a75d5fb4f904cbd81673cb86d0be9f31cb76ce2515fa29a42f53a8e81321f3063d0bddce3257cac9b95
|
7
|
+
data.tar.gz: '090dd0f577b52bc5494121420d8600b12018f857bcccd05be15849fd774de4e02abfdc1c36610d8908910f79cfe4153b2f0dd613d015e5aaa86e2f984844ab1f'
|
data/README.md
CHANGED
@@ -6,16 +6,17 @@
|
|
6
6
|
[](http://choosealicense.com/licenses/mit/)
|
7
7
|
|
8
8
|
# Seccomp Tools
|
9
|
-
|
9
|
+
Provide powerful tools for seccomp analysis.
|
10
10
|
|
11
11
|
This project is targeted to (but not limited to) analyze seccomp sandbox in CTF pwn challenges.
|
12
|
-
Some features might be CTF-specific, but still useful for
|
12
|
+
Some features might be CTF-specific, but still useful for analyzing seccomp in real-case.
|
13
13
|
|
14
14
|
## Features
|
15
|
-
* Dump - Automatically dump seccomp-bpf from
|
15
|
+
* Dump - Automatically dump seccomp-bpf from execution file(s).
|
16
16
|
* Disasm - Convert bpf to human readable format.
|
17
17
|
- Simple decompile.
|
18
18
|
- Show syscall names.
|
19
|
+
- Colorful!
|
19
20
|
* Asm - Write seccomp rules is so easy!
|
20
21
|
* Emu - Emulate seccomp rules.
|
21
22
|
* (TODO) Solve constraints for executing syscalls (e.g. `execve/open/read/write`).
|
@@ -40,13 +41,13 @@ $ seccomp-tools --help
|
|
40
41
|
#
|
41
42
|
# asm Seccomp bpf assembler.
|
42
43
|
# disasm Disassemble seccomp bpf.
|
43
|
-
# dump Automatically dump seccomp bpf from execution file.
|
44
|
+
# dump Automatically dump seccomp bpf from execution file(s).
|
44
45
|
# emu Emulate seccomp rules.
|
45
46
|
#
|
46
47
|
# See 'seccomp-tools <command> --help' to read about a specific subcommand.
|
47
48
|
|
48
49
|
$ seccomp-tools dump --help
|
49
|
-
# dump - Automatically dump seccomp bpf from execution file.
|
50
|
+
# dump - Automatically dump seccomp bpf from execution file(s).
|
50
51
|
#
|
51
52
|
# Usage: seccomp-tools dump [exec] [options]
|
52
53
|
# -c, --sh-exec <command> Executes the given command (via sh).
|
@@ -166,7 +167,7 @@ $ seccomp-tools asm
|
|
166
167
|
$ cat spec/data/libseccomp.asm
|
167
168
|
# # check if arch is X86_64
|
168
169
|
# A = arch
|
169
|
-
# A ==
|
170
|
+
# A == ARCH_X86_64 ? next : dead
|
170
171
|
# A = sys_number
|
171
172
|
# A >= 0x40000000 ? dead : next
|
172
173
|
# A == write ? ok : next
|
@@ -246,6 +247,7 @@ $ seccomp-tools emu spec/data/libseccomp.bpf 0x3
|
|
246
247
|

|
247
248
|
|
248
249
|
## I Need You
|
250
|
+
|
249
251
|
Any suggestion or feature request is welcome!
|
250
252
|
Feel free to file an issue or send a pull request.
|
251
|
-
And, if you like this work, I'll be happy to be [
|
253
|
+
And, if you like this work, I'll be happy to be [starred](https://github.com/david942j/seccomp-tools/stargazers) :grimacing:
|
@@ -42,7 +42,6 @@ module SeccompTools
|
|
42
42
|
else
|
43
43
|
@insts << res
|
44
44
|
end
|
45
|
-
res
|
46
45
|
end
|
47
46
|
|
48
47
|
# @return [Array<SeccompTools::BPF>]
|
@@ -84,11 +83,10 @@ module SeccompTools
|
|
84
83
|
# mem[i] = <A|X>
|
85
84
|
def compile_assign(dst, src)
|
86
85
|
# misc txa / tax
|
87
|
-
return
|
88
|
-
return emit(:misc, :tax) if dst == :x && src == :a
|
89
|
-
src = evaluate(src)
|
86
|
+
return compile_assign_misc(dst, src) if (dst == :a && src == :x) || (dst == :x && src == :a)
|
90
87
|
# case of st / stx
|
91
|
-
return emit(src == :x ? :stx : :st, k: dst.last) if dst
|
88
|
+
return emit(src == :x ? :stx : :st, k: dst.last) if dst.is_a?(Array) && dst.first == :mem
|
89
|
+
src = evaluate(src)
|
92
90
|
ld = dst == :x ? :ldx : :ld
|
93
91
|
# <A|X> = <immi>
|
94
92
|
return emit(ld, :imm, k: src) if src.is_a?(Integer)
|
@@ -99,6 +97,10 @@ module SeccompTools
|
|
99
97
|
emit(ld, :abs, k: src.last)
|
100
98
|
end
|
101
99
|
|
100
|
+
def compile_assign_misc(dst, _src)
|
101
|
+
emit(:misc, dst == :a ? :txa : :tax)
|
102
|
+
end
|
103
|
+
|
102
104
|
def compile_alu(op, val)
|
103
105
|
val = evaluate(val)
|
104
106
|
src = val == :x ? :x : :k
|
@@ -138,13 +140,17 @@ module SeccompTools
|
|
138
140
|
when 'arch' then [:data, 4]
|
139
141
|
else val
|
140
142
|
end
|
141
|
-
return
|
143
|
+
return eval_constants(val) if val.is_a?(String)
|
142
144
|
# remains are [:mem/:data/:args, <num>]
|
143
145
|
# first convert args to data
|
144
146
|
val = [:data, val.last * 8 + 16] if val.first == :args
|
145
147
|
val
|
146
148
|
end
|
147
149
|
|
150
|
+
def eval_constants(str)
|
151
|
+
Const::Syscall.const_get(@arch.upcase.to_sym)[str.to_sym] || Const::Audit::ARCH[str]
|
152
|
+
end
|
153
|
+
|
148
154
|
attr_reader :token
|
149
155
|
|
150
156
|
# A <comparison> <sys_str|X|Integer> ? <label|Integer> : <label|Integer>
|
@@ -40,7 +40,7 @@ module SeccompTools
|
|
40
40
|
res = case type
|
41
41
|
when String then fetch_str(type) || raise_expected("token #{type.inspect}")
|
42
42
|
when :comparison then fetch_strs(COMPARISON).to_sym || raise_expected('a comparison operator')
|
43
|
-
when :sys_num_x then
|
43
|
+
when :sys_num_x then fetch_sys_num_arch_x || raise_expected("a syscall number or 'X'")
|
44
44
|
when :goto then fetch_number || fetch_label || raise_expected('a number or label name')
|
45
45
|
when :ret then fetch_return || raise(ArgumentError, <<-EOS)
|
46
46
|
Invalid return type: #{cur.inspect}.
|
@@ -74,9 +74,9 @@ Invalid return type: #{cur.inspect}.
|
|
74
74
|
nil
|
75
75
|
end
|
76
76
|
|
77
|
-
def
|
77
|
+
def fetch_sys_num_arch_x
|
78
78
|
return :x if fetch_str('X')
|
79
|
-
fetch_number || fetch_syscall
|
79
|
+
fetch_number || fetch_syscall || fetch_arch
|
80
80
|
end
|
81
81
|
|
82
82
|
# Currently only supports 10-based decimal numbers.
|
@@ -92,6 +92,10 @@ Invalid return type: #{cur.inspect}.
|
|
92
92
|
fetch_strs(sys.keys.map(&:to_s).sort_by(&:size).reverse)
|
93
93
|
end
|
94
94
|
|
95
|
+
def fetch_arch
|
96
|
+
fetch_strs(Const::Audit::ARCH.keys)
|
97
|
+
end
|
98
|
+
|
95
99
|
def fetch_regexp(regexp)
|
96
100
|
idx = cur =~ regexp
|
97
101
|
return nil if idx.nil? || idx != 0
|
@@ -121,7 +125,7 @@ Invalid return type: #{cur.inspect}.
|
|
121
125
|
|
122
126
|
def fetch_ary
|
123
127
|
support_name = %w[data mem args]
|
124
|
-
regexp = /(#{support_name.join('|')})\[[0-9]{1,
|
128
|
+
regexp = /(#{support_name.join('|')})\[[0-9]{1,2}\]/
|
125
129
|
match = fetch_regexp(regexp)
|
126
130
|
return nil if match.nil?
|
127
131
|
res, val = match.split('[')
|
data/lib/seccomp-tools/bpf.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'set'
|
2
|
+
require 'stringio'
|
2
3
|
|
3
4
|
require 'seccomp-tools/const'
|
4
5
|
require 'seccomp-tools/instruction/instruction'
|
@@ -30,7 +31,7 @@ module SeccompTools
|
|
30
31
|
# Line number of this filter.
|
31
32
|
def initialize(raw, arch, line)
|
32
33
|
if raw.is_a?(String)
|
33
|
-
io = StringIO.new(raw)
|
34
|
+
io = ::StringIO.new(raw)
|
34
35
|
@code = io.read(2).unpack('S').first
|
35
36
|
@jt = io.read(1).ord
|
36
37
|
@jf = io.read(1).ord
|
@@ -23,7 +23,7 @@ module SeccompTools
|
|
23
23
|
|
24
24
|
# Handle show help message.
|
25
25
|
# @return [Boolean]
|
26
|
-
# For decestors to check if
|
26
|
+
# For decestors to check if need to continue.
|
27
27
|
def handle
|
28
28
|
return CLI.show(parser.help) if argv.empty? || %w[-h --help].any? { |h| argv.include?(h) }
|
29
29
|
parser.parse!(argv)
|
@@ -7,7 +7,7 @@ module SeccompTools
|
|
7
7
|
# Handle 'dump' command.
|
8
8
|
class Dump < Base
|
9
9
|
# Summary of this command.
|
10
|
-
SUMMARY = 'Automatically dump seccomp bpf from execution file.'.freeze
|
10
|
+
SUMMARY = 'Automatically dump seccomp bpf from execution file(s).'.freeze
|
11
11
|
# Usage of this command.
|
12
12
|
USAGE = ('dump - ' + SUMMARY + "\n\n" + 'Usage: seccomp-tools dump [exec] [options]').freeze
|
13
13
|
|
@@ -44,7 +44,6 @@ module SeccompTools
|
|
44
44
|
return CLI.show(parser.help) if option[:ifile].nil?
|
45
45
|
raw = input
|
46
46
|
insts = SeccompTools::Disasm.to_bpf(raw, option[:arch]).map(&:inst)
|
47
|
-
disasm = SeccompTools::Disasm.disasm(raw, arch: option[:arch])
|
48
47
|
sys, *args = argv
|
49
48
|
sys = Integer(sys) if sys
|
50
49
|
args.map! { |v| Integer(v) }
|
@@ -54,26 +53,36 @@ module SeccompTools
|
|
54
53
|
end
|
55
54
|
|
56
55
|
if option[:verbose] >= 1
|
57
|
-
disasm = disasm.lines
|
58
|
-
|
59
|
-
output { disasm.shift }
|
60
|
-
disasm.each_with_index do |line, idx|
|
61
|
-
output do
|
62
|
-
next line if trace.member?(idx)
|
63
|
-
Util.colorize(line, t: :gray)
|
64
|
-
end
|
65
|
-
# Too much remain, omit them.
|
66
|
-
rem = disasm.size - idx - 1
|
67
|
-
break output { Util.colorize("... (omitting #{rem} lines)\n", t: :gray) } if rem > 3 && idx > res[:pc] + 4
|
68
|
-
end
|
69
|
-
output { "\n" }
|
56
|
+
disasm = SeccompTools::Disasm.disasm(raw, arch: option[:arch]).lines
|
57
|
+
output_emulate_path(disasm, trace, res)
|
70
58
|
end
|
71
59
|
output do
|
72
|
-
ret_type = Const::BPF::ACTION.invert[res[:ret] &
|
73
|
-
errno = ret_type == :ERRNO ? "(#{res[:ret] &
|
60
|
+
ret_type = Const::BPF::ACTION.invert[res[:ret] & Const::BPF::SECCOMP_RET_ACTION_FULL]
|
61
|
+
errno = ret_type == :ERRNO ? "(#{res[:ret] & Const::BPF::SECCOMP_RET_DATA})" : ''
|
74
62
|
format("return %s%s at line %04d\n", ret_type, errno, res[:pc])
|
75
63
|
end
|
76
64
|
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
# output the path during emulation
|
69
|
+
# @param [Array<String>] disasm
|
70
|
+
# @param [Set] trace
|
71
|
+
# @param [{Symbol => Object}] result
|
72
|
+
def output_emulate_path(disasm, trace, result)
|
73
|
+
output { disasm.shift }
|
74
|
+
output { disasm.shift }
|
75
|
+
disasm.each_with_index do |line, idx|
|
76
|
+
output do
|
77
|
+
next line if trace.member?(idx)
|
78
|
+
Util.colorize(line, t: :gray)
|
79
|
+
end
|
80
|
+
# Too much remain, omit them.
|
81
|
+
rem = disasm.size - idx - 1
|
82
|
+
break output { Util.colorize("... (omitting #{rem} lines)\n", t: :gray) } if rem > 3 && idx > result[:pc] + 4
|
83
|
+
end
|
84
|
+
output { "\n" }
|
85
|
+
end
|
77
86
|
end
|
78
87
|
end
|
79
88
|
end
|
data/lib/seccomp-tools/const.rb
CHANGED
@@ -12,6 +12,16 @@ module SeccompTools
|
|
12
12
|
# filter mode
|
13
13
|
SECCOMP_MODE_FILTER = 2
|
14
14
|
|
15
|
+
# For syscall +seccomp+
|
16
|
+
SECCOMP_SET_MODE_FILTER = 1
|
17
|
+
|
18
|
+
# Masks for the return value sections.
|
19
|
+
|
20
|
+
# mask of return action
|
21
|
+
SECCOMP_RET_ACTION_FULL = 0xffff0000
|
22
|
+
# mask of return data
|
23
|
+
SECCOMP_RET_DATA = 0x0000ffff
|
24
|
+
|
15
25
|
# bpf command classes
|
16
26
|
COMMAND = {
|
17
27
|
ld: 0x0,
|
@@ -42,11 +52,13 @@ module SeccompTools
|
|
42
52
|
|
43
53
|
# seccomp action values
|
44
54
|
ACTION = {
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
55
|
+
KILL_PROCESS: 0x80000000,
|
56
|
+
KILL_THREAD: 0x00000000,
|
57
|
+
KILL: 0x00000000, # alias of KILL_THREAD
|
58
|
+
TRAP: 0x00030000,
|
59
|
+
ERRNO: 0x00050000,
|
60
|
+
TRACE: 0x7ff00000,
|
61
|
+
ALLOW: 0x7fff0000
|
50
62
|
}.freeze
|
51
63
|
|
52
64
|
# mode used in ld / ldx
|
data/lib/seccomp-tools/dumper.rb
CHANGED
@@ -74,7 +74,7 @@ module SeccompTools
|
|
74
74
|
end
|
75
75
|
!limit.zero?
|
76
76
|
end
|
77
|
-
syscalls.
|
77
|
+
syscalls.each_key { |cpid| Process.kill('KILL', cpid) if alive?(cpid) }
|
78
78
|
collect
|
79
79
|
end
|
80
80
|
|
@@ -95,9 +95,9 @@ module SeccompTools
|
|
95
95
|
cont = yield(child)
|
96
96
|
end
|
97
97
|
Ptrace.syscall(child, 0, 0) unless status.exited?
|
98
|
-
|
98
|
+
cont
|
99
99
|
rescue Errno::ECHILD
|
100
|
-
|
100
|
+
false
|
101
101
|
end
|
102
102
|
|
103
103
|
# @return [SeccompTools::Syscall]
|
@@ -119,9 +119,9 @@ module SeccompTools
|
|
119
119
|
def handle_child(*args)
|
120
120
|
Ptrace.traceme_and_stop
|
121
121
|
exec(*args)
|
122
|
-
rescue # exec fail
|
122
|
+
rescue # rubocop:disable Style/RescueStandardError # exec fail
|
123
123
|
# TODO: use logger
|
124
|
-
|
124
|
+
warn("Failed to execute #{args.join(' ')}")
|
125
125
|
exit(1)
|
126
126
|
end
|
127
127
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'seccomp-tools/const'
|
2
2
|
|
3
3
|
module SeccompTools
|
4
|
-
# For
|
4
|
+
# For emulating seccomp.
|
5
5
|
class Emulator
|
6
6
|
# Instantiate a {Emulator} object.
|
7
7
|
#
|
@@ -89,7 +89,7 @@ module SeccompTools
|
|
89
89
|
def cmp(op, src, jt, jf)
|
90
90
|
src = get(:x) if src == :x
|
91
91
|
a = get(:a)
|
92
|
-
val = a.
|
92
|
+
val = a.__send__(op, src)
|
93
93
|
val = (val != 0) if val.is_a?(Integer) # handle & operator
|
94
94
|
j = val ? jt : jf
|
95
95
|
set(:pc, get(:pc) + j + 1)
|
@@ -100,7 +100,7 @@ module SeccompTools
|
|
100
100
|
set(:a, 2**32 - get(:a))
|
101
101
|
else
|
102
102
|
src = get(:x) if src == :x
|
103
|
-
set(:a, get(:a).
|
103
|
+
set(:a, get(:a).__send__(op, src))
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
@@ -9,14 +9,13 @@ module SeccompTools
|
|
9
9
|
def decompile
|
10
10
|
return goto(k) if jop == :none
|
11
11
|
# if jt == 0 && jf == 0 => no-op # should not happen
|
12
|
-
# jt == 0 => if(!) goto jf
|
12
|
+
# jt == 0 => if(!) goto jf;
|
13
13
|
# jf == 0 => if() goto jt;
|
14
14
|
# otherwise => if () goto jt; else goto jf;
|
15
15
|
return '/* no-op */' if jt.zero? && jf.zero?
|
16
16
|
return goto(jt) if jt == jf
|
17
|
-
return if_str
|
18
|
-
|
19
|
-
if_str(true) + goto(jf)
|
17
|
+
return if_str(true) + goto(jf) if jt.zero?
|
18
|
+
if_str + goto(jt) + (jf.zero? ? '' : ' else ' + goto(jf))
|
20
19
|
end
|
21
20
|
|
22
21
|
# See {Instruction::Base#symbolize}.
|
@@ -27,8 +27,8 @@ module SeccompTools
|
|
27
27
|
def ret_str
|
28
28
|
_, type = symbolize
|
29
29
|
return 'A' if type == :a
|
30
|
-
str = ACTION.invert[type &
|
31
|
-
str
|
30
|
+
str = ACTION.invert[type & SECCOMP_RET_ACTION_FULL].to_s
|
31
|
+
str << "(#{type & SECCOMP_RET_DATA})" if str == 'ERRNO'
|
32
32
|
str
|
33
33
|
end
|
34
34
|
end
|
@@ -6,7 +6,7 @@ module SeccompTools
|
|
6
6
|
class Syscall
|
7
7
|
# Syscall arguments offset of +struct user+ in different arch.
|
8
8
|
ABI = {
|
9
|
-
amd64: { number: 120, args: [112, 104, 96, 56, 72, 44], ret: 80, SYS_prctl: 157 },
|
9
|
+
amd64: { number: 120, args: [112, 104, 96, 56, 72, 44], ret: 80, SYS_prctl: 157, SYS_seccomp: 317 },
|
10
10
|
i386: { number: 120, args: [40, 88, 96, 104, 112, 32], ret: 80, SYS_prctl: 172 }
|
11
11
|
}.freeze
|
12
12
|
|
@@ -33,11 +33,13 @@ module SeccompTools
|
|
33
33
|
@ret = peek(abi[:ret])
|
34
34
|
end
|
35
35
|
|
36
|
-
# Is this a +prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, addr)+ syscall?
|
36
|
+
# Is this a +seccomp(SECCOMP_MODE_FILTER, addr)+/+prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, addr)+ syscall?
|
37
|
+
#
|
37
38
|
# @return [Boolean]
|
38
39
|
# +true+ for is a seccomp installation syscall.
|
39
40
|
def set_seccomp?
|
40
|
-
# TODO: handle SECCOMP_MODE_STRICT
|
41
|
+
# TODO: handle SECCOMP_MODE_SET_STRICT / SECCOMP_MODE_STRICT
|
42
|
+
return true if number == abi[:SYS_seccomp] && args[0] == Const::BPF::SECCOMP_SET_MODE_FILTER
|
41
43
|
number == abi[:SYS_prctl] && args[0] == Const::BPF::PR_SET_SECCOMP && args[1] == Const::BPF::SECCOMP_MODE_FILTER
|
42
44
|
end
|
43
45
|
|
data/lib/seccomp-tools/util.rb
CHANGED
@@ -7,7 +7,9 @@ module SeccompTools
|
|
7
7
|
# @return [Array<Symbol>]
|
8
8
|
# Architectures.
|
9
9
|
def supported_archs
|
10
|
-
@
|
10
|
+
@supported_archs ||= Dir.glob(File.join(__dir__, 'consts', '*.rb'))
|
11
|
+
.map { |f| File.basename(f, '.rb').to_sym }
|
12
|
+
.sort
|
11
13
|
end
|
12
14
|
|
13
15
|
# Detect system architecture.
|
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: seccomp-tools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.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: 2018-04-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: codeclimate-test-reporter
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0.6'
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0.6'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: pry
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,42 +58,42 @@ dependencies:
|
|
72
58
|
requirements:
|
73
59
|
- - "~>"
|
74
60
|
- !ruby/object:Gem::Version
|
75
|
-
version: '3.
|
61
|
+
version: '3.7'
|
76
62
|
type: :development
|
77
63
|
prerelease: false
|
78
64
|
version_requirements: !ruby/object:Gem::Requirement
|
79
65
|
requirements:
|
80
66
|
- - "~>"
|
81
67
|
- !ruby/object:Gem::Version
|
82
|
-
version: '3.
|
68
|
+
version: '3.7'
|
83
69
|
- !ruby/object:Gem::Dependency
|
84
70
|
name: rubocop
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
86
72
|
requirements:
|
87
73
|
- - "~>"
|
88
74
|
- !ruby/object:Gem::Version
|
89
|
-
version: '0.
|
75
|
+
version: '0.54'
|
90
76
|
type: :development
|
91
77
|
prerelease: false
|
92
78
|
version_requirements: !ruby/object:Gem::Requirement
|
93
79
|
requirements:
|
94
80
|
- - "~>"
|
95
81
|
- !ruby/object:Gem::Version
|
96
|
-
version: '0.
|
82
|
+
version: '0.54'
|
97
83
|
- !ruby/object:Gem::Dependency
|
98
84
|
name: simplecov
|
99
85
|
requirement: !ruby/object:Gem::Requirement
|
100
86
|
requirements:
|
101
87
|
- - "~>"
|
102
88
|
- !ruby/object:Gem::Version
|
103
|
-
version: 0.
|
89
|
+
version: 0.16.0
|
104
90
|
type: :development
|
105
91
|
prerelease: false
|
106
92
|
version_requirements: !ruby/object:Gem::Requirement
|
107
93
|
requirements:
|
108
94
|
- - "~>"
|
109
95
|
- !ruby/object:Gem::Version
|
110
|
-
version: 0.
|
96
|
+
version: 0.16.0
|
111
97
|
- !ruby/object:Gem::Dependency
|
112
98
|
name: yard
|
113
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -188,7 +174,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
188
174
|
version: '0'
|
189
175
|
requirements: []
|
190
176
|
rubyforge_project:
|
191
|
-
rubygems_version: 2.6.
|
177
|
+
rubygems_version: 2.6.14
|
192
178
|
signing_key:
|
193
179
|
specification_version: 4
|
194
180
|
summary: seccomp-tools
|