1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
|
# Copyright 2018 syzkaller project authors. All rights reserved.
# Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
include <uapi/linux/a.out.h>
include <uapi/linux/elf.h>
include <linux/fcntl.h>
resource fd_binfmt[fd]
resource fd_binfmt_register[fd]
resource fd_binfmt_format[fd]
resource ptr_binfmt_file[intptr]
syz_create_resource$binfmt(file ptr[in, filename]) ptr_binfmt_file
execve(file ptr[in, filename], argv ptr[in, argv_array], envp ptr[in, argv_array])
execveat(dirfd fd_dir, file ptr[in, filename], argv ptr[in, argv_array], envp ptr[in, argv_array], flags flags[at_flags])
execveat$binfmt(dirfd fd_dir, file ptr_binfmt_file, argv ptr[in, argv_array], envp ptr[in, argv_array], flags flags[at_flags])
openat$binfmt(fd const[AT_FDCWD], file ptr_binfmt_file, flags const[BINFMT_OPEN_FLAGS], mode const[0x1ff]) fd_binfmt
write$binfmt_script(fd fd_binfmt, data ptr[in, binfmt_script], len bytesize[data])
write$binfmt_misc(fd fd_binfmt, data ptr[in, array[int8]], len bytesize[data])
write$binfmt_aout(fd fd_binfmt, data ptr[in, binfmt_aout], len bytesize[data])
write$binfmt_elf32(fd fd_binfmt, data ptr[in, binfmt_elf32], len bytesize[data])
write$binfmt_elf64(fd fd_binfmt, data ptr[in, binfmt_elf64], len bytesize[data])
close$binfmt(fd fd_binfmt)
openat$binfmt_register(fd const[AT_FDCWD], file ptr[in, string["/proc/sys/fs/binfmt_misc/register"]], flags const[O_WRONLY], mode const[0]) fd_binfmt_register
write$binfmt_register(fd fd_binfmt_register, data ptr[in, binfmt_register], len bytesize[data])
openat$binfmt_format(fd const[AT_FDCWD], file ptr[in, string[binfmt_format_files]], flags const[O_RDWR], mode const[0]) fd_binfmt_format
write$binfmt_format(fd fd_binfmt_format, data ptr[in, string[binfmt_format_cmd]], len bytesize[data])
define BINFMT_OPEN_FLAGS O_WRONLY | O_CREAT
argv_array {
args array[ptr[in, string]]
z const[0, intptr]
} [packed]
# For details of the format see:
# Documentation/admin-guide/binfmt-misc.rst
binfmt_register {
colon0 const[':', int8]
name stringnoz[binfmt_names]
colon1 const[':', int8]
type stringnoz[binfmt_types]
colon2 const[':', int8]
offset fmt[dec, int64]
colon3 const[':', int8]
magic stringnoz
colon4 const[':', int8]
mask stringnoz
colon5 const[':', int8]
interpreter stringnoz[filename]
colon6 const[':', int8]
flags array[flags[binfmt_flags, int8]]
} [packed]
# syz0/1 are pre-registered by executor, but we can delete them and them re-create.
binfmt_names = "syz0", "syz1", "syz2", "syz3"
binfmt_types = "M", "E"
binfmt_flags = 'P', 'O', 'C', 'F'
binfmt_format_cmd = "0", "1", "-1"
binfmt_format_files = "/proc/sys/fs/binfmt_misc/syz0", "/proc/sys/fs/binfmt_misc/syz1", "/proc/sys/fs/binfmt_misc/syz2", "/proc/sys/fs/binfmt_misc/syz3"
binfmt_script {
hdr stringnoz["#! "]
bin stringnoz[filename]
args array[binfmt_script_arg]
nl const[0xa, int8]
data array[int8]
} [packed]
binfmt_script_arg {
sp const[0x20, int8]
arg stringnoz
}
binfmt_aout {
exec exec
data array[int8]
# Just to make the file of a non-trivial size.
pad array[array[const[0, int64], 32], 0:10]
} [packed]
exec {
magic flags[aouthdr_magics, int16]
machtype int8
flags int8
a_text int32[0:1000]
a_data int32[0:1000]
a_bss int32
a_syms int32[0:1000]
a_entry int32
a_trsize const[0, int32]
a_drsize const[0, int32]
}
aouthdr_magics = OMAGIC, NMAGIC, ZMAGIC, QMAGIC
type binfmt_elf32 binfmt_elf[int32, elf32_phdr, ELF32_PHDR_SIZE]
type binfmt_elf64 binfmt_elf[int64, elf64_phdr, ELF64_PHDR_SIZE]
type binfmt_elf[ADDR, PHDR, PHENTSIZE] {
hdr elf_hdr[ADDR, PHENTSIZE]
phdr array[PHDR, 1:4]
data array[int8]
# Just to make the file of a non-trivial size.
pad array[array[const[0, int64], 32], 0:10]
} [packed]
type elf_hdr[ADDR, PHENTSIZE] {
e_ident0 const[0x7f, int8]
e_ident1 const[0x45, int8]
e_ident2 const[0x4c, int8]
e_ident3 const[0x46, int8]
e_ident_class int8
e_ident_data int8
e_ident_ver int8
e_ident_osabi int8
e_ident_pad int64
e_type flags[elf_types, int16]
e_machine flags[elf_machines, int16]
e_version int32
e_entry ADDR[0:1000]
e_phoff bytesize[parent, ADDR]
e_shoff ADDR[0:1000]
e_flags int32
e_ehsize int16
e_phentsize const[PHENTSIZE, int16]
e_phnum len[binfmt_elf:phdr, int16]
e_shentsize int16
e_shnum int16
e_shstrndx int16
}
elf32_phdr {
p_type flags[elf_ptypes, int32]
p_offset int32
p_vaddr int32
p_paddr int32
p_filesz int32
p_memsz int32
p_flags int32
p_align int32
} [size[ELF32_PHDR_SIZE]]
elf64_phdr {
p_type flags[elf_ptypes, int32]
p_flags int32
p_offset int64
p_vaddr int64
p_paddr int64
p_filesz int64
p_memsz int64
p_align int64
} [size[ELF64_PHDR_SIZE]]
elf_types = ET_EXEC, ET_DYN
elf_machines = EM_386, EM_486, EM_X86_64
elf_ptypes = PT_LOAD, PT_DYNAMIC, PT_INTERP, PT_NOTE, PT_SHLIB, PT_PHDR, PT_TLS, PT_LOOS, PT_LOPROC, PT_GNU_STACK
define ELF32_PHDR_SIZE sizeof(struct elf32_phdr)
define ELF64_PHDR_SIZE sizeof(struct elf64_phdr)
|