[Syzkaller III]syzlang

syzlang用于定义系统调用规约模板
通俗来说, 系统调用规约模板包含:
- 可以使用哪些系统调用
- 对于1中可能的每个系统调用, 他可能的参数是什么格式的
- 解决资源依赖问题, 比如文件描述符fd
include <linux/fs.h>
open$testxy(file ptr[in, string["/proc/test1"]], flags flags[proc_open_flags], mode flags[proc_open_mode]) fd
read$testxy(fd fd, buf buffer[out], count len[buf])
write$testxy(fd fd, buf buffer[in], count len[buf])
proc_open_flags = O_RDONLY, O_WRONLY, O_RDWR, O_APPEND, FASYNC, O_CLOEXEC, O_CREAT, O_DIRECT, O_DIRECTORY, O_EXCL, O_LARGEFILE, O_NOATIME, O_NOCTTY, O_NOFOLLOW, O_NONBLOCK, O_PATH, O_SYNC, O_TRUNC, __O_TMPFILE
proc_open_mode = S_IRUSR, S_IWUSR, S_IXUSR, S_IRGRP, S_IWGRP, S_IXGRP, S_IROTH, S_IWOTH, S_IXOTH
这里
open$testxy为了和其他模块的open调用规约区分开比如对于模块A可以有
open$a对于模块B可以有
open$b这样可以在syz-manager的config文件中指定启用哪个系统调用, 比如
有了这个模板后, 模糊测试器就可能指导产生如下syzlang源码:
使用syz-execprog可以生成等价的一份c源码, 里面带着syz-execprog生成的注释, 方便理解
// autogenerated by syzkaller (https://github.com/google/syzkaller)
#define _GNU_SOURCE
#include <endian.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
uint64_t r[1] = {0xffffffffffffffff};
int main(void)
{
syscall(__NR_mmap, /*addr=*/0x1ffffffff000ul, /*len=*/0x1000ul, /*prot=*/0ul,
/*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x32ul,
/*fd=*/(intptr_t)-1, /*offset=*/0ul);
syscall(__NR_mmap, /*addr=*/0x200000000000ul, /*len=*/0x1000000ul,
/*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/ 7ul,
/*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x32ul,
/*fd=*/(intptr_t)-1, /*offset=*/0ul);
syscall(__NR_mmap, /*addr=*/0x200001000000ul, /*len=*/0x1000ul, /*prot=*/0ul,
/*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x32ul,
/*fd=*/(intptr_t)-1, /*offset=*/0ul);
const char* reason;
(void)reason;
intptr_t res = 0;
if (write(1, "executing program\n", sizeof("executing program\n") - 1)) {
}
// open$testxy arguments: [
// file: ptr[in, buffer] {
// buffer: {2f 70 72 6f 63 2f 74 65 73 74 31 00} (length 0xc)
// }
// flags: proc_open_flags = 0x28441 (8 bytes)
// mode: proc_open_mode = 0x21 (8 bytes)
// ]
// returns fd
memcpy((void*)0x200000000040, "/proc/test1\000", 12);
res = syscall(
__NR_open, /*file=*/0x200000000040ul,
/*flags=O_NOFOLLOW|O_LARGEFILE|O_CREAT|O_APPEND|O_WRONLY*/ 0x28441ul,
/*mode=S_IXOTH|S_IRGRP*/ 0x21ul);
if (res != -1)
r[0] = res;
// write$testxy arguments: [
// fd: fd (resource)
// buf: nil
// count: len = 0x0 (8 bytes)
// ]
syscall(__NR_write, /*fd=*/r[0], /*buf=*/0ul, /*count=*/0ul);
return 0;
}
具体的syzlang语法见:
syzkaller/docs/syscall_descriptions.md at master · google/syzkaller · GitHub
syzkaller/docs/syscall_descriptions_syntax.md at master · google/syzkaller · GitHub