seccomp-tools 1.2.0 → 1.3.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.
Files changed (40) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +84 -17
  3. data/bin/seccomp-tools +1 -0
  4. data/ext/ptrace/ptrace.c +8 -1
  5. data/lib/seccomp-tools.rb +2 -0
  6. data/lib/seccomp-tools/asm/asm.rb +4 -1
  7. data/lib/seccomp-tools/asm/compiler.rb +61 -10
  8. data/lib/seccomp-tools/asm/tokenizer.rb +15 -3
  9. data/lib/seccomp-tools/bpf.rb +2 -0
  10. data/lib/seccomp-tools/cli/asm.rb +14 -4
  11. data/lib/seccomp-tools/cli/base.rb +5 -0
  12. data/lib/seccomp-tools/cli/cli.rb +6 -3
  13. data/lib/seccomp-tools/cli/disasm.rb +5 -1
  14. data/lib/seccomp-tools/cli/dump.rb +4 -1
  15. data/lib/seccomp-tools/cli/emu.rb +15 -2
  16. data/lib/seccomp-tools/const.rb +25 -19
  17. data/lib/seccomp-tools/consts/sys_arg.rb +432 -0
  18. data/lib/seccomp-tools/consts/{amd64.rb → sys_nr/amd64.rb} +4 -2
  19. data/lib/seccomp-tools/consts/{i386.rb → sys_nr/i386.rb} +5 -2
  20. data/lib/seccomp-tools/disasm/context.rb +125 -34
  21. data/lib/seccomp-tools/disasm/disasm.rb +4 -2
  22. data/lib/seccomp-tools/dumper.rb +4 -0
  23. data/lib/seccomp-tools/emulator.rb +10 -0
  24. data/lib/seccomp-tools/instruction/alu.rb +6 -1
  25. data/lib/seccomp-tools/instruction/base.rb +4 -2
  26. data/lib/seccomp-tools/instruction/instruction.rb +2 -0
  27. data/lib/seccomp-tools/instruction/jmp.rb +12 -2
  28. data/lib/seccomp-tools/instruction/ld.rb +27 -11
  29. data/lib/seccomp-tools/instruction/ldx.rb +2 -0
  30. data/lib/seccomp-tools/instruction/misc.rb +2 -0
  31. data/lib/seccomp-tools/instruction/ret.rb +3 -0
  32. data/lib/seccomp-tools/instruction/st.rb +3 -1
  33. data/lib/seccomp-tools/instruction/stx.rb +2 -0
  34. data/lib/seccomp-tools/syscall.rb +5 -1
  35. data/lib/seccomp-tools/templates/asm.amd64.asm +26 -0
  36. data/lib/seccomp-tools/templates/asm.c +17 -0
  37. data/lib/seccomp-tools/templates/asm.i386.asm +33 -0
  38. data/lib/seccomp-tools/util.rb +16 -1
  39. data/lib/seccomp-tools/version.rb +3 -1
  40. metadata +18 -11
@@ -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
@@ -10,6 +14,7 @@ module SeccompTools
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
- nctx = context.dup
34
- type = load_val
35
- nctx[reg] = case type[:rel]
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 this mode
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
- idx.even? ? "args[#{idx / 2}]" : "args[#{idx / 2}] >> 32"
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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'seccomp-tools/instruction/ld'
2
4
 
3
5
  module SeccompTools
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'seccomp-tools/instruction/base'
2
4
 
3
5
  module SeccompTools
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'seccomp-tools/instruction/base'
2
4
 
3
5
  module SeccompTools
@@ -27,6 +29,7 @@ module SeccompTools
27
29
  def ret_str
28
30
  _, type = symbolize
29
31
  return 'A' if type == :a
32
+
30
33
  str = ACTION.invert[type & SECCOMP_RET_ACTION_FULL].to_s
31
34
  str << "(#{type & SECCOMP_RET_DATA})" if str == 'ERRNO'
32
35
  str
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'seccomp-tools/instruction/ld'
2
4
 
3
5
  module SeccompTools
@@ -18,7 +20,7 @@ module SeccompTools
18
20
  # @return [Array<(Integer, Context)>]
19
21
  def branch(context)
20
22
  ctx = context.dup
21
- ctx[k] = ctx[reg]
23
+ ctx.store(k, reg)
22
24
  [[line + 1, ctx]]
23
25
  end
24
26
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'seccomp-tools/instruction/st'
2
4
 
3
5
  module SeccompTools
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'seccomp-tools/const'
2
4
  require 'seccomp-tools/ptrace'
