From 538a10560010f93f22b0a8912dbd221d077deaa4 Mon Sep 17 00:00:00 2001 From: Greg Steuck Date: Sat, 17 Nov 2018 15:42:37 -0800 Subject: executor: OpenBSD network package injection Squash of: * Doc typo * Ported some tun related functions. * Copy vnet.txt from linux to openbsd. * Simplified syz_emit_ethernet and stubbed out vnet.txt. * Undo clang-format header sorting: headers are order sensitive. * Uniquify tap devices by pid. * clang-format off for includes * Happier clang-format. * Partially revert "Uniquify tap devices by pid." Just rely on procid magic instead of getting it from a flag. --- docs/linux/external_fuzzing_network.md | 2 +- executor/common_bsd.h | 239 ++++++++++++++++++++++++++++++++- executor/defs.h | 2 +- executor/syscalls.h | 3 + pkg/csource/generated.go | 220 +++++++++++++++++++++++++++++- sys/openbsd/gen/amd64.go | 21 ++- sys/openbsd/vnet.txt | 20 +++ 7 files changed, 491 insertions(+), 16 deletions(-) create mode 100644 sys/openbsd/vnet.txt diff --git a/docs/linux/external_fuzzing_network.md b/docs/linux/external_fuzzing_network.md index f080692b1..03463f876 100644 --- a/docs/linux/external_fuzzing_network.md +++ b/docs/linux/external_fuzzing_network.md @@ -23,7 +23,7 @@ Since many network protocols require checksum fields to be embedded into packets There's a `csum` type, which right now supports two different kinds of checksumming: [the Internet checksum](https://tools.ietf.org/html/rfc1071): `csum[parent, inet, int16be]`, and TCP-like pseudo header checksum: `csum[tcp_packet, pseudo, IPPROTO_TCP, int16be]`. -The checksums are computed and embedded right before emitting a packet though the virtual interface. +The checksums are computed and embedded right before emitting a packet through the virtual interface. There's also a nice feature: when syzkaller generates a C reproducer, it generates code to compute checksums in runtime as well. By using `syz_emit_ethernet` and `syz_extract_tcp_res` the following syzkaller program is able to establish a TCP connection over IPv4: diff --git a/executor/common_bsd.h b/executor/common_bsd.h index 63ae6c1d1..e09437353 100644 --- a/executor/common_bsd.h +++ b/executor/common_bsd.h @@ -5,14 +5,54 @@ #include -#if SYZ_EXECUTOR || SYZ_SANDBOX_NONE -static void loop(); -static int do_sandbox_none(void) +#include +#include +#include + +static void vsnprintf_check(char* str, size_t size, const char* format, va_list args) { - loop(); - return 0; + int rv; + + rv = vsnprintf(str, size, format, args); + if (rv < 0) + fail("vsnprintf failed"); + if ((size_t)rv >= size) + fail("vsnprintf: string '%s...' doesn't fit into buffer", str); +} + +static void snprintf_check(char* str, size_t size, const char* format, ...) +{ + va_list args; + + va_start(args, format); + vsnprintf_check(str, size, format, args); + va_end(args); +} + +#define COMMAND_MAX_LEN 128 +#define PATH_PREFIX "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin " +#define PATH_PREFIX_LEN (sizeof(PATH_PREFIX) - 1) + +static void execute_command(bool panic, const char* format, ...) +{ + va_list args; + char command[PATH_PREFIX_LEN + COMMAND_MAX_LEN]; + int rv; + + va_start(args, format); + // Executor process does not have any env, including PATH. + // On some distributions, system/shell adds a minimal PATH, on some it does not. + // Set own standard PATH to make it work across distributions. + memcpy(command, PATH_PREFIX, PATH_PREFIX_LEN); + vsnprintf_check(command + PATH_PREFIX_LEN, COMMAND_MAX_LEN, format, args); + va_end(args); + rv = system(command); + if (rv) { + if (panic) + fail("command '%s' failed: %d", &command[0], rv); + debug("command '%s': %d\n", &command[0], rv); + } } -#endif #if GOOS_openbsd @@ -26,7 +66,7 @@ static int do_sandbox_none(void) #else // Needed when compiling on Linux. #include -#endif +#endif // defined(__OpenBSD__) static uintptr_t syz_open_pts(void) { @@ -41,6 +81,191 @@ static uintptr_t syz_open_pts(void) return slave; } +#endif // SYZ_EXECUTOR || __NR_syz_open_pts + +#if SYZ_EXECUTOR || SYZ_TUN_ENABLE + +#include +#include +#include + +static int tunfd = -1; + +// We just need this to be large enough to hold headers that we parse (ethernet/ip/tcp). +// Rest of the packet (if any) will be silently truncated which is fine. +#define SYZ_TUN_MAX_PACKET_SIZE 1000 + +// Maximum number of tun devices in the default install. +#define MAX_TUN 4 + +// All patterns are non-expanding given values < MAX_TUN. +#define TUN_IFACE "tap%d" +#define TUN_DEVICE "/dev/tap%d" + +#define LOCAL_IPV4 "172.20.%d.170" +#define LOCAL_IPV6 "fe80::%02hxaa" + +static void initialize_tun(int tun_id) +{ +#if SYZ_EXECUTOR + if (!flag_enable_tun) + return; +#endif // SYZ_EXECUTOR + + if (tun_id < 0 || tun_id >= MAX_TUN) { + fail("tun_id out of range %d\n", tun_id); + } + + char tun_device[sizeof(TUN_DEVICE)]; + snprintf_check(tun_device, sizeof(tun_device), TUN_DEVICE, tun_id); + + tunfd = open(tun_device, O_RDWR | O_NONBLOCK); + if (tunfd == -1) { +#if SYZ_EXECUTOR + fail("tun: can't open %s\n", tun_device); +#else + printf("tun: can't open %s: errno=%d\n", tun_device, errno); + return; +#endif // SYZ_EXECUTOR + } + // Remap tun onto higher fd number to hide it from fuzzer and to keep + // fd numbers stable regardless of whether tun is opened or not (also see kMaxFd). + const int kTunFd = 240; + if (dup2(tunfd, kTunFd) < 0) + fail("dup2(tunfd, kTunFd) failed"); + close(tunfd); + tunfd = kTunFd; + + char tun_iface[sizeof(TUN_IFACE)]; + snprintf_check(tun_iface, sizeof(tun_iface), TUN_IFACE, tun_id); + + char local_ipv4[sizeof(LOCAL_IPV4)]; + snprintf_check(local_ipv4, sizeof(local_ipv4), LOCAL_IPV4, tun_id); + execute_command(1, "ifconfig %s inet %s", tun_iface, local_ipv4); + + char local_ipv6[sizeof(LOCAL_IPV6)]; + snprintf_check(local_ipv6, sizeof(local_ipv6), LOCAL_IPV6, tun_id); + execute_command(1, "ifconfig %s inet6 %s", tun_iface, local_ipv6); +} + +#endif // SYZ_EXECUTOR || SYZ_TUN_ENABLE + +#if SYZ_EXECUTOR || __NR_syz_emit_ethernet && SYZ_TUN_ENABLE +#include +#include + +static long syz_emit_ethernet(long a0, long a1) +{ + // syz_emit_ethernet(len len[packet], packet ptr[in, eth_packet]) + if (tunfd < 0) + return (uintptr_t)-1; + + size_t length = a0; + const char* data = (char*)a1; + debug_dump_data(data, length); + + return write(tunfd, data, length); +} +#endif + +#if SYZ_EXECUTOR || SYZ_TUN_ENABLE && (__NR_syz_extract_tcp_res || SYZ_REPEAT) +#include + +static int read_tun(char* data, int size) +{ + if (tunfd < 0) + return -1; + + int rv = read(tunfd, data, size); + if (rv < 0) { + if (errno == EAGAIN) + return -1; + fail("tun: read failed with %d", rv); + } + return rv; +} #endif +#if SYZ_EXECUTOR || __NR_syz_extract_tcp_res && SYZ_TUN_ENABLE + +struct tcp_resources { + uint32 seq; + uint32 ack; +}; + +#include +#include +#include +#include +#include +#include +#include + +// Include order matters, empty line prevent re-sorting. +#include + +static long syz_extract_tcp_res(long a0, long a1, long a2) +{ + // syz_extract_tcp_res(res ptr[out, tcp_resources], seq_inc int32, ack_inc int32) + + if (tunfd < 0) + return (uintptr_t)-1; + + char data[SYZ_TUN_MAX_PACKET_SIZE]; + int rv = read_tun(&data[0], sizeof(data)); + if (rv == -1) + return (uintptr_t)-1; + size_t length = rv; + debug_dump_data(data, length); + + struct tcphdr* tcphdr; + + if (length < sizeof(struct ether_header)) + return (uintptr_t)-1; + struct ether_header* ethhdr = (struct ether_header*)&data[0]; + + if (ethhdr->ether_type == htons(ETHERTYPE_IP)) { + if (length < sizeof(struct ether_header) + sizeof(struct ip)) + return (uintptr_t)-1; + struct ip* iphdr = (struct ip*)&data[sizeof(struct ether_header)]; + if (iphdr->ip_p != IPPROTO_TCP) + return (uintptr_t)-1; + if (length < sizeof(struct ether_header) + iphdr->ip_hl * 4 + sizeof(struct tcphdr)) + return (uintptr_t)-1; + tcphdr = (struct tcphdr*)&data[sizeof(struct ether_header) + iphdr->ip_hl * 4]; + } else { + if (length < sizeof(struct ether_header) + sizeof(struct ip6_hdr)) + return (uintptr_t)-1; + struct ip6_hdr* ipv6hdr = (struct ip6_hdr*)&data[sizeof(struct ether_header)]; + // TODO: parse and skip extension headers. + if (ipv6hdr->ip6_nxt != IPPROTO_TCP) + return (uintptr_t)-1; + if (length < sizeof(struct ether_header) + sizeof(struct ip6_hdr) + sizeof(struct tcphdr)) + return (uintptr_t)-1; + tcphdr = (struct tcphdr*)&data[sizeof(struct ether_header) + sizeof(struct ip6_hdr)]; + } + + struct tcp_resources* res = (struct tcp_resources*)a0; + NONFAILING(res->seq = htonl((ntohl(tcphdr->th_seq) + (uint32)a1))); + NONFAILING(res->ack = htonl((ntohl(tcphdr->th_ack) + (uint32)a2))); + + debug("extracted seq: %08x\n", res->seq); + debug("extracted ack: %08x\n", res->ack); + + return 0; +} +#endif + +#if SYZ_EXECUTOR || SYZ_SANDBOX_NONE +static void loop(); +static int do_sandbox_none(void) +{ +#if SYZ_EXECUTOR || SYZ_TUN_ENABLE + initialize_tun(procid); #endif + loop(); + return 0; +} +#endif // SYZ_EXECUTOR || SYZ_SANDBOX_NONE + +#endif // GOOS_openbsd diff --git a/executor/defs.h b/executor/defs.h index 72ae20794..1b6da6208 100644 --- a/executor/defs.h +++ b/executor/defs.h @@ -130,7 +130,7 @@ #if GOARCH_amd64 #define GOARCH "amd64" -#define SYZ_REVISION "df30b58093a18d87ed6803bfe65ec9af86f721a3" +#define SYZ_REVISION "05e6185f1ea57bbe311ffe3829b1cca890f472fc" #define SYZ_EXECUTOR_USES_FORK_SERVER 1 #define SYZ_EXECUTOR_USES_SHMEM 1 #define SYZ_PAGE_SIZE 4096 diff --git a/executor/syscalls.h b/executor/syscalls.h index 9f01c99ff..fb0ea2d1c 100644 --- a/executor/syscalls.h +++ b/executor/syscalls.h @@ -12933,7 +12933,10 @@ const call_t syscalls[] = { {"symlink", 57}, {"symlinkat", 324}, {"sync", 36}, + {"syz_emit_ethernet", 0, (syscall_t)syz_emit_ethernet}, {"syz_execute_func", 0, (syscall_t)syz_execute_func}, + {"syz_extract_tcp_res", 0, (syscall_t)syz_extract_tcp_res}, + {"syz_extract_tcp_res$synack", 0, (syscall_t)syz_extract_tcp_res}, {"syz_open_pts", 0, (syscall_t)syz_open_pts}, {"truncate", 200}, {"unlink", 10}, diff --git a/pkg/csource/generated.go b/pkg/csource/generated.go index d467fe621..a5124979b 100644 --- a/pkg/csource/generated.go +++ b/pkg/csource/generated.go @@ -398,14 +398,51 @@ void child() #include -#if SYZ_EXECUTOR || SYZ_SANDBOX_NONE -static void loop(); -static int do_sandbox_none(void) +#include +#include +#include + +static void vsnprintf_check(char* str, size_t size, const char* format, va_list args) { - loop(); - return 0; + int rv; + + rv = vsnprintf(str, size, format, args); + if (rv < 0) + fail("vsnprintf failed"); + if ((size_t)rv >= size) + fail("vsnprintf: string '%s...' doesn't fit into buffer", str); +} + +static void snprintf_check(char* str, size_t size, const char* format, ...) +{ + va_list args; + + va_start(args, format); + vsnprintf_check(str, size, format, args); + va_end(args); +} + +#define COMMAND_MAX_LEN 128 +#define PATH_PREFIX "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin " +#define PATH_PREFIX_LEN (sizeof(PATH_PREFIX) - 1) + +static void execute_command(bool panic, const char* format, ...) +{ + va_list args; + char command[PATH_PREFIX_LEN + COMMAND_MAX_LEN]; + int rv; + + va_start(args, format); + memcpy(command, PATH_PREFIX, PATH_PREFIX_LEN); + vsnprintf_check(command + PATH_PREFIX_LEN, COMMAND_MAX_LEN, format, args); + va_end(args); + rv = system(command); + if (rv) { + if (panic) + fail("command '%s' failed: %d", &command[0], rv); + debug("command '%s': %d\n", &command[0], rv); + } } -#endif #if GOOS_openbsd @@ -433,6 +470,177 @@ static uintptr_t syz_open_pts(void) #endif +#if SYZ_EXECUTOR || SYZ_TUN_ENABLE + +#include +#include +#include + +static int tunfd = -1; +#define SYZ_TUN_MAX_PACKET_SIZE 1000 +#define MAX_TUN 4 +#define TUN_IFACE "tap%d" +#define TUN_DEVICE "/dev/tap%d" + +#define LOCAL_IPV4 "172.20.%d.170" +#define LOCAL_IPV6 "fe80::%02hxaa" + +static void initialize_tun(int tun_id) +{ +#if SYZ_EXECUTOR + if (!flag_enable_tun) + return; +#endif + + if (tun_id < 0 || tun_id >= MAX_TUN) { + fail("tun_id out of range %d\n", tun_id); + } + + char tun_device[sizeof(TUN_DEVICE)]; + snprintf_check(tun_device, sizeof(tun_device), TUN_DEVICE, tun_id); + + tunfd = open(tun_device, O_RDWR | O_NONBLOCK); + if (tunfd == -1) { +#if SYZ_EXECUTOR + fail("tun: can't open %s\n", tun_device); +#else + printf("tun: can't open %s: errno=%d\n", tun_device, errno); + return; +#endif + } + const int kTunFd = 240; + if (dup2(tunfd, kTunFd) < 0) + fail("dup2(tunfd, kTunFd) failed"); + close(tunfd); + tunfd = kTunFd; + + char tun_iface[sizeof(TUN_IFACE)]; + snprintf_check(tun_iface, sizeof(tun_iface), TUN_IFACE, tun_id); + + char local_ipv4[sizeof(LOCAL_IPV4)]; + snprintf_check(local_ipv4, sizeof(local_ipv4), LOCAL_IPV4, tun_id); + execute_command(1, "ifconfig %s inet %s", tun_iface, local_ipv4); + + char local_ipv6[sizeof(LOCAL_IPV6)]; + snprintf_check(local_ipv6, sizeof(local_ipv6), LOCAL_IPV6, tun_id); + execute_command(1, "ifconfig %s inet6 %s", tun_iface, local_ipv6); +} + +#endif + +#if SYZ_EXECUTOR || __NR_syz_emit_ethernet && SYZ_TUN_ENABLE +#include +#include + +static long syz_emit_ethernet(long a0, long a1) +{ + if (tunfd < 0) + return (uintptr_t)-1; + + size_t length = a0; + const char* data = (char*)a1; + debug_dump_data(data, length); + + return write(tunfd, data, length); +} +#endif + +#if SYZ_EXECUTOR || SYZ_TUN_ENABLE && (__NR_syz_extract_tcp_res || SYZ_REPEAT) +#include + +static int read_tun(char* data, int size) +{ + if (tunfd < 0) + return -1; + + int rv = read(tunfd, data, size); + if (rv < 0) { + if (errno == EAGAIN) + return -1; + fail("tun: read failed with %d", rv); + } + return rv; +} +#endif + +#if SYZ_EXECUTOR || __NR_syz_extract_tcp_res && SYZ_TUN_ENABLE + +struct tcp_resources { + uint32 seq; + uint32 ack; +}; + +#include +#include +#include +#include +#include +#include +#include +#include + +static long syz_extract_tcp_res(long a0, long a1, long a2) +{ + + if (tunfd < 0) + return (uintptr_t)-1; + + char data[SYZ_TUN_MAX_PACKET_SIZE]; + int rv = read_tun(&data[0], sizeof(data)); + if (rv == -1) + return (uintptr_t)-1; + size_t length = rv; + debug_dump_data(data, length); + + struct tcphdr* tcphdr; + + if (length < sizeof(struct ether_header)) + return (uintptr_t)-1; + struct ether_header* ethhdr = (struct ether_header*)&data[0]; + + if (ethhdr->ether_type == htons(ETHERTYPE_IP)) { + if (length < sizeof(struct ether_header) + sizeof(struct ip)) + return (uintptr_t)-1; + struct ip* iphdr = (struct ip*)&data[sizeof(struct ether_header)]; + if (iphdr->ip_p != IPPROTO_TCP) + return (uintptr_t)-1; + if (length < sizeof(struct ether_header) + iphdr->ip_hl * 4 + sizeof(struct tcphdr)) + return (uintptr_t)-1; + tcphdr = (struct tcphdr*)&data[sizeof(struct ether_header) + iphdr->ip_hl * 4]; + } else { + if (length < sizeof(struct ether_header) + sizeof(struct ip6_hdr)) + return (uintptr_t)-1; + struct ip6_hdr* ipv6hdr = (struct ip6_hdr*)&data[sizeof(struct ether_header)]; + if (ipv6hdr->ip6_nxt != IPPROTO_TCP) + return (uintptr_t)-1; + if (length < sizeof(struct ether_header) + sizeof(struct ip6_hdr) + sizeof(struct tcphdr)) + return (uintptr_t)-1; + tcphdr = (struct tcphdr*)&data[sizeof(struct ether_header) + sizeof(struct ip6_hdr)]; + } + + struct tcp_resources* res = (struct tcp_resources*)a0; + NONFAILING(res->seq = htonl((ntohl(tcphdr->th_seq) + (uint32)a1))); + NONFAILING(res->ack = htonl((ntohl(tcphdr->th_ack) + (uint32)a2))); + + debug("extracted seq: %08x\n", res->seq); + debug("extracted ack: %08x\n", res->ack); + + return 0; +} +#endif + +#if SYZ_EXECUTOR || SYZ_SANDBOX_NONE +static void loop(); +static int do_sandbox_none(void) +{ +#if SYZ_EXECUTOR || SYZ_TUN_ENABLE + initialize_tun(procid); +#endif + loop(); + return 0; +} +#endif + #endif #elif GOOS_fuchsia diff --git a/sys/openbsd/gen/amd64.go b/sys/openbsd/gen/amd64.go index 317e8f8e5..9b3b04f64 100644 --- a/sys/openbsd/gen/amd64.go +++ b/sys/openbsd/gen/amd64.go @@ -26,6 +26,7 @@ var resources_amd64 = []*ResourceDesc{ {Name: "sock_in", Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", TypeSize: 4}}}, Kind: []string{"fd", "sock", "sock_in"}, Values: []uint64{18446744073709551615, 18446744073709551516}}, {Name: "sock_in6", Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", TypeSize: 4}}}, Kind: []string{"fd", "sock", "sock_in6"}, Values: []uint64{18446744073709551615, 18446744073709551516}}, {Name: "sock_unix", Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", TypeSize: 4}}}, Kind: []string{"fd", "sock", "sock_unix"}, Values: []uint64{18446744073709551615, 18446744073709551516}}, + {Name: "tcp_seq_num", Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", TypeSize: 4}}}, Kind: []string{"tcp_seq_num"}, Values: []uint64{1094861636}}, {Name: "uid", Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", TypeSize: 4}}}, Kind: []string{"uid"}, Values: []uint64{0, 18446744073709551615}}, } @@ -342,6 +343,10 @@ var structDescs_amd64 = []*KeyedStruct{ &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", FldName: "pad1", TypeSize: 4, ArgDir: 1}}}, &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", FldName: "pad2", TypeSize: 4, ArgDir: 1}}}, }}}, + {Key: StructKey{Name: "tcp_resources", Dir: 1}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "tcp_resources", TypeSize: 8, ArgDir: 1}, Fields: []Type{ + &ResourceType{TypeCommon: TypeCommon{TypeName: "tcp_seq_num", FldName: "seq", TypeSize: 4, ArgDir: 1}}, + &ResourceType{TypeCommon: TypeCommon{TypeName: "tcp_seq_num", FldName: "ack", TypeSize: 4, ArgDir: 1}}, + }}}, {Key: StructKey{Name: "termios"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "termios", TypeSize: 44}, Fields: []Type{ &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", FldName: "iflag", TypeSize: 4}}}, &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", FldName: "oflag", TypeSize: 4}}}, @@ -1461,9 +1466,23 @@ var syscalls_amd64 = []*Syscall{ &PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "new", TypeSize: 8}, Type: &BufferType{TypeCommon: TypeCommon{TypeName: "filename", IsVarlen: true}, Kind: 3}}, }}, {NR: 36, Name: "sync", CallName: "sync"}, + {Name: "syz_emit_ethernet", CallName: "syz_emit_ethernet", Args: []Type{ + &LenType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "len", FldName: "len", TypeSize: 8}}, Buf: "packet"}, + &PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "packet", TypeSize: 8}, Type: &BufferType{TypeCommon: TypeCommon{TypeName: "array", IsVarlen: true}}}, + }}, {Name: "syz_execute_func", CallName: "syz_execute_func", Args: []Type{ &PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "text", TypeSize: 8}, Type: &BufferType{TypeCommon: TypeCommon{TypeName: "text", IsVarlen: true}, Kind: 4}}, }}, + {Name: "syz_extract_tcp_res", CallName: "syz_extract_tcp_res", Args: []Type{ + &PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "res", TypeSize: 8}, Type: &StructType{Key: StructKey{Name: "tcp_resources", Dir: 1}}}, + &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", FldName: "seq_inc", TypeSize: 4}}}, + &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", FldName: "ack_inc", TypeSize: 4}}}, + }}, + {Name: "syz_extract_tcp_res$synack", CallName: "syz_extract_tcp_res", Args: []Type{ + &PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "res", TypeSize: 8}, Type: &StructType{Key: StructKey{Name: "tcp_resources", Dir: 1}}}, + &ConstType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "const", FldName: "seq_inc", TypeSize: 8}}, Val: 1}, + &ConstType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "const", FldName: "ack_inc", TypeSize: 8}}}, + }}, {Name: "syz_open_pts", CallName: "syz_open_pts", Ret: &ResourceType{TypeCommon: TypeCommon{TypeName: "fd_tty", FldName: "ret", TypeSize: 4, ArgDir: 1}}}, {NR: 200, Name: "truncate", CallName: "truncate", Args: []Type{ &PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "file", TypeSize: 8}, Type: &BufferType{TypeCommon: TypeCommon{TypeName: "filename", IsVarlen: true}, Kind: 3}}, @@ -1893,4 +1912,4 @@ var consts_amd64 = []ConstValue{ {Name: "__MAP_NOREPLACE", Value: 2048}, } -const revision_amd64 = "df30b58093a18d87ed6803bfe65ec9af86f721a3" +const revision_amd64 = "05e6185f1ea57bbe311ffe3829b1cca890f472fc" diff --git a/sys/openbsd/vnet.txt b/sys/openbsd/vnet.txt new file mode 100644 index 000000000..1c9f99a04 --- /dev/null +++ b/sys/openbsd/vnet.txt @@ -0,0 +1,20 @@ +# 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. + +# TODO(blackgnezdo): discover a cheap way to share protocol +# descriptions between different OSs. They are platform agnostic +# and should not need to be recreated on each platform. + +syz_emit_ethernet(len len[packet], packet ptr[in, array[int8]]) + +resource tcp_seq_num[int32]: 0x41424344 + +tcp_resources { + seq tcp_seq_num + ack tcp_seq_num +} + +# These pseudo syscalls read a packet from tap device and extract tcp sequence and acknowledgement numbers from it. +# They also adds the inc arguments to the returned values, this way sequence numbers get incremented. +syz_extract_tcp_res(res ptr[out, tcp_resources], seq_inc int32, ack_inc int32) +syz_extract_tcp_res$synack(res ptr[out, tcp_resources], seq_inc const[1], ack_inc const[0]) -- cgit mrf-deployment