seccomp-tools 1.5.0 → 1.6.1
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 +98 -18
- data/lib/seccomp-tools/asm/asm.rb +8 -6
- data/lib/seccomp-tools/asm/compiler.rb +136 -226
- 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 +1 -1
- data/lib/seccomp-tools/cli/base.rb +4 -4
- data/lib/seccomp-tools/cli/disasm.rb +26 -2
- data/lib/seccomp-tools/const.rb +25 -4
- data/lib/seccomp-tools/consts/sys_nr/amd64.rb +1 -0
- 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 +15 -9
- data/lib/seccomp-tools/dumper.rb +1 -2
- data/lib/seccomp-tools/emulator.rb +5 -10
- data/lib/seccomp-tools/error.rb +31 -0
- data/lib/seccomp-tools/instruction/base.rb +1 -1
- data/lib/seccomp-tools/instruction/jmp.rb +14 -1
- data/lib/seccomp-tools/instruction/ld.rb +3 -1
- data/lib/seccomp-tools/syscall.rb +13 -8
- data/lib/seccomp-tools/templates/asm.s390x.asm +26 -0
- data/lib/seccomp-tools/util.rb +2 -1
- data/lib/seccomp-tools/version.rb +1 -1
- metadata +17 -15
- data/lib/seccomp-tools/asm/tokenizer.rb +0 -169
data/lib/seccomp-tools/const.rb
CHANGED
@@ -120,14 +120,15 @@ module SeccompTools
|
|
120
120
|
filename = File.join(__dir__, 'consts', 'sys_nr', "#{arch}.rb")
|
121
121
|
return unless File.exist?(filename)
|
122
122
|
|
123
|
-
const_set(cons, instance_eval(
|
123
|
+
const_set(cons, instance_eval(File.read(filename)))
|
124
124
|
end
|
125
125
|
|
126
|
+
# Helper for loading syscall prototypes from generated sys_arg.rb.
|
126
127
|
def load_args
|
127
|
-
hash = instance_eval(
|
128
|
+
hash = instance_eval(File.read(File.join(__dir__, 'consts', 'sys_arg.rb')))
|
128
129
|
Hash.new do |_h, k|
|
129
130
|
next hash[k] if hash[k]
|
130
|
-
next hash[k.to_s[4
|
131
|
+
next hash[k.to_s[4..].to_sym] if k.to_s.start_with?('x32_')
|
131
132
|
|
132
133
|
nil
|
133
134
|
end
|
@@ -139,11 +140,31 @@ module SeccompTools
|
|
139
140
|
|
140
141
|
# Constants from https://github.com/torvalds/linux/blob/master/include/uapi/linux/audit.h.
|
141
142
|
module Audit
|
143
|
+
# Maps arch name to {ARCH}'s key.
|
144
|
+
ARCH_NAME = {
|
145
|
+
amd64: 'ARCH_X86_64',
|
146
|
+
i386: 'ARCH_I386',
|
147
|
+
aarch64: 'ARCH_AARCH64',
|
148
|
+
s390x: 'ARCH_S390X'
|
149
|
+
}.freeze
|
150
|
+
|
142
151
|
# AUDIT_ARCH_*
|
143
152
|
ARCH = {
|
144
153
|
'ARCH_X86_64' => 0xc000003e,
|
145
154
|
'ARCH_I386' => 0x40000003,
|
146
|
-
'ARCH_AARCH64' => 0xc00000b7
|
155
|
+
'ARCH_AARCH64' => 0xc00000b7,
|
156
|
+
'ARCH_S390X' => 0x80000016
|
157
|
+
}.freeze
|
158
|
+
end
|
159
|
+
|
160
|
+
# Endianess constants.
|
161
|
+
module Endian
|
162
|
+
# Defining default endianess of architectures.
|
163
|
+
ENDIAN = {
|
164
|
+
i386: '<',
|
165
|
+
amd64: '<',
|
166
|
+
aarch64: '<',
|
167
|
+
s390x: '>'
|
147
168
|
}.freeze
|
148
169
|
end
|
149
170
|
end
|
@@ -0,0 +1,365 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
{
|
4
|
+
exit: 1,
|
5
|
+
fork: 2,
|
6
|
+
read: 3,
|
7
|
+
write: 4,
|
8
|
+
open: 5,
|
9
|
+
close: 6,
|
10
|
+
restart_syscall: 7,
|
11
|
+
creat: 8,
|
12
|
+
link: 9,
|
13
|
+
unlink: 10,
|
14
|
+
execve: 11,
|
15
|
+
chdir: 12,
|
16
|
+
mknod: 14,
|
17
|
+
chmod: 15,
|
18
|
+
lseek: 19,
|
19
|
+
getpid: 20,
|
20
|
+
mount: 21,
|
21
|
+
umount: 22,
|
22
|
+
ptrace: 26,
|
23
|
+
alarm: 27,
|
24
|
+
pause: 29,
|
25
|
+
utime: 30,
|
26
|
+
access: 33,
|
27
|
+
nice: 34,
|
28
|
+
sync: 36,
|
29
|
+
kill: 37,
|
30
|
+
rename: 38,
|
31
|
+
mkdir: 39,
|
32
|
+
rmdir: 40,
|
33
|
+
dup: 41,
|
34
|
+
pipe: 42,
|
35
|
+
times: 43,
|
36
|
+
brk: 45,
|
37
|
+
signal: 48,
|
38
|
+
acct: 51,
|
39
|
+
umount2: 52,
|
40
|
+
ioctl: 54,
|
41
|
+
fcntl: 55,
|
42
|
+
setpgid: 57,
|
43
|
+
umask: 60,
|
44
|
+
chroot: 61,
|
45
|
+
ustat: 62,
|
46
|
+
dup2: 63,
|
47
|
+
getppid: 64,
|
48
|
+
getpgrp: 65,
|
49
|
+
setsid: 66,
|
50
|
+
sigaction: 67,
|
51
|
+
sigsuspend: 72,
|
52
|
+
sigpending: 73,
|
53
|
+
sethostname: 74,
|
54
|
+
setrlimit: 75,
|
55
|
+
getrusage: 77,
|
56
|
+
gettimeofday: 78,
|
57
|
+
settimeofday: 79,
|
58
|
+
symlink: 83,
|
59
|
+
readlink: 85,
|
60
|
+
uselib: 86,
|
61
|
+
swapon: 87,
|
62
|
+
reboot: 88,
|
63
|
+
readdir: 89,
|
64
|
+
mmap: 90,
|
65
|
+
munmap: 91,
|
66
|
+
truncate: 92,
|
67
|
+
ftruncate: 93,
|
68
|
+
fchmod: 94,
|
69
|
+
getpriority: 96,
|
70
|
+
setpriority: 97,
|
71
|
+
statfs: 99,
|
72
|
+
fstatfs: 100,
|
73
|
+
socketcall: 102,
|
74
|
+
syslog: 103,
|
75
|
+
setitimer: 104,
|
76
|
+
getitimer: 105,
|
77
|
+
stat: 106,
|
78
|
+
lstat: 107,
|
79
|
+
fstat: 108,
|
80
|
+
lookup_dcookie: 110,
|
81
|
+
vhangup: 111,
|
82
|
+
idle: 112,
|
83
|
+
wait4: 114,
|
84
|
+
swapoff: 115,
|
85
|
+
sysinfo: 116,
|
86
|
+
ipc: 117,
|
87
|
+
fsync: 118,
|
88
|
+
sigreturn: 119,
|
89
|
+
clone: 120,
|
90
|
+
setdomainname: 121,
|
91
|
+
uname: 122,
|
92
|
+
adjtimex: 124,
|
93
|
+
mprotect: 125,
|
94
|
+
sigprocmask: 126,
|
95
|
+
create_module: 127,
|
96
|
+
init_module: 128,
|
97
|
+
delete_module: 129,
|
98
|
+
get_kernel_syms: 130,
|
99
|
+
quotactl: 131,
|
100
|
+
getpgid: 132,
|
101
|
+
fchdir: 133,
|
102
|
+
bdflush: 134,
|
103
|
+
sysfs: 135,
|
104
|
+
personality: 136,
|
105
|
+
afs_syscall: 137,
|
106
|
+
getdents: 141,
|
107
|
+
select: 142,
|
108
|
+
flock: 143,
|
109
|
+
msync: 144,
|
110
|
+
readv: 145,
|
111
|
+
writev: 146,
|
112
|
+
getsid: 147,
|
113
|
+
fdatasync: 148,
|
114
|
+
_sysctl: 149,
|
115
|
+
mlock: 150,
|
116
|
+
munlock: 151,
|
117
|
+
mlockall: 152,
|
118
|
+
munlockall: 153,
|
119
|
+
sched_setparam: 154,
|
120
|
+
sched_getparam: 155,
|
121
|
+
sched_setscheduler: 156,
|
122
|
+
sched_getscheduler: 157,
|
123
|
+
sched_yield: 158,
|
124
|
+
sched_get_priority_max: 159,
|
125
|
+
sched_get_priority_min: 160,
|
126
|
+
sched_rr_get_interval: 161,
|
127
|
+
nanosleep: 162,
|
128
|
+
mremap: 163,
|
129
|
+
query_module: 167,
|
130
|
+
poll: 168,
|
131
|
+
nfsservctl: 169,
|
132
|
+
prctl: 172,
|
133
|
+
rt_sigreturn: 173,
|
134
|
+
rt_sigaction: 174,
|
135
|
+
rt_sigprocmask: 175,
|
136
|
+
rt_sigpending: 176,
|
137
|
+
rt_sigtimedwait: 177,
|
138
|
+
rt_sigqueueinfo: 178,
|
139
|
+
rt_sigsuspend: 179,
|
140
|
+
pread64: 180,
|
141
|
+
pwrite64: 181,
|
142
|
+
getcwd: 183,
|
143
|
+
capget: 184,
|
144
|
+
capset: 185,
|
145
|
+
sigaltstack: 186,
|
146
|
+
sendfile: 187,
|
147
|
+
getpmsg: 188,
|
148
|
+
putpmsg: 189,
|
149
|
+
vfork: 190,
|
150
|
+
getrlimit: 191,
|
151
|
+
lchown: 198,
|
152
|
+
getuid: 199,
|
153
|
+
getgid: 200,
|
154
|
+
geteuid: 201,
|
155
|
+
getegid: 202,
|
156
|
+
setreuid: 203,
|
157
|
+
setregid: 204,
|
158
|
+
getgroups: 205,
|
159
|
+
setgroups: 206,
|
160
|
+
fchown: 207,
|
161
|
+
setresuid: 208,
|
162
|
+
getresuid: 209,
|
163
|
+
setresgid: 210,
|
164
|
+
getresgid: 211,
|
165
|
+
chown: 212,
|
166
|
+
setuid: 213,
|
167
|
+
setgid: 214,
|
168
|
+
setfsuid: 215,
|
169
|
+
setfsgid: 216,
|
170
|
+
pivot_root: 217,
|
171
|
+
mincore: 218,
|
172
|
+
madvise: 219,
|
173
|
+
getdents64: 220,
|
174
|
+
readahead: 222,
|
175
|
+
setxattr: 224,
|
176
|
+
lsetxattr: 225,
|
177
|
+
fsetxattr: 226,
|
178
|
+
getxattr: 227,
|
179
|
+
lgetxattr: 228,
|
180
|
+
fgetxattr: 229,
|
181
|
+
listxattr: 230,
|
182
|
+
llistxattr: 231,
|
183
|
+
flistxattr: 232,
|
184
|
+
removexattr: 233,
|
185
|
+
lremovexattr: 234,
|
186
|
+
fremovexattr: 235,
|
187
|
+
gettid: 236,
|
188
|
+
tkill: 237,
|
189
|
+
futex: 238,
|
190
|
+
sched_setaffinity: 239,
|
191
|
+
sched_getaffinity: 240,
|
192
|
+
tgkill: 241,
|
193
|
+
io_setup: 243,
|
194
|
+
io_destroy: 244,
|
195
|
+
io_getevents: 245,
|
196
|
+
io_submit: 246,
|
197
|
+
io_cancel: 247,
|
198
|
+
exit_group: 248,
|
199
|
+
epoll_create: 249,
|
200
|
+
epoll_ctl: 250,
|
201
|
+
epoll_wait: 251,
|
202
|
+
set_tid_address: 252,
|
203
|
+
fadvise64: 253,
|
204
|
+
timer_create: 254,
|
205
|
+
timer_settime: 255,
|
206
|
+
timer_gettime: 256,
|
207
|
+
timer_getoverrun: 257,
|
208
|
+
timer_delete: 258,
|
209
|
+
clock_settime: 259,
|
210
|
+
clock_gettime: 260,
|
211
|
+
clock_getres: 261,
|
212
|
+
clock_nanosleep: 262,
|
213
|
+
statfs64: 265,
|
214
|
+
fstatfs64: 266,
|
215
|
+
remap_file_pages: 267,
|
216
|
+
mbind: 268,
|
217
|
+
get_mempolicy: 269,
|
218
|
+
set_mempolicy: 270,
|
219
|
+
mq_open: 271,
|
220
|
+
mq_unlink: 272,
|
221
|
+
mq_timedsend: 273,
|
222
|
+
mq_timedreceive: 274,
|
223
|
+
mq_notify: 275,
|
224
|
+
mq_getsetattr: 276,
|
225
|
+
kexec_load: 277,
|
226
|
+
add_key: 278,
|
227
|
+
request_key: 279,
|
228
|
+
keyctl: 280,
|
229
|
+
waitid: 281,
|
230
|
+
ioprio_set: 282,
|
231
|
+
ioprio_get: 283,
|
232
|
+
inotify_init: 284,
|
233
|
+
inotify_add_watch: 285,
|
234
|
+
inotify_rm_watch: 286,
|
235
|
+
migrate_pages: 287,
|
236
|
+
openat: 288,
|
237
|
+
mkdirat: 289,
|
238
|
+
mknodat: 290,
|
239
|
+
fchownat: 291,
|
240
|
+
futimesat: 292,
|
241
|
+
newfstatat: 293,
|
242
|
+
unlinkat: 294,
|
243
|
+
renameat: 295,
|
244
|
+
linkat: 296,
|
245
|
+
symlinkat: 297,
|
246
|
+
readlinkat: 298,
|
247
|
+
fchmodat: 299,
|
248
|
+
faccessat: 300,
|
249
|
+
pselect6: 301,
|
250
|
+
ppoll: 302,
|
251
|
+
unshare: 303,
|
252
|
+
set_robust_list: 304,
|
253
|
+
get_robust_list: 305,
|
254
|
+
splice: 306,
|
255
|
+
sync_file_range: 307,
|
256
|
+
tee: 308,
|
257
|
+
vmsplice: 309,
|
258
|
+
move_pages: 310,
|
259
|
+
getcpu: 311,
|
260
|
+
epoll_pwait: 312,
|
261
|
+
utimes: 313,
|
262
|
+
fallocate: 314,
|
263
|
+
utimensat: 315,
|
264
|
+
signalfd: 316,
|
265
|
+
timerfd: 317,
|
266
|
+
eventfd: 318,
|
267
|
+
timerfd_create: 319,
|
268
|
+
timerfd_settime: 320,
|
269
|
+
timerfd_gettime: 321,
|
270
|
+
signalfd4: 322,
|
271
|
+
eventfd2: 323,
|
272
|
+
inotify_init1: 324,
|
273
|
+
pipe2: 325,
|
274
|
+
dup3: 326,
|
275
|
+
epoll_create1: 327,
|
276
|
+
preadv: 328,
|
277
|
+
pwritev: 329,
|
278
|
+
rt_tgsigqueueinfo: 330,
|
279
|
+
perf_event_open: 331,
|
280
|
+
fanotify_init: 332,
|
281
|
+
fanotify_mark: 333,
|
282
|
+
prlimit64: 334,
|
283
|
+
name_to_handle_at: 335,
|
284
|
+
open_by_handle_at: 336,
|
285
|
+
clock_adjtime: 337,
|
286
|
+
syncfs: 338,
|
287
|
+
setns: 339,
|
288
|
+
process_vm_readv: 340,
|
289
|
+
process_vm_writev: 341,
|
290
|
+
s390_runtime_instr: 342,
|
291
|
+
kcmp: 343,
|
292
|
+
finit_module: 344,
|
293
|
+
sched_setattr: 345,
|
294
|
+
sched_getattr: 346,
|
295
|
+
renameat2: 347,
|
296
|
+
seccomp: 348,
|
297
|
+
getrandom: 349,
|
298
|
+
memfd_create: 350,
|
299
|
+
bpf: 351,
|
300
|
+
s390_pci_mmio_write: 352,
|
301
|
+
s390_pci_mmio_read: 353,
|
302
|
+
execveat: 354,
|
303
|
+
userfaultfd: 355,
|
304
|
+
membarrier: 356,
|
305
|
+
recvmmsg: 357,
|
306
|
+
sendmmsg: 358,
|
307
|
+
socket: 359,
|
308
|
+
socketpair: 360,
|
309
|
+
bind: 361,
|
310
|
+
connect: 362,
|
311
|
+
listen: 363,
|
312
|
+
accept4: 364,
|
313
|
+
getsockopt: 365,
|
314
|
+
setsockopt: 366,
|
315
|
+
getsockname: 367,
|
316
|
+
getpeername: 368,
|
317
|
+
sendto: 369,
|
318
|
+
sendmsg: 370,
|
319
|
+
recvfrom: 371,
|
320
|
+
recvmsg: 372,
|
321
|
+
shutdown: 373,
|
322
|
+
mlock2: 374,
|
323
|
+
copy_file_range: 375,
|
324
|
+
preadv2: 376,
|
325
|
+
pwritev2: 377,
|
326
|
+
s390_guarded_storage: 378,
|
327
|
+
statx: 379,
|
328
|
+
s390_sthyi: 380,
|
329
|
+
kexec_file_load: 381,
|
330
|
+
io_pgetevents: 382,
|
331
|
+
rseq: 383,
|
332
|
+
pkey_mprotect: 384,
|
333
|
+
pkey_alloc: 385,
|
334
|
+
pkey_free: 386,
|
335
|
+
semtimedop: 392,
|
336
|
+
semget: 393,
|
337
|
+
semctl: 394,
|
338
|
+
shmget: 395,
|
339
|
+
shmctl: 396,
|
340
|
+
shmat: 397,
|
341
|
+
shmdt: 398,
|
342
|
+
msgget: 399,
|
343
|
+
msgsnd: 400,
|
344
|
+
msgrcv: 401,
|
345
|
+
msgctl: 402,
|
346
|
+
pidfd_send_signal: 424,
|
347
|
+
io_uring_setup: 425,
|
348
|
+
io_uring_enter: 426,
|
349
|
+
io_uring_register: 427,
|
350
|
+
open_tree: 428,
|
351
|
+
move_mount: 429,
|
352
|
+
fsopen: 430,
|
353
|
+
fsconfig: 431,
|
354
|
+
fsmount: 432,
|
355
|
+
fspick: 433,
|
356
|
+
pidfd_open: 434,
|
357
|
+
clone3: 435,
|
358
|
+
close_range: 436,
|
359
|
+
openat2: 437,
|
360
|
+
pidfd_getfd: 438,
|
361
|
+
faccessat2: 439,
|
362
|
+
process_madvise: 440,
|
363
|
+
epoll_pwait2: 441,
|
364
|
+
mount_setattr: 442
|
365
|
+
}
|
@@ -58,7 +58,7 @@ module SeccompTools
|
|
58
58
|
# Value to be set to +reg/mem+.
|
59
59
|
# @param [Array<Integer?>] known_data
|
60
60
|
# Records which index of data is known.
|
61
|
-
# It's used for tracking
|
61
|
+
# It's used for tracking when the syscall number is known, which can be used to display argument names of the
|
62
62
|
# syscall.
|
63
63
|
def initialize(values: {}, known_data: [])
|
64
64
|
@values = values
|
@@ -104,7 +104,7 @@ module SeccompTools
|
|
104
104
|
# Returns the object itself.
|
105
105
|
def eql!(val)
|
106
106
|
tap do
|
107
|
-
# only cares
|
107
|
+
# only cares when A is fetched from data
|
108
108
|
next unless a.data?
|
109
109
|
next known_data[a.val] = val if val.is_a?(Integer)
|
110
110
|
# A == X, we can handle these cases:
|
@@ -7,20 +7,22 @@ require 'seccomp-tools/disasm/context'
|
|
7
7
|
require 'seccomp-tools/util'
|
8
8
|
|
9
9
|
module SeccompTools
|
10
|
-
# Disassembler of seccomp
|
10
|
+
# Disassembler of seccomp BPF.
|
11
11
|
module Disasm
|
12
12
|
module_function
|
13
13
|
|
14
|
-
# Disassemble
|
14
|
+
# Disassemble BPF codes.
|
15
15
|
# @param [String] raw
|
16
|
-
# The raw
|
16
|
+
# The raw BPF bytes.
|
17
17
|
# @param [Symbol] arch
|
18
18
|
# Architecture.
|
19
|
-
|
19
|
+
# @param [Boolean] display_bpf
|
20
|
+
# @param [Boolean] arg_infer
|
21
|
+
def disasm(raw, arch: nil, display_bpf: true, arg_infer: true)
|
20
22
|
codes = to_bpf(raw, arch)
|
21
23
|
contexts = Array.new(codes.size) { Set.new }
|
22
24
|
contexts[0].add(Context.new)
|
23
|
-
# all we care is
|
25
|
+
# all we care is whether A is data[*]
|
24
26
|
dis = codes.zip(contexts).map do |code, ctxs|
|
25
27
|
ctxs.each do |ctx|
|
26
28
|
code.branch(ctx) do |pc, c|
|
@@ -28,16 +30,20 @@ module SeccompTools
|
|
28
30
|
end
|
29
31
|
end
|
30
32
|
code.contexts = ctxs
|
31
|
-
code.disasm
|
33
|
+
code.disasm(code: display_bpf, arg_infer: arg_infer)
|
32
34
|
end.join("\n")
|
33
|
-
|
35
|
+
if display_bpf
|
36
|
+
<<-EOS
|
34
37
|
line CODE JT JF K
|
35
38
|
=================================
|
36
39
|
#{dis}
|
37
|
-
|
40
|
+
EOS
|
41
|
+
else
|
42
|
+
"#{dis}\n"
|
43
|
+
end
|
38
44
|
end
|
39
45
|
|
40
|
-
# Convert raw
|
46
|
+
# Convert raw BPF string to array of {BPF}.
|
41
47
|
# @param [String] raw
|
42
48
|
# @param [Symbol] arch
|
43
49
|
# @return [Array<BPF>]
|
data/lib/seccomp-tools/dumper.rb
CHANGED
@@ -8,7 +8,6 @@ require 'seccomp-tools/syscall'
|
|
8
8
|
|
9
9
|
module SeccompTools
|
10
10
|
# Dump seccomp-bpf using ptrace of binary.
|
11
|
-
# Currently only support x86_64 and aarch64.
|
12
11
|
module Dumper
|
13
12
|
# Whether the dumper is supported.
|
14
13
|
# Dumper works based on ptrace, so we need the platform be Linux.
|
@@ -66,7 +65,7 @@ module SeccompTools
|
|
66
65
|
# @yieldparam [String] bpf
|
67
66
|
# Seccomp bpf in raw bytes.
|
68
67
|
# @yieldparam [Symbol] arch
|
69
|
-
# Architecture
|
68
|
+
# Architecture. See {SeccompTools::Syscall::ABI} for supported architectures.
|
70
69
|
# @return [Array<Object>, Array<String>]
|
71
70
|
# Return the block returned. If block is not given, array of raw bytes will be returned.
|
72
71
|
def handle(limit, &block)
|
@@ -7,7 +7,7 @@ module SeccompTools
|
|
7
7
|
class Emulator
|
8
8
|
# Instantiate a {Emulator} object.
|
9
9
|
#
|
10
|
-
# All parameters except +instructions+ are optional
|
10
|
+
# All parameters except +instructions+ are optional. A warning is shown when uninitialized data is accessed.
|
11
11
|
# @param [Array<Instruction::Base>] instructions
|
12
12
|
# @param [Integer] sys_nr
|
13
13
|
# Syscall number.
|
@@ -15,8 +15,8 @@ module SeccompTools
|
|
15
15
|
# Syscall arguments
|
16
16
|
# @param [Integer] instruction_pointer
|
17
17
|
# Program counter address when this syscall invoked.
|
18
|
-
# @param [Symbol] arch
|
19
|
-
#
|
18
|
+
# @param [Symbol?] arch
|
19
|
+
# System architecture is used when this parameter is not provided.
|
20
20
|
#
|
21
21
|
# See {SeccompTools::Util.supported_archs} for list of supported architectures.
|
22
22
|
def initialize(instructions, sys_nr: nil, args: [], instruction_pointer: nil, arch: nil)
|
@@ -28,7 +28,7 @@ module SeccompTools
|
|
28
28
|
end
|
29
29
|
|
30
30
|
# Run emulation!
|
31
|
-
# @return [
|
31
|
+
# @return [{Symbol, Integer => Integer}]
|
32
32
|
def run
|
33
33
|
@values = { pc: 0, a: 0, x: 0 }
|
34
34
|
loop do
|
@@ -58,12 +58,7 @@ module SeccompTools
|
|
58
58
|
end
|
59
59
|
|
60
60
|
def audit(arch)
|
61
|
-
|
62
|
-
amd64: 'ARCH_X86_64',
|
63
|
-
i386: 'ARCH_I386',
|
64
|
-
aarch64: 'ARCH_AARCH64'
|
65
|
-
}[arch]
|
66
|
-
Const::Audit::ARCH[type]
|
61
|
+
Const::Audit::ARCH[Const::Audit::ARCH_NAME[arch]]
|
67
62
|
end
|
68
63
|
|
69
64
|
def ret(num)
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SeccompTools
|
4
|
+
# Base error class.
|
5
|
+
class Error < StandardError
|
6
|
+
end
|
7
|
+
|
8
|
+
# Raised when unrecognized token(s) are found on compiling seccomp assembly.
|
9
|
+
class UnrecognizedTokenError < Error
|
10
|
+
end
|
11
|
+
|
12
|
+
# Raised when a referred label is defined no where on compiling seccomp assembly.
|
13
|
+
class UndefinedLabelError < Error
|
14
|
+
end
|
15
|
+
|
16
|
+
# Raised on RACC parsing error when compiling seccomp assembly.
|
17
|
+
class ParseError < Error
|
18
|
+
end
|
19
|
+
|
20
|
+
# Raised when a jump expression goes backward on compiling seccomp assembly.
|
21
|
+
class BackwardJumpError < Error
|
22
|
+
end
|
23
|
+
|
24
|
+
# Raised when a label is defined more than once on compiling seccomp assembly.
|
25
|
+
class DuplicateLabelError < Error
|
26
|
+
end
|
27
|
+
|
28
|
+
# Raised when a jump is longer than supported distance.
|
29
|
+
class LongJumpError < Error
|
30
|
+
end
|
31
|
+
end
|
@@ -74,7 +74,20 @@ module SeccompTools
|
|
74
74
|
end
|
75
75
|
|
76
76
|
def sysname_by_k
|
77
|
-
|
77
|
+
a = infer_arch || arch
|
78
|
+
name = Const::Syscall.const_get(a.upcase.to_sym).invert[k]
|
79
|
+
return name if name.nil?
|
80
|
+
|
81
|
+
a == arch ? name : "#{a}.#{name}"
|
82
|
+
end
|
83
|
+
|
84
|
+
# Infers the architecture from context.
|
85
|
+
# @return [Symbol?]
|
86
|
+
def infer_arch
|
87
|
+
arches = contexts.map { |ctx| ctx.known_data[4] }.uniq
|
88
|
+
return nil unless arches.size == 1 && !arches.first.nil?
|
89
|
+
|
90
|
+
Const::Audit::ARCH_NAME.invert[Const::Audit::ARCH.invert[arches.first]]
|
78
91
|
end
|
79
92
|
|
80
93
|
def src
|
@@ -78,8 +78,10 @@ module SeccompTools
|
|
78
78
|
end
|
79
79
|
|
80
80
|
def args_name(idx)
|
81
|
-
sys_nrs = contexts.map { |ctx| ctx.known_data[0] }.uniq
|
82
81
|
default = idx.even? ? "args[#{idx / 2}]" : "args[#{idx / 2}] >> 32"
|
82
|
+
return default unless show_arg_infer?
|
83
|
+
|
84
|
+
sys_nrs = contexts.map { |ctx| ctx.known_data[0] }.uniq
|
83
85
|
return default if sys_nrs.size != 1 || sys_nrs.first.nil?
|
84
86
|
|
85
87
|
sys = Const::Syscall.const_get(arch.upcase.to_sym).invert[sys_nrs.first]
|
@@ -12,12 +12,15 @@ module SeccompTools
|
|
12
12
|
ABI = {
|
13
13
|
amd64: { number: 120, args: [112, 104, 96, 56, 72, 44], ret: 80, SYS_prctl: 157, SYS_seccomp: 317 },
|
14
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 }
|
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 }
|
16
19
|
}.freeze
|
17
20
|
|
18
21
|
# @return [Integer] Process id.
|
19
22
|
attr_reader :pid
|
20
|
-
# @return [
|
23
|
+
# @return [{Symbol => Integer, Array<Integer>}] See {ABI}.
|
21
24
|
attr_reader :abi
|
22
25
|
# @return [Integer] Syscall number.
|
23
26
|
attr_reader :number
|
@@ -64,11 +67,12 @@ module SeccompTools
|
|
64
67
|
def arch
|
65
68
|
@arch ||= File.open("/proc/#{pid}/exe", 'rb') do |f|
|
66
69
|
f.pos = 18
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
70
|
+
{
|
71
|
+
"\x03\x00" => :i386,
|
72
|
+
"\x3e\x00" => :amd64,
|
73
|
+
"\xb7\x00" => :aarch64,
|
74
|
+
"\x00\x16" => :s390x
|
75
|
+
}[f.read(2)]
|
72
76
|
end
|
73
77
|
end
|
74
78
|
|
@@ -78,7 +82,8 @@ module SeccompTools
|
|
78
82
|
{
|
79
83
|
i386: 32,
|
80
84
|
amd64: 64,
|
81
|
-
aarch64: 64
|
85
|
+
aarch64: 64,
|
86
|
+
s390x: 64
|
82
87
|
}[arch]
|
83
88
|
end
|
84
89
|
|
@@ -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:
|