aboutsummaryrefslogtreecommitdiffstats
path: root/sys/linux/binfmt.txt
blob: 08938298cc36492f5c47e92c1d30623d9b093819 (plain)
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)