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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e486ade31fe2b1da262f3636060b4d0b3947fb29
4
- data.tar.gz: c65f8074f25cb4b3806726a04d2c2377d44b3ec4
3
+ metadata.gz: 5c6965417440352f339d587caf0ee612604d7d0e
4
+ data.tar.gz: 294d2c627f26b1bf03581675d35412d13296f27b
5
5
  SHA512:
6
- metadata.gz: 4fbb16ae849bcfc0d17eb8bbcb36f4e7906adb3da00f8bcc31712b69a299e3d3a4f659227e1668f8809433f5c4805170fd79e4934c174a4c455438bca6973361
7
- data.tar.gz: a3aba5b768d38fe50f4533a60f7f9cc9d592429803a17728101f721d1aaaf767fcec270ffe59d08bd36763e542e48af48774a707d30dcba71d3920fc6a05123c
6
+ metadata.gz: cfc63e0881c0cb4c7852051a4a0b98f93935523674582a75d5fb4f904cbd81673cb86d0be9f31cb76ce2515fa29a42f53a8e81321f3063d0bddce3257cac9b95
7
+ data.tar.gz: '090dd0f577b52bc5494121420d8600b12018f857bcccd05be15849fd774de4e02abfdc1c36610d8908910f79cfe4153b2f0dd613d015e5aaa86e2f984844ab1f'
data/README.md CHANGED
@@ -6,16 +6,17 @@
6
6
  [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](http://choosealicense.com/licenses/mit/)
7
7
 
8
8
  # Seccomp Tools
9
- Provides powerful tools for seccomp analysis.
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 analysis of seccomp in real-case.
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 binary.
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 == 0xc000003e ? next : dead
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
  ![emu](https://github.com/david942j/seccomp-tools/blob/master/examples/emu-amigo.png?raw=true)
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 [stared](https://github.com/david942j/seccomp-tools/stargazers) :grimacing:
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 emit(:misc, :txa) if dst == :a && src == :x
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[0] == :mem
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 Const::Syscall.const_get(@arch.upcase.to_sym)[val.to_sym] if val.is_a?(String)
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 fetch_sys_num_x || raise_expected("a syscall number or 'X'")
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 fetch_sys_num_x
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,9}\]/
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('[')
@@ -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 needs to conitnue.
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
- output { disasm.shift }
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] & 0x7fff0000]
73
- errno = ret_type == :ERRNO ? "(#{res[:ret] & 0xffff})" : ''
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
@@ -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
- KILL: 0x00000000,
46
- TRAP: 0x00030000,
47
- ERRNO: 0x00050000,
48
- TRACE: 0x7ff00000,
49
- ALLOW: 0x7fff0000
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
@@ -74,7 +74,7 @@ module SeccompTools
74
74
  end
75
75
  !limit.zero?
76
76
  end
77
- syscalls.keys.each { |cpid| Process.kill('KILL', cpid) if alive?(cpid) }
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
- return cont
98
+ cont
99
99
  rescue Errno::ECHILD
100
- return false
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
- $stderr.puts("Failed to execute #{args.join(' ')}")
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 emulation seccomp.
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.send(op, src)
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).send(op, src))
103
+ set(:a, get(:a).__send__(op, src))
104
104
  end
105
105
  end
106
106
 
@@ -47,7 +47,7 @@ module SeccompTools
47
47
 
48
48
  %i(code jt jf k arch line contexts).each do |sym|
49
49
  define_method(sym) do
50
- @bpf.send(sym)
50
+ @bpf.__send__(sym)
51
51
  end
52
52
  end
53
53
  end
@@ -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 + goto(jt) + ' else ' + goto(jf) unless jt.zero? || jf.zero?
18
- return if_str + goto(jt) if jf.zero?
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 & 0x7fff0000].to_s
31
- str += "(#{type & 0xffff})" if str == 'ERRNO'
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
 
@@ -7,7 +7,9 @@ module SeccompTools
7
7
  # @return [Array<Symbol>]
8
8
  # Architectures.
9
9
  def supported_archs
10
- @archs ||= Dir.glob(File.join(__dir__, 'consts', '*.rb')).map { |f| File.basename(f, '.rb').to_sym }.sort
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.
@@ -1,4 +1,4 @@
1
1
  module SeccompTools
2
2
  # Gem version.
3
- VERSION = '1.1.1'.freeze
3
+ VERSION = '1.2.0'.freeze
4
4
  end
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.1.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: 2017-12-01 00:00:00.000000000 Z
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.5'
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.5'
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.49'
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.49'
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.13.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.13.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.13
177
+ rubygems_version: 2.6.14
192
178
  signing_key:
193
179
  specification_version: 4
194
180
  summary: seccomp-tools