seccomp-tools 1.1.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +112 -30
  3. data/bin/seccomp-tools +1 -0
  4. data/ext/ptrace/extconf.rb +2 -0
  5. data/ext/ptrace/ptrace.c +107 -5
  6. data/lib/seccomp-tools.rb +5 -0
  7. data/lib/seccomp-tools/asm/asm.rb +5 -2
  8. data/lib/seccomp-tools/asm/compiler.rb +96 -18
  9. data/lib/seccomp-tools/asm/tokenizer.rb +25 -8
  10. data/lib/seccomp-tools/bpf.rb +7 -4
  11. data/lib/seccomp-tools/cli/asm.rb +16 -6
  12. data/lib/seccomp-tools/cli/base.rb +10 -4
  13. data/lib/seccomp-tools/cli/cli.rb +9 -6
  14. data/lib/seccomp-tools/cli/disasm.rb +6 -2
  15. data/lib/seccomp-tools/cli/dump.rb +37 -6
  16. data/lib/seccomp-tools/cli/emu.rb +41 -22
  17. data/lib/seccomp-tools/const.rb +47 -16
  18. data/lib/seccomp-tools/consts/sys_arg.rb +432 -0
  19. data/lib/seccomp-tools/consts/sys_nr/aarch64.rb +284 -0
  20. data/lib/seccomp-tools/consts/{amd64.rb → sys_nr/amd64.rb} +6 -1
  21. data/lib/seccomp-tools/consts/{i386.rb → sys_nr/i386.rb} +18 -15
  22. data/lib/seccomp-tools/disasm/context.rb +125 -34
  23. data/lib/seccomp-tools/disasm/disasm.rb +5 -2
  24. data/lib/seccomp-tools/dumper.rb +75 -8
  25. data/lib/seccomp-tools/emulator.rb +19 -8
  26. data/lib/seccomp-tools/instruction/alu.rb +7 -2
  27. data/lib/seccomp-tools/instruction/base.rb +5 -3
  28. data/lib/seccomp-tools/instruction/instruction.rb +2 -0
  29. data/lib/seccomp-tools/instruction/jmp.rb +28 -14
  30. data/lib/seccomp-tools/instruction/ld.rb +28 -12
  31. data/lib/seccomp-tools/instruction/ldx.rb +2 -0
  32. data/lib/seccomp-tools/instruction/misc.rb +2 -0
  33. data/lib/seccomp-tools/instruction/ret.rb +14 -2
  34. data/lib/seccomp-tools/instruction/st.rb +4 -2
  35. data/lib/seccomp-tools/instruction/stx.rb +2 -0
  36. data/lib/seccomp-tools/logger.rb +40 -0
  37. data/lib/seccomp-tools/syscall.rb +24 -13
  38. data/lib/seccomp-tools/templates/asm.amd64.asm +26 -0
  39. data/lib/seccomp-tools/templates/asm.c +17 -0
  40. data/lib/seccomp-tools/templates/asm.i386.asm +33 -0
  41. data/lib/seccomp-tools/util.rb +24 -3
  42. data/lib/seccomp-tools/version.rb +3 -1
  43. metadata +51 -44
