# 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 include include 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)