diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2017-09-29 09:41:10 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2017-10-02 13:56:36 +0200 |
| commit | eb97aa06109e7b258c888b3c364533de17ec33ee (patch) | |
| tree | 1f345e449c62cf61a5b4417e866a8ca1c992b918 | |
| parent | ffd2a08fd98c0e0834def0cbec1cf94182f1df6f (diff) | |
executor: support fragmentation in syz_emit_ethernet
A recent linux commit "tun: enable napi_gro_frags() for TUN/TAP driver"
added support for fragmentation when emitting packets via tun.
Support this feature in syz_emit_ethernet.
| -rw-r--r-- | executor/common_linux.h | 98 | ||||
| -rw-r--r-- | executor/syscalls_linux.h | 10 | ||||
| -rw-r--r-- | pkg/csource/common.go | 83 | ||||
| -rw-r--r-- | sys/linux/386.go | 8 | ||||
| -rw-r--r-- | sys/linux/amd64.go | 8 | ||||
| -rw-r--r-- | sys/linux/arm.go | 8 | ||||
| -rw-r--r-- | sys/linux/arm64.go | 8 | ||||
| -rw-r--r-- | sys/linux/ppc64le.go | 8 | ||||
| -rw-r--r-- | sys/linux/vnet.txt | 10 |
9 files changed, 195 insertions, 46 deletions
diff --git a/executor/common_linux.h b/executor/common_linux.h index 3ad7d374f..e61a42902 100644 --- a/executor/common_linux.h +++ b/executor/common_linux.h @@ -263,6 +263,7 @@ static void execute_command(const char* format, ...) } static int tunfd = -1; +static int tun_frags_enabled; // 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. @@ -281,6 +282,13 @@ static int tunfd = -1; #define LOCAL_IPV6 "fe80::%02hxaa" #define REMOTE_IPV6 "fe80::%02hxbb" +#ifndef IFF_NAPI +#define IFF_NAPI 0x0010 +#endif +#ifndef IFF_NAPI_FRAGS +#define IFF_NAPI_FRAGS 0x0020 +#endif + static void initialize_tun(uint64_t pid) { if (pid >= MAX_PIDS) @@ -297,9 +305,19 @@ static void initialize_tun(uint64_t pid) struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, iface, IFNAMSIZ); - ifr.ifr_flags = IFF_TAP | IFF_NO_PI; - if (ioctl(tunfd, TUNSETIFF, (void*)&ifr) < 0) - fail("tun: ioctl(TUNSETIFF) failed"); + ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_NAPI | IFF_NAPI_FRAGS; + if (ioctl(tunfd, TUNSETIFF, (void*)&ifr) < 0) { + // IFF_NAPI_FRAGS requires root, so try without it. + ifr.ifr_flags = IFF_TAP | IFF_NO_PI; + if (ioctl(tunfd, TUNSETIFF, (void*)&ifr) < 0) + fail("tun: ioctl(TUNSETIFF) failed"); + } + // If IFF_NAPI_FRAGS is not supported it will be silently dropped, + // so query the effective flags. + if (ioctl(tunfd, TUNGETIFF, (void*)&ifr) < 0) + fail("tun: ioctl(TUNGETIFF) failed"); + tun_frags_enabled = (ifr.ifr_flags & IFF_NAPI_FRAGS) != 0; + debug("tun_frags_enabled=%d\n", tun_frags_enabled); char local_mac[ADDR_MAX_LEN]; snprintf_check(local_mac, sizeof(local_mac), LOCAL_MAC, id); @@ -345,7 +363,10 @@ static int read_tun(char* data, int size) if (rv < 0) { if (errno == EAGAIN) return -1; - fail("tun: read failed with %d, errno: %d", rv, errno); + // Tun sometimes returns this, unclear if it's a kernel bug or not. + if (errno == EBADFD) + return -1; + fail("tun: read failed with %d", rv); } return rv; } @@ -366,17 +387,60 @@ static void debug_dump_data(const char* data, int length) #endif #if defined(SYZ_EXECUTOR) || (defined(__NR_syz_emit_ethernet) && defined(SYZ_TUN_ENABLE)) -static uintptr_t syz_emit_ethernet(uintptr_t a0, uintptr_t a1) -{ - // syz_emit_ethernet(len len[packet], packet ptr[in, eth_packet]) +#define MAX_FRAGS 4 +struct vnet_fragmentation { + uint32_t full; + uint32_t count; + uint32_t frags[MAX_FRAGS]; +}; +static uintptr_t syz_emit_ethernet(uintptr_t a0, uintptr_t a1, uintptr_t a2) +{ + // syz_emit_ethernet(len len[packet], packet ptr[in, eth_packet], frags ptr[in, vnet_fragmentation, opt]) + // vnet_fragmentation { + // full int32[0:1] + // count len[frags, int32] + // frags array[int32[0:4096], 1:4] + // } if (tunfd < 0) return (uintptr_t)-1; - int64_t length = a0; + uint32_t length = a0; char* data = (char*)a1; debug_dump_data(data, length); - return write(tunfd, data, length); + + struct vnet_fragmentation* frags = (struct vnet_fragmentation*)a2; + struct iovec vecs[MAX_FRAGS + 1]; + uint32_t nfrags = 0; + if (!tun_frags_enabled || frags == NULL) { + vecs[nfrags].iov_base = data; + vecs[nfrags].iov_len = length; + nfrags++; + } else { + bool full = true; + uint32_t i, count = 0; + NONFAILING(full = frags->full); + NONFAILING(count = frags->count); + if (count > MAX_FRAGS) + count = MAX_FRAGS; + for (i = 0; i < count && length != 0; i++) { + uint32_t size = 0; + NONFAILING(size = frags->frags[i]); + if (size > length) + size = length; + vecs[nfrags].iov_base = data; + vecs[nfrags].iov_len = size; + nfrags++; + data += size; + length -= size; + } + if (length != 0 && (full || nfrags == 0)) { + vecs[nfrags].iov_base = data; + vecs[nfrags].iov_len = length; + nfrags++; + } + } + return writev(tunfd, vecs, nfrags); } #endif @@ -685,8 +749,6 @@ static bool write_file(const char* file, const char* what, ...) #if defined(SYZ_EXECUTOR) || defined(SYZ_SANDBOX_NAMESPACE) static int real_uid; static int real_gid; -static int epid; -static bool etun; __attribute__((aligned(64 << 10))) static char sandbox_stack[1 << 20]; static int namespace_sandbox_proc(void* arg) @@ -700,12 +762,6 @@ static int namespace_sandbox_proc(void* arg) if (!write_file("/proc/self/gid_map", "0 %d 1\n", real_gid)) fail("write of /proc/self/gid_map failed"); -#if defined(SYZ_EXECUTOR) || defined(SYZ_TUN_ENABLE) - // For sandbox namespace we setup tun after initializing uid mapping, - // otherwise ip commands fail. - setup_tun(epid, etun); -#endif - if (mkdir("./syz-tmp", 0777)) fail("mkdir(syz-tmp) failed"); if (mount("", "./syz-tmp", "tmpfs", 0, NULL)) @@ -759,10 +815,14 @@ static int namespace_sandbox_proc(void* arg) static int do_sandbox_namespace(int executor_pid, bool enable_tun) { +#if defined(SYZ_EXECUTOR) || defined(SYZ_TUN_ENABLE) + // For sandbox namespace we setup tun before dropping privs, + // because IFF_NAPI_FRAGS requires root. + setup_tun(executor_pid, enable_tun); +#endif + real_uid = getuid(); real_gid = getgid(); - epid = executor_pid; - etun = enable_tun; mprotect(sandbox_stack, 4096, PROT_NONE); // to catch stack underflows return clone(namespace_sandbox_proc, &sandbox_stack[sizeof(sandbox_stack) - 64], CLONE_NEWUSER | CLONE_NEWPID | CLONE_NEWUTS | CLONE_NEWNET, NULL); diff --git a/executor/syscalls_linux.h b/executor/syscalls_linux.h index b30807290..2f5842e1c 100644 --- a/executor/syscalls_linux.h +++ b/executor/syscalls_linux.h @@ -2,7 +2,7 @@ #if defined(__i386__) || 0 #define GOARCH "386" -#define SYZ_REVISION "7b2f1949d48094cf3369932d0743db166049457b" +#define SYZ_REVISION "20782fd14495c17a4a404316929c89e9d66373d6" #define __NR_syz_emit_ethernet 1000000 #define __NR_syz_extract_tcp_res 1000001 #define __NR_syz_fuse_mount 1000002 @@ -1501,7 +1501,7 @@ call_t syscalls[] = { #if defined(__x86_64__) || 0 #define GOARCH "amd64" -#define SYZ_REVISION "8349df62e623f9c8d8bfaefcc8ba3febf463ce92" +#define SYZ_REVISION "c1ab3550b8fbe92662ee054df76419327b5b72a7" #define __NR_syz_emit_ethernet 1000000 #define __NR_syz_extract_tcp_res 1000001 #define __NR_syz_fuse_mount 1000002 @@ -3061,7 +3061,7 @@ call_t syscalls[] = { #if defined(__arm__) || 0 #define GOARCH "arm" -#define SYZ_REVISION "02567c0623e18214f0be8d059aad68c263064645" +#define SYZ_REVISION "48d11406b51cb3dad2399863375cfc24d4892473" #define __NR_syz_emit_ethernet 1000000 #define __NR_syz_extract_tcp_res 1000001 #define __NR_syz_fuse_mount 1000002 @@ -4574,7 +4574,7 @@ call_t syscalls[] = { #if defined(__aarch64__) || 0 #define GOARCH "arm64" -#define SYZ_REVISION "0709fe60bdd20ea30d937d14615a40269fadb2b8" +#define SYZ_REVISION "65746b600515d1f1026ed56961d3450e70d65878" #define __NR_syz_emit_ethernet 1000000 #define __NR_syz_extract_tcp_res 1000001 #define __NR_syz_fuse_mount 1000002 @@ -6062,7 +6062,7 @@ call_t syscalls[] = { #if defined(__ppc64__) || defined(__PPC64__) || defined(__powerpc64__) || 0 #define GOARCH "ppc64le" -#define SYZ_REVISION "8bfb8686625fa3398eb8d1a5d66834dec0d3fa06" +#define SYZ_REVISION "5e9d29319478130f5d8b9238e869d979870e5cb3" #define __NR_syz_emit_ethernet 1000000 #define __NR_syz_extract_tcp_res 1000001 #define __NR_syz_fuse_mount 1000002 diff --git a/pkg/csource/common.go b/pkg/csource/common.go index 7f34a8753..1a759ede0 100644 --- a/pkg/csource/common.go +++ b/pkg/csource/common.go @@ -396,6 +396,7 @@ static void execute_command(const char* format, ...) } static int tunfd = -1; +static int tun_frags_enabled; #define SYZ_TUN_MAX_PACKET_SIZE 1000 @@ -411,6 +412,13 @@ static int tunfd = -1; #define LOCAL_IPV6 "fe80::%02hxaa" #define REMOTE_IPV6 "fe80::%02hxbb" +#ifndef IFF_NAPI +#define IFF_NAPI 0x0010 +#endif +#ifndef IFF_NAPI_FRAGS +#define IFF_NAPI_FRAGS 0x0020 +#endif + static void initialize_tun(uint64_t pid) { if (pid >= MAX_PIDS) @@ -427,9 +435,16 @@ static void initialize_tun(uint64_t pid) struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, iface, IFNAMSIZ); - ifr.ifr_flags = IFF_TAP | IFF_NO_PI; - if (ioctl(tunfd, TUNSETIFF, (void*)&ifr) < 0) - fail("tun: ioctl(TUNSETIFF) failed"); + ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_NAPI | IFF_NAPI_FRAGS; + if (ioctl(tunfd, TUNSETIFF, (void*)&ifr) < 0) { + ifr.ifr_flags = IFF_TAP | IFF_NO_PI; + if (ioctl(tunfd, TUNSETIFF, (void*)&ifr) < 0) + fail("tun: ioctl(TUNSETIFF) failed"); + } + if (ioctl(tunfd, TUNGETIFF, (void*)&ifr) < 0) + fail("tun: ioctl(TUNGETIFF) failed"); + tun_frags_enabled = (ifr.ifr_flags & IFF_NAPI_FRAGS) != 0; + debug("tun_frags_enabled=%d\n", tun_frags_enabled); char local_mac[ADDR_MAX_LEN]; snprintf_check(local_mac, sizeof(local_mac), LOCAL_MAC, id); @@ -472,7 +487,9 @@ static int read_tun(char* data, int size) if (rv < 0) { if (errno == EAGAIN) return -1; - fail("tun: read failed with %d, errno: %d", rv, errno); + if (errno == EBADFD) + return -1; + fail("tun: read failed with %d", rv); } return rv; } @@ -493,16 +510,54 @@ static void debug_dump_data(const char* data, int length) #endif #if defined(SYZ_EXECUTOR) || (defined(__NR_syz_emit_ethernet) && defined(SYZ_TUN_ENABLE)) -static uintptr_t syz_emit_ethernet(uintptr_t a0, uintptr_t a1) -{ +#define MAX_FRAGS 4 +struct vnet_fragmentation { + uint32_t full; + uint32_t count; + uint32_t frags[MAX_FRAGS]; +}; +static uintptr_t syz_emit_ethernet(uintptr_t a0, uintptr_t a1, uintptr_t a2) +{ if (tunfd < 0) return (uintptr_t)-1; - int64_t length = a0; + uint32_t length = a0; char* data = (char*)a1; debug_dump_data(data, length); - return write(tunfd, data, length); + + struct vnet_fragmentation* frags = (struct vnet_fragmentation*)a2; + struct iovec vecs[MAX_FRAGS + 1]; + uint32_t nfrags = 0; + if (!tun_frags_enabled || frags == NULL) { + vecs[nfrags].iov_base = data; + vecs[nfrags].iov_len = length; + nfrags++; + } else { + bool full = true; + uint32_t i, count = 0; + NONFAILING(full = frags->full); + NONFAILING(count = frags->count); + if (count > MAX_FRAGS) + count = MAX_FRAGS; + for (i = 0; i < count && length != 0; i++) { + uint32_t size = 0; + NONFAILING(size = frags->frags[i]); + if (size > length) + size = length; + vecs[nfrags].iov_base = data; + vecs[nfrags].iov_len = size; + nfrags++; + data += size; + length -= size; + } + if (length != 0 && (full || nfrags == 0)) { + vecs[nfrags].iov_base = data; + vecs[nfrags].iov_len = length; + nfrags++; + } + } + return writev(tunfd, vecs, nfrags); } #endif @@ -1745,8 +1800,6 @@ static bool write_file(const char* file, const char* what, ...) #if defined(SYZ_EXECUTOR) || defined(SYZ_SANDBOX_NAMESPACE) static int real_uid; static int real_gid; -static int epid; -static bool etun; __attribute__((aligned(64 << 10))) static char sandbox_stack[1 << 20]; static int namespace_sandbox_proc(void* arg) @@ -1759,10 +1812,6 @@ static int namespace_sandbox_proc(void* arg) if (!write_file("/proc/self/gid_map", "0 %d 1\n", real_gid)) fail("write of /proc/self/gid_map failed"); -#if defined(SYZ_EXECUTOR) || defined(SYZ_TUN_ENABLE) - setup_tun(epid, etun); -#endif - if (mkdir("./syz-tmp", 0777)) fail("mkdir(syz-tmp) failed"); if (mount("", "./syz-tmp", "tmpfs", 0, NULL)) @@ -1812,10 +1861,12 @@ static int namespace_sandbox_proc(void* arg) static int do_sandbox_namespace(int executor_pid, bool enable_tun) { +#if defined(SYZ_EXECUTOR) || defined(SYZ_TUN_ENABLE) + setup_tun(executor_pid, enable_tun); +#endif + real_uid = getuid(); real_gid = getgid(); - epid = executor_pid; - etun = enable_tun; mprotect(sandbox_stack, 4096, PROT_NONE); return clone(namespace_sandbox_proc, &sandbox_stack[sizeof(sandbox_stack) - 64], CLONE_NEWUSER | CLONE_NEWPID | CLONE_NEWUTS | CLONE_NEWNET, NULL); diff --git a/sys/linux/386.go b/sys/linux/386.go index 431f21d24..72a1a89fc 100644 --- a/sys/linux/386.go +++ b/sys/linux/386.go @@ -5563,6 +5563,11 @@ var structDescs_386 = []*KeyedStruct{ &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "dei", TypeSize: 2}, BitfieldOff: 3, BitfieldLen: 1, BitfieldMdl: true}}, &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "vid", TypeSize: 2}, BitfieldOff: 4, BitfieldLen: 12}}, }}}, + {Key: StructKey{Name: "vnet_fragmentation"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "vnet_fragmentation"}, Fields: []Type{ + &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", FldName: "full", TypeSize: 4}}, Kind: 2, RangeEnd: 1}, + &LenType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "len", FldName: "count", TypeSize: 4}}, Buf: "frags"}, + &ArrayType{TypeCommon: TypeCommon{TypeName: "array", FldName: "frags"}, Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", TypeSize: 4}}, Kind: 2, RangeEnd: 4096}, Kind: 1, RangeBegin: 1, RangeEnd: 4}, + }}}, {Key: StructKey{Name: "vt_consize"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "vt_consize", TypeSize: 12}, Fields: []Type{ &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "rows", TypeSize: 2}}}, &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "cols", TypeSize: 2}}}, @@ -13119,6 +13124,7 @@ var syscalls_386 = []*Syscall{ {ID: 1333, NR: 1000000, Name: "syz_emit_ethernet", CallName: "syz_emit_ethernet", Args: []Type{ &LenType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "len", FldName: "len", TypeSize: 4}}, Buf: "packet"}, &PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "packet", TypeSize: 4}, Type: &StructType{Key: StructKey{Name: "eth_packet"}}}, + &PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "frags", TypeSize: 4, IsOptional: true}, Type: &StructType{Key: StructKey{Name: "vnet_fragmentation"}}}, }}, {ID: 1334, NR: 1000001, Name: "syz_extract_tcp_res", CallName: "syz_extract_tcp_res", Args: []Type{ &PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "res", TypeSize: 4}, Type: &StructType{Key: StructKey{Name: "tcp_resources", Dir: 1}}}, @@ -16734,4 +16740,4 @@ var consts_386 = []ConstValue{ {Name: "__WNOTHREAD", Value: 536870912}, } -const revision_386 = "7b2f1949d48094cf3369932d0743db166049457b" +const revision_386 = "20782fd14495c17a4a404316929c89e9d66373d6" diff --git a/sys/linux/amd64.go b/sys/linux/amd64.go index 1a43b6760..c5f751a67 100644 --- a/sys/linux/amd64.go +++ b/sys/linux/amd64.go @@ -5745,6 +5745,11 @@ var structDescs_amd64 = []*KeyedStruct{ &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "dei", TypeSize: 2}, BitfieldOff: 3, BitfieldLen: 1, BitfieldMdl: true}}, &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "vid", TypeSize: 2}, BitfieldOff: 4, BitfieldLen: 12}}, }}}, + {Key: StructKey{Name: "vnet_fragmentation"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "vnet_fragmentation"}, Fields: []Type{ + &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", FldName: "full", TypeSize: 4}}, Kind: 2, RangeEnd: 1}, + &LenType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "len", FldName: "count", TypeSize: 4}}, Buf: "frags"}, + &ArrayType{TypeCommon: TypeCommon{TypeName: "array", FldName: "frags"}, Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", TypeSize: 4}}, Kind: 2, RangeEnd: 4096}, Kind: 1, RangeBegin: 1, RangeEnd: 4}, + }}}, {Key: StructKey{Name: "vt_consize"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "vt_consize", TypeSize: 12}, Fields: []Type{ &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "rows", TypeSize: 2}}}, &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "cols", TypeSize: 2}}}, @@ -13616,6 +13621,7 @@ var syscalls_amd64 = []*Syscall{ {ID: 1394, NR: 1000000, 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: &StructType{Key: StructKey{Name: "eth_packet"}}}, + &PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "frags", TypeSize: 8, IsOptional: true}, Type: &StructType{Key: StructKey{Name: "vnet_fragmentation"}}}, }}, {ID: 1395, NR: 1000001, 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}}}, @@ -17264,4 +17270,4 @@ var consts_amd64 = []ConstValue{ {Name: "__WNOTHREAD", Value: 536870912}, } -const revision_amd64 = "8349df62e623f9c8d8bfaefcc8ba3febf463ce92" +const revision_amd64 = "c1ab3550b8fbe92662ee054df76419327b5b72a7" diff --git a/sys/linux/arm.go b/sys/linux/arm.go index 5c4fddab6..2e85a49c7 100644 --- a/sys/linux/arm.go +++ b/sys/linux/arm.go @@ -5420,6 +5420,11 @@ var structDescs_arm = []*KeyedStruct{ &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "dei", TypeSize: 2}, BitfieldOff: 3, BitfieldLen: 1, BitfieldMdl: true}}, &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "vid", TypeSize: 2}, BitfieldOff: 4, BitfieldLen: 12}}, }}}, + {Key: StructKey{Name: "vnet_fragmentation"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "vnet_fragmentation"}, Fields: []Type{ + &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", FldName: "full", TypeSize: 4}}, Kind: 2, RangeEnd: 1}, + &LenType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "len", FldName: "count", TypeSize: 4}}, Buf: "frags"}, + &ArrayType{TypeCommon: TypeCommon{TypeName: "array", FldName: "frags"}, Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", TypeSize: 4}}, Kind: 2, RangeEnd: 4096}, Kind: 1, RangeBegin: 1, RangeEnd: 4}, + }}}, {Key: StructKey{Name: "vt_consize"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "vt_consize", TypeSize: 12}, Fields: []Type{ &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "rows", TypeSize: 2}}}, &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "cols", TypeSize: 2}}}, @@ -13062,6 +13067,7 @@ var syscalls_arm = []*Syscall{ {ID: 1347, NR: 1000000, Name: "syz_emit_ethernet", CallName: "syz_emit_ethernet", Args: []Type{ &LenType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "len", FldName: "len", TypeSize: 4}}, Buf: "packet"}, &PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "packet", TypeSize: 4}, Type: &StructType{Key: StructKey{Name: "eth_packet"}}}, + &PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "frags", TypeSize: 4, IsOptional: true}, Type: &StructType{Key: StructKey{Name: "vnet_fragmentation"}}}, }}, {ID: 1348, NR: 1000001, Name: "syz_extract_tcp_res", CallName: "syz_extract_tcp_res", Args: []Type{ &PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "res", TypeSize: 4}, Type: &StructType{Key: StructKey{Name: "tcp_resources", Dir: 1}}}, @@ -16631,4 +16637,4 @@ var consts_arm = []ConstValue{ {Name: "__WNOTHREAD", Value: 536870912}, } -const revision_arm = "02567c0623e18214f0be8d059aad68c263064645" +const revision_arm = "48d11406b51cb3dad2399863375cfc24d4892473" diff --git a/sys/linux/arm64.go b/sys/linux/arm64.go index 39061d67a..c293f4594 100644 --- a/sys/linux/arm64.go +++ b/sys/linux/arm64.go @@ -5521,6 +5521,11 @@ var structDescs_arm64 = []*KeyedStruct{ &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "dei", TypeSize: 2}, BitfieldOff: 3, BitfieldLen: 1, BitfieldMdl: true}}, &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "vid", TypeSize: 2}, BitfieldOff: 4, BitfieldLen: 12}}, }}}, + {Key: StructKey{Name: "vnet_fragmentation"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "vnet_fragmentation"}, Fields: []Type{ + &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", FldName: "full", TypeSize: 4}}, Kind: 2, RangeEnd: 1}, + &LenType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "len", FldName: "count", TypeSize: 4}}, Buf: "frags"}, + &ArrayType{TypeCommon: TypeCommon{TypeName: "array", FldName: "frags"}, Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", TypeSize: 4}}, Kind: 2, RangeEnd: 4096}, Kind: 1, RangeBegin: 1, RangeEnd: 4}, + }}}, {Key: StructKey{Name: "vt_consize"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "vt_consize", TypeSize: 12}, Fields: []Type{ &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "rows", TypeSize: 2}}}, &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "cols", TypeSize: 2}}}, @@ -13100,6 +13105,7 @@ var syscalls_arm64 = []*Syscall{ {ID: 1328, NR: 1000000, 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: &StructType{Key: StructKey{Name: "eth_packet"}}}, + &PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "frags", TypeSize: 8, IsOptional: true}, Type: &StructType{Key: StructKey{Name: "vnet_fragmentation"}}}, }}, {ID: 1329, NR: 1000001, 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}}}, @@ -16641,4 +16647,4 @@ var consts_arm64 = []ConstValue{ {Name: "__WNOTHREAD", Value: 536870912}, } -const revision_arm64 = "0709fe60bdd20ea30d937d14615a40269fadb2b8" +const revision_arm64 = "65746b600515d1f1026ed56961d3450e70d65878" diff --git a/sys/linux/ppc64le.go b/sys/linux/ppc64le.go index 1c02c5a08..cea138274 100644 --- a/sys/linux/ppc64le.go +++ b/sys/linux/ppc64le.go @@ -5378,6 +5378,11 @@ var structDescs_ppc64le = []*KeyedStruct{ &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "dei", TypeSize: 2}, BitfieldOff: 3, BitfieldLen: 1, BitfieldMdl: true}}, &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "vid", TypeSize: 2}, BitfieldOff: 4, BitfieldLen: 12}}, }}}, + {Key: StructKey{Name: "vnet_fragmentation"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "vnet_fragmentation"}, Fields: []Type{ + &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", FldName: "full", TypeSize: 4}}, Kind: 2, RangeEnd: 1}, + &LenType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "len", FldName: "count", TypeSize: 4}}, Buf: "frags"}, + &ArrayType{TypeCommon: TypeCommon{TypeName: "array", FldName: "frags"}, Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", TypeSize: 4}}, Kind: 2, RangeEnd: 4096}, Kind: 1, RangeBegin: 1, RangeEnd: 4}, + }}}, {Key: StructKey{Name: "vt_consize"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "vt_consize", TypeSize: 12}, Fields: []Type{ &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "rows", TypeSize: 2}}}, &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "cols", TypeSize: 2}}}, @@ -12778,6 +12783,7 @@ var syscalls_ppc64le = []*Syscall{ {ID: 1303, NR: 1000000, 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: &StructType{Key: StructKey{Name: "eth_packet"}}}, + &PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "frags", TypeSize: 8, IsOptional: true}, Type: &StructType{Key: StructKey{Name: "vnet_fragmentation"}}}, }}, {ID: 1304, NR: 1000001, 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}}}, @@ -16330,4 +16336,4 @@ var consts_ppc64le = []ConstValue{ {Name: "__WNOTHREAD", Value: 536870912}, } -const revision_ppc64le = "8bfb8686625fa3398eb8d1a5d66834dec0d3fa06" +const revision_ppc64le = "5e9d29319478130f5d8b9238e869d979870e5cb3" diff --git a/sys/linux/vnet.txt b/sys/linux/vnet.txt index 3ec5430b8..0389f7133 100644 --- a/sys/linux/vnet.txt +++ b/sys/linux/vnet.txt @@ -4,7 +4,15 @@ include <linux/types.h> include <linux/byteorder/generic.h> -syz_emit_ethernet(len len[packet], packet ptr[in, eth_packet]) +syz_emit_ethernet(len len[packet], packet ptr[in, eth_packet], frags ptr[in, vnet_fragmentation, opt]) + +vnet_fragmentation { +# If set and we have remaining data after fragmentation, it is written in an additional fragment. +# If not set, data remaining after fragmentation is discarded. + full int32[0:1] + count len[frags, int32] + frags array[int32[0:4096], 1:4] +} resource tcp_seq_num[int32]: 0x42424242 |