@@ -0,0 +1,284 @@
1
+ # frozen_string_literal: true
2
+
3
+ {
4
+ io_setup: 0,
5
+ io_destroy: 1,
6
+ io_submit: 2,
7
+ io_cancel: 3,
8
+ io_getevents: 4,
9
+ setxattr: 5,
10
+ lsetxattr: 6,
11
+ fsetxattr: 7,
12
+ getxattr: 8,
13
+ lgetxattr: 9,
14
+ fgetxattr: 10,
15
+ listxattr: 11,
16
+ llistxattr: 12,
17
+ flistxattr: 13,
18
+ removexattr: 14,
19
+ lremovexattr: 15,
20
+ fremovexattr: 16,
21
+ getcwd: 17,
22
+ lookup_dcookie: 18,
23
+ eventfd2: 19,
24
+ epoll_create1: 20,
25
+ epoll_ctl: 21,
26
+ epoll_pwait: 22,
27
+ dup: 23,
28
+ dup3: 24,
29
+ fcntl: 25,
30
+ inotify_init1: 26,
31
+ inotify_add_watch: 27,
32
+ inotify_rm_watch: 28,
33
+ ioctl: 29,
34
+ ioprio_set: 30,
35
+ ioprio_get: 31,
36
+ flock: 32,
37
+ mknodat: 33,
38
+ mkdirat: 34,
39
+ unlinkat: 35,
40
+ symlinkat: 36,
41
+ linkat: 37,
42
+ renameat: 38,
43
+ umount2: 39,
44
+ mount: 40,
45
+ pivot_root: 41,
46
+ nfsservctl: 42,
47
+ statfs: 43,
48
+ fstatfs: 44,
49
+ truncate: 45,
50
+ ftruncate: 46,
51
+ fallocate: 47,
52
+ faccessat: 48,
53
+ chdir: 49,
54
+ fchdir: 50,
55
+ chroot: 51,
56
+ fchmod: 52,
57
+ fchmodat: 53,
58
+ fchownat: 54,
59
+ fchown: 55,
60
+ openat: 56,
61
+ close: 57,
62
+ vhangup: 58,
63
+ pipe2: 59,
64
+ quotactl: 60,
65
+ getdents: 61,
66
+ getdents64: 61,
67
+ lseek: 62,
68
+ read: 63,
69
+ write: 64,
70
+ readv: 65,
71
+ writev: 66,
72
+ pread: 67,
73
+ pread64: 67,
74
+ pwrite: 68,
75
+ pwrite64: 68,
76
+ preadv: 69,
77
+ pwritev: 70,
78
+ sendfile: 71,
79
+ pselect6: 72,
80
+ ppoll: 73,
81
+ signalfd4: 74,
82
+ vmsplice: 75,
83
+ splice: 76,
84
+ tee: 77,
85
+ readlinkat: 78,
86
+ newfstatat: 79,
87
+ fstat: 80,
88
+ newfstat: 80,
89
+ sync: 81,
90
+ fsync: 82,
91
+ fdatasync: 83,
92
+ sync_file_range: 84,
93
+ timerfd_create: 85,
94
+ timerfd_settime: 86,
95
+ timerfd_gettime: 87,
96
+ utimensat: 88,
97
+ acct: 89,
98
+ capget: 90,
99
+ capset: 91,
100
+ personality: 92,
101
+ exit: 93,
102
+ exit_group: 94,
103
+ waitid: 95,
104
+ set_tid_address: 96,
105
+ unshare: 97,
106
+ futex: 98,
107
+ set_robust_list: 99,
108
+ get_robust_list: 100,
109
+ nanosleep: 101,
110
+ getitimer: 102,
111
+ setitimer: 103,
112
+ kexec_load: 104,
113
+ init_module: 105,
114
+ delete_module: 106,
115
+ timer_create: 107,
116
+ timer_gettime: 108,
117
+ timer_getoverrun: 109,
118
+ timer_settime: 110,
119
+ timer_delete: 111,
120
+ clock_settime: 112,
121
+ clock_gettime: 113,
122
+ clock_getres: 114,
123
+ clock_nanosleep: 115,
124
+ syslog: 116,
125
+ ptrace: 117,
126
+ sched_setparam: 118,
127
+ sched_setscheduler: 119,
128
+ sched_getscheduler: 120,
129
+ sched_getparam: 121,
130
+ sched_setaffinity: 122,
131
+ sched_getaffinity: 123,
132
+ sched_yield: 124,
133
+ sched_get_priority_max: 125,
134
+ sched_get_priority_min: 126,
135
+ sched_rr_get_interval: 127,
136
+ restart_syscall: 128,
137
+ kill: 129,
138
+ tkill: 130,
139
+ tgkill: 131,
140
+ sigaltstack: 132,
141
+ rt_sigsuspend: 133,
142
+ rt_sigaction: 134,
143
+ rt_sigprocmask: 135,
144
+ rt_sigpending: 136,
145
+ rt_sigtimedwait: 137,
146
+ rt_sigqueueinfo: 138,
147
+ rt_sigreturn: 139,
148
+ setpriority: 140,
149
+ getpriority: 141,
150
+ reboot: 142,
151
+ setregid: 143,
152
+ setgid: 144,
153
+ setreuid: 145,
154
+ setuid: 146,
155
+ setresuid: 147,
156
+ getresuid: 148,
157
+ setresgid: 149,
158
+ getresgid: 150,
159
+ setfsuid: 151,
160
+ setfsgid: 152,
161
+ times: 153,
162
+ setpgid: 154,
163
+ getpgid: 155,
164
+ getsid: 156,
165
+ setsid: 157,
166
+ getgroups: 158,
167
+ setgroups: 159,
168
+ uname: 160,
169
+ sethostname: 161,
170
+ setdomainname: 162,
171
+ getrlimit: 163,
172
+ setrlimit: 164,
173
+ getrusage: 165,
174
+ umask: 166,
175
+ prctl: 167,
176
+ getcpu: 168,
177
+ gettimeofday: 169,
178
+ settimeofday: 170,
179
+ adjtimex: 171,
180
+ getpid: 172,
181
+ getppid: 173,
182
+ getuid: 174,
183
+ geteuid: 175,
184
+ getgid: 176,
185
+ getegid: 177,
186
+ gettid: 178,
187
+ sysinfo: 179,
188
+ mq_open: 180,
189
+ mq_unlink: 181,
190
+ mq_timedsend: 182,
191
+ mq_timedreceive: 183,
192
+ mq_notify: 184,
193
+ mq_getsetattr: 185,
194
+ msgget: 186,
195
+ msgctl: 187,
196
+ msgrcv: 188,
197
+ msgsnd: 189,
198
+ semget: 190,
199
+ semctl: 191,
200
+ semtimedop: 192,
201
+ semop: 193,
202
+ shmget: 194,
203
+ shmctl: 195,
204
+ shmat: 196,
205
+ shmdt: 197,
206
+ socket: 198,
207
+ socketpair: 199,
208
+ bind: 200,
209
+ listen: 201,
210
+ accept: 202,
211
+ connect: 203,
212
+ getsockname: 204,
213
+ getpeername: 205,
214
+ sendto: 206,
215
+ recvfrom: 207,
216
+ setsockopt: 208,
217
+ getsockopt: 209,
218
+ shutdown: 210,
219
+ sendmsg: 211,
220
+ recvmsg: 212,
221
+ readahead: 213,
222
+ brk: 214,
223
+ munmap: 215,
224
+ mremap: 216,
225
+ add_key: 217,
226
+ request_key: 218,
227
+ keyctl: 219,
228
+ clone: 220,
229
+ execve: 221,
230
+ mmap: 222,
231
+ fadvise64: 223,
232
+ swapon: 224,
233
+ swapoff: 225,
234
+ mprotect: 226,
235
+ msync: 227,
236
+ mlock: 228,
237
+ munlock: 229,
238
+ mlockall: 230,
239
+ munlockall: 231,
240
+ mincore: 232,
241
+ madvise: 233,
242
+ remap_file_pages: 234,
243
+ mbind: 235,
244
+ get_mempolicy: 236,
245
+ set_mempolicy: 237,
246
+ migrate_pages: 238,
247
+ move_pages: 239,
248
+ rt_tgsigqueueinfo: 240,
249
+ perf_event_open: 241,
250
+ accept4: 242,
251
+ recvmmsg: 243,
252
+ wait4: 260,
253
+ prlimit64: 261,
254
+ fanotify_init: 262,
255
+ fanotify_mark: 263,
256
+ name_to_handle_at: 264,
257
+ open_by_handle_at: 265,
258
+ clock_adjtime: 266,
259
+ syncfs: 267,
260
+ setns: 268,
261
+ sendmmsg: 269,
262
+ process_vm_readv: 270,
263
+ process_vm_writev: 271,
264
+ kcmp: 272,
265
+ finit_module: 273,
266
+ sched_setattr: 274,
267
+ sched_getattr: 275,
268
+ renameat2: 276,
269
+ seccomp: 277,
270
+ getrandom: 278,
271
+ memfd_create: 279,
272
+ bpf: 280,
273
+ execveat: 281,
274
+ userfaultfd: 282,
275
+ membarrier: 283,
276
+ mlock2: 284,
277
+ copy_file_range: 285,
278
+ preadv2: 286,
279
+ pwritev2: 287,
280
+ pkey_mprotect: 288,
281
+ pkey_alloc: 289,
282
+ pkey_free: 290,
283
+ statx: 291
284
+ }
@@ -1,3 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ X32_MODE_BIT = 0x40000000
1
4
  {
2
5
  read: 0,
3
6
  write: 1,
@@ -17,7 +20,9 @@
17
20
  rt_sigreturn: 15,
18
21
  ioctl: 16,
19
22
  pread: 17,
23
+ pread64: 17,
20
24
  pwrite: 18,
25
+ pwrite64: 18,
21
26
  readv: 19,
22
27
  writev: 20,
23
28
  access: 21,
@@ -332,4 +337,4 @@
332
337
  pkey_alloc: 330,
333
338
  pkey_free: 331,
334
339
  statx: 332
335
- }
340
+ }.tap { |h| h.keys.each { |k| h["x32_#{k}".to_sym] = h[k] | X32_MODE_BIT } } # rubocop:disable Style/HashEachMethods
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  {
4
+ restart_syscall: 0,
2
5
  exit: 1,
3
6
  fork: 2,
4
7
  read: 3,
@@ -178,8 +181,8 @@
178
181
  rt_sigtimedwait: 177,
179
182
  rt_sigqueueinfo: 178,
180
183
  rt_sigsuspend: 179,
181
- pread: 180,
182
- pwrite: 181,
184
+ pread64: 180,
185
+ pwrite64: 181,
183
186
  chown: 182,
184
187
  getcwd: 183,
185
188
  capget: 184,
@@ -256,14 +259,14 @@
256
259
  remap_file_pages: 257,
257
260
  set_tid_address: 258,
258
261
  timer_create: 259,
259
- timer_settime: (259 + 1),
260
- timer_gettime: (259 + 2),
261
- timer_getoverrun: (259 + 3),
262
- timer_delete: (259 + 4),
263
- clock_settime: (259 + 5),
264
- clock_gettime: (259 + 6),
265
- clock_getres: (259 + 7),
266
- clock_nanosleep: (259 + 8),
262
+ timer_settime: 260,
263
+ timer_gettime: 261,
264
+ timer_getoverrun: 262,
265
+ timer_delete: 263,
266
+ clock_settime: 264,
267
+ clock_gettime: 265,
268
+ clock_getres: 266,
269
+ clock_nanosleep: 267,
267
270
  statfs64: 268,
268
271
  fstatfs64: 269,
269
272
  tgkill: 270,
@@ -274,11 +277,11 @@
274
277
  get_mempolicy: 275,
275
278
  set_mempolicy: 276,
276
279
  mq_open: 277,
277
- mq_unlink: (277 + 1),
278
- mq_timedsend: (277 + 2),
279
- mq_timedreceive: (277 + 3),
280
- mq_notify: (277 + 4),
281
- mq_getsetattr: (277 + 5),
280
+ mq_unlink: 278,
281
+ mq_timedsend: 279,
282
+ mq_timedreceive: 280,
283
+ mq_notify: 281,
284
+ mq_getsetattr: 282,
282
285
  sys_kexec_load: 283,
283
286
  waitid: 284,
284
287
  add_key: 286,
@@ -1,79 +1,170 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SeccompTools
2
4
  module Disasm
5
+ # @private
6
+ #
3
7
  # Context for disassembler to analyze.
4
8
  #
5
- # This context only care if +reg/mem+ can be one of +data[*]+.
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
6
12
  class Context
7
- # @return [Hash{Integer, Symbol => Integer?}] Records reg and mem values.
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.
8
52
  attr_reader :values
53
+ # @return [Array<Integer?>] Records the known value of data.
54
+ attr_reader :known_data
9
55
 
10
56
  # Instantiate a {Context} object.
11
- # @param [Integer?] a
12
- # Value to be set to +A+ register.
13
- # @param [Integer?] x
14
- # Value to be set to +X+ register.
15
- # @param [Hash{Integer => Integer?}] mem
16
- # Value to be set to +mem+.
17
- def initialize(a: nil, x: nil, mem: {})
18
- @values = mem
19
- 16.times { |i| @values[i] ||= nil } # make @values always has all keys
20
- @values[:a] = a
21
- @values[:x] = x
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 if 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
22
69
  end
23
70
 
24
- # Implement a deep dup.
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 if 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.
25
121
  # @return [Context]
26
122
  def dup
27
- Context.new(a: a, x: x, mem: values.dup)
123
+ Context.new(values: values.dup, known_data: known_data.dup)
28
124
  end
29
125
 
30
126
  # Register A.
31
- # @return [Integer?]
127
+ # @return [Context::Value]
32
128
  def a
33
129
  values[:a]
34
130
  end
35
131
 
36
132
  # Register X.
37
- # @return [Integer?]
133
+ # @return [Context::Value]
38
134
  def x
39
135
  values[:x]
40
136
  end
41
137
 
42
138
  # For conveniently get instance variable.
43
139
  # @param [String, Symbol, Integer] key
44
- # @return [Integer?]
140
+ # @return [Context::Value]
45
141
  def [](key)
46
142
  return values[key] if key.is_a?(Integer) # mem
143
+
47
144
  values[key.downcase.to_sym]
48
145
  end
49
146
 
50
- # For conveniently set instance variable.
51
- # @param [#downcase, Integer] key
52
- # Can be +'A', 'a', :a, 'X', 'x', :x+ or an integer.
53
- # @param [Integer?] val
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
54
151
  # Value to set.
55
152
  # @return [void]
56
- def []=(key, val)
57
- if key.is_a?(Integer)
58
- raise RangeError, "Expect 0 <= key < 16, got #{key}." unless key.between?(0, 15)
59
- raise RangeError, "Expect 0 <= val < 64, got #{val}." unless val.nil? || val.between?(0, 63)
60
- values[key] = val
61
- else
62
- values[key.downcase.to_sym] = val
63
- end
153
+ def []=(reg, val)
154
+ values[reg.downcase.to_sym] = val
64
155
  end
65
156
 
66
- # For +Set+ to compare two {Context} object.
157
+ # For +Set+ to compare two {Context} objects.
67
158
  # @param [Context] other
68
159
  # @return [Boolean]
69
160
  def eql?(other)
70
- values.eql?(other.values)
161
+ values.eql?(other.values) && known_data.eql?(other.known_data)
71
162
  end
72
163
 
73
- # For +Set+ to get hash key.
164
+ # For +Set+ to get the hash value.
74
165
  # @return [Integer]
75
166
  def hash
76
- values.hash
167
+ values.hash ^ known_data.hash
77
168
  end
78
169
  end
79
170
  end