3
5
 
@@ -7,7 +9,7 @@ module SeccompTools
7
9
  # Syscall arguments offset of +struct user+ in different arch.
8
10
  ABI = {
9
11
  amd64: { number: 120, args: [112, 104, 96, 56, 72, 44], ret: 80, SYS_prctl: 157, SYS_seccomp: 317 },
10
- i386: { number: 120, args: [40, 88, 96, 104, 112, 32], ret: 80, SYS_prctl: 172 }
12
+ i386: { number: 120, args: [40, 88, 96, 104, 112, 32], ret: 80, SYS_prctl: 172, SYS_seccomp: 354 }
11
13
  }.freeze
12
14
 
13
15
  # @return [Integer] Process id.
@@ -27,6 +29,7 @@ module SeccompTools
27
29
  def initialize(pid)
28
30
  @pid = pid
29
31
  raise ArgumentError, "Only supports #{ABI.keys.join(', ')}" if ABI[arch].nil?
32
+
30
33
  @abi = ABI[arch]
31
34
  @number = peek(abi[:number])
32
35
  @args = abi[:args].map { |off| peek(off) }
@@ -40,6 +43,7 @@ module SeccompTools
40
43
  def set_seccomp?
41
44
  # TODO: handle SECCOMP_MODE_SET_STRICT / SECCOMP_MODE_STRICT
42
45
  return true if number == abi[:SYS_seccomp] && args[0] == Const::BPF::SECCOMP_SET_MODE_FILTER
46
+
43
47
  number == abi[:SYS_prctl] && args[0] == Const::BPF::PR_SET_SECCOMP && args[1] == Const::BPF::SECCOMP_MODE_FILTER
44
48
  end
45
49
 
@@ -0,0 +1,26 @@
1
+ install_seccomp:
2
+ push rbp
3
+ mov rbp, rsp
4
+ push 38
5
+ pop rdi
6
+ push 0x1
7
+ pop rsi
8
+ xor eax, eax
9
+ mov al, 0x9d
10
+ syscall
11
+ push 22
12
+ pop rdi
13
+ lea rdx, [rip + _filter]
14
+ push rdx /* .filter */
15
+ push _filter_end - _filter >> 3 /* .len */
16
+ mov rdx, rsp
17
+ push 0x2
18
+ pop rsi
19
+ xor eax, eax
20
+ mov al, 0x9d
21
+ syscall
22
+ leave
23
+ ret
24
+ _filter:
25
+ .ascii "<TO_BE_REPLACED>"
26
+ _filter_end:
@@ -0,0 +1,17 @@
1
+ #include <linux/seccomp.h>
2
+ #include <stdio.h>
3
+ #include <stdlib.h>
4
+ #include <sys/prctl.h>
5
+
6
+ static void install_seccomp() {
7
+ static unsigned char filter[] = {<TO_BE_REPLACED>};
8
+ struct prog {
9
+ unsigned short len;
10
+ unsigned char *filter;
11
+ } rule = {
12
+ .len = sizeof(filter) >> 3,
13
+ .filter = filter
14
+ };
15
+ if(prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) { perror("prctl(PR_SET_NO_NEW_PRIVS)"); exit(2); }
16
+ if(prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &rule) < 0) { perror("prctl(PR_SET_SECCOMP)"); exit(2); }
17
+ }
@@ -0,0 +1,33 @@
1
+ install_seccomp:
2
+ push ebx
3
+ push ebp
4
+ mov ebp, esp
5
+ push 38
6
+ pop ebx
7
+ push 0x1
8
+ pop ecx
9
+ xor eax, eax
10
+ mov al, 0xac
11
+ int 0x80
12
+ push 22
13
+ pop ebx
14
+ jmp __get_eip__
15
+ __back__:
16
+ pop edx
17
+ push edx /* .filter */
18
+ mov edx, _filter_end - _filter >> 3 /* .len */
19
+ push edx
20
+ mov edx, esp
21
+ push 0x2
22
+ pop ecx
23
+ xor eax, eax
24
+ mov al, 0xac
25
+ int 0x80
26
+ leave
27
+ pop ebx
28
+ ret
29
+ __get_eip__:
30
+ call __back__
31
+ _filter:
32
+ .ascii "<TO_BE_REPLACED>"
33
+ _filter_end:
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SeccompTools
2
4
  # Define utility methods.
3
5
  module Util
@@ -7,7 +9,7 @@ module SeccompTools
7
9
  # @return [Array<Symbol>]
8
10
  # Architectures.
9
11
  def supported_archs
10
- @supported_archs ||= Dir.glob(File.join(__dir__, 'consts', '*.rb'))
12
+ @supported_archs ||= Dir.glob(File.join(__dir__, 'consts', 'sys_nr', '*.rb'))
11
13
  .map { |f| File.basename(f, '.rb').to_sym }
12
14
  .sort
13
15
  end
@@ -45,6 +47,7 @@ module SeccompTools
45
47
  esc_m: "\e[0m",
46
48
  syscall: "\e[38;5;120m", # light green
47
49
  arch: "\e[38;5;230m", # light yellow
50
+ args: "\e[38;5;230m", # light yellow, same as arch
48
51
  gray: "\e[2m"
49
52
  }.freeze
50
53
  # Wrapper color codes.
@@ -57,9 +60,21 @@ module SeccompTools
57
60
  def colorize(s, t: nil)
58
61
  s = s.to_s
59
62
  return s unless colorize_enabled?
63
+
60
64
  cc = COLOR_CODE
61
65
  color = cc[t]
62
66
  "#{color}#{s.sub(cc[:esc_m], cc[:esc_m] + color)}#{cc[:esc_m]}"
63
67
  end
68
+
69
+ # Get content of filename under directory templates/.
70
+ #
71
+ # @param [String] filename
72
+ # The filename.
73
+ #
74
+ # @return [String]
75
+ # Content of the file.
76
+ def template(filename)
77
+ IO.binread(File.join(__dir__, 'templates', filename))
78
+ end
64
79
  end
65
80
  end
@@ -1,4 +1,6 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SeccompTools
2
4
  # Gem version.
3
- VERSION = '1.2.0'.freeze
5
+ VERSION = '1.3.0'
4
6
  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.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - david942j
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-04-05 00:00:00.000000000 Z
11
+ date: 2019-06-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry
@@ -72,14 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '0.54'
75
+ version: '0.59'
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.54'
82
+ version: '0.59'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: simplecov
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -135,8 +135,9 @@ files:
135
135
  - lib/seccomp-tools/cli/dump.rb
136
136
  - lib/seccomp-tools/cli/emu.rb
137
137
  - lib/seccomp-tools/const.rb
138
- - lib/seccomp-tools/consts/amd64.rb
139
- - lib/seccomp-tools/consts/i386.rb
138
+ - lib/seccomp-tools/consts/sys_arg.rb
139
+ - lib/seccomp-tools/consts/sys_nr/amd64.rb
140
+ - lib/seccomp-tools/consts/sys_nr/i386.rb
140
141
  - lib/seccomp-tools/disasm/context.rb
141
142
  - lib/seccomp-tools/disasm/disasm.rb
142
143
  - lib/seccomp-tools/dumper.rb
@@ -152,12 +153,19 @@ files:
152
153
  - lib/seccomp-tools/instruction/st.rb
153
154
  - lib/seccomp-tools/instruction/stx.rb
154
155
  - lib/seccomp-tools/syscall.rb
156
+ - lib/seccomp-tools/templates/asm.amd64.asm
157
+ - lib/seccomp-tools/templates/asm.c
158
+ - lib/seccomp-tools/templates/asm.i386.asm
155
159
  - lib/seccomp-tools/util.rb
156
160
  - lib/seccomp-tools/version.rb
157
- homepage: https://github.com/david942j/seccomp-tools
161
+ homepage:
158
162
  licenses:
159
163
  - MIT
160
- metadata: {}
164
+ metadata:
165
+ bug_tracker_uri: https://github.com/david942j/seccomp-tools/issues
166
+ documentation_uri: https://www.rubydoc.info/github/david942j/seccomp-tools/master
167
+ homepage_uri: https://github.com/david942j/seccomp-tools
168
+ source_code_uri: https://github.com/david942j/seccomp-tools
161
169
  post_install_message:
162
170
  rdoc_options: []
163
171
  require_paths:
@@ -166,15 +174,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
166
174
  requirements:
167
175
  - - ">="
168
176
  - !ruby/object:Gem::Version
169
- version: 2.1.0
177
+ version: '2.3'
170
178
  required_rubygems_version: !ruby/object:Gem::Requirement
171
179
  requirements:
172
180
  - - ">="
173
181
  - !ruby/object:Gem::Version
174
182
  version: '0'
175
183
  requirements: []
176
- rubyforge_project:
177
- rubygems_version: 2.6.14
184
+ rubygems_version: 3.0.2
178
185
  signing_key:
179
186
  specification_version: 4
180
187
  summary: seccomp-tools