diff options
| author | Cheng-Min Chiang <chmnchiang@google.com> | 2020-07-24 18:05:18 -0700 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2020-08-07 09:28:26 +0200 |
| commit | 20a3465b973bec140ff12740acffa6c357b27edc (patch) | |
| tree | 055bd8837d2f68319165366dfc273ea8b891a92c /pkg/csource | |
| parent | cb436c69d9bcb0330518a48559649c9436ed5e7a (diff) | |
sys/linux: add descriptions for BPF LSM
This commit includes the following changes:
* executor: add a new syz_btf_id_by_name psuedo-syscall
* sys/linux: add descriptions for BPF LSM subsystem
* sys/linux: add instructions on how to dump vmlinux and install
bpftool
* sys/linux/test: add tests for the new psuedo-syscall
* pkg/host: add support detection for the new psuedo-syscall
* pkg/runtest: skip the coverage test when invoking the new
psuedo-syscall
Update #533.
Diffstat (limited to 'pkg/csource')
| -rw-r--r-- | pkg/csource/generated.go | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/pkg/csource/generated.go b/pkg/csource/generated.go index dda5a5525..2643c8767 100644 --- a/pkg/csource/generated.go +++ b/pkg/csource/generated.go @@ -3660,6 +3660,171 @@ static long syz_io_uring_submit(volatile long a0, volatile long a1, volatile lon #endif #endif + +#if SYZ_EXECUTOR || __NR_syz_btf_id_by_name + +#include <errno.h> +#include <fcntl.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <unistd.h> +#define BTF_MAGIC 0xeB9F + +struct btf_header { + __u16 magic; + __u8 version; + __u8 flags; + __u32 hdr_len; + __u32 type_off; + __u32 type_len; + __u32 str_off; + __u32 str_len; +}; + +#define BTF_INFO_KIND(info) (((info) >> 24) & 0x0f) +#define BTF_INFO_VLEN(info) ((info)&0xffff) + +#define BTF_KIND_INT 1 +#define BTF_KIND_ARRAY 3 +#define BTF_KIND_STRUCT 4 +#define BTF_KIND_UNION 5 +#define BTF_KIND_ENUM 6 +#define BTF_KIND_FUNC_PROTO 13 +#define BTF_KIND_VAR 14 +#define BTF_KIND_DATASEC 15 + +struct btf_type { + __u32 name_off; + __u32 info; + union { + __u32 size; + __u32 type; + }; +}; + +struct btf_enum { + __u32 name_off; + __s32 val; +}; + +struct btf_array { + __u32 type; + __u32 index_type; + __u32 nelems; +}; + +struct btf_member { + __u32 name_off; + __u32 type; + __u32 offset; +}; + +struct btf_param { + __u32 name_off; + __u32 type; +}; + +struct btf_var { + __u32 linkage; +}; + +struct btf_var_secinfo { + __u32 type; + __u32 offset; + __u32 size; +}; +#define VMLINUX_MAX_SUPPORT_SIZE (10 * 1024 * 1024) +static char* read_btf_vmlinux() +{ + static bool is_read = false; + static char buf[VMLINUX_MAX_SUPPORT_SIZE]; + if (is_read) + return buf; + + int fd = open("/sys/kernel/btf/vmlinux", O_RDONLY); + if (fd < 0) + return NULL; + + unsigned long bytes_read = 0; + for (;;) { + ssize_t ret = read(fd, buf + bytes_read, + VMLINUX_MAX_SUPPORT_SIZE - bytes_read); + + if (ret < 0 || bytes_read + ret == VMLINUX_MAX_SUPPORT_SIZE) + return NULL; + + if (ret == 0) + break; + + bytes_read += ret; + } + + is_read = true; + return buf; +} +static long syz_btf_id_by_name(volatile long a0) +{ + char* target = (char*)a0; + + char* vmlinux = read_btf_vmlinux(); + if (vmlinux == NULL) + return -1; + + struct btf_header* btf_header = (struct btf_header*)vmlinux; + if (btf_header->magic != BTF_MAGIC) + return -1; + char* btf_type_sec = vmlinux + btf_header->hdr_len + btf_header->type_off; + char* btf_str_sec = vmlinux + btf_header->hdr_len + btf_header->str_off; + unsigned int bytes_parsed = 0; + long idx = 1; + while (bytes_parsed < btf_header->type_len) { + struct btf_type* btf_type = (struct btf_type*)(btf_type_sec + bytes_parsed); + uint32 kind = BTF_INFO_KIND(btf_type->info); + uint32 vlen = BTF_INFO_VLEN(btf_type->info); + char* name = btf_str_sec + btf_type->name_off; + + if (strcmp(name, target) == 0) + return idx; + size_t skip; + switch (kind) { + case BTF_KIND_INT: + skip = sizeof(uint32); + break; + case BTF_KIND_ENUM: + skip = sizeof(struct btf_enum) * vlen; + break; + case BTF_KIND_ARRAY: + skip = sizeof(struct btf_array); + break; + case BTF_KIND_STRUCT: + case BTF_KIND_UNION: + skip = sizeof(struct btf_member) * vlen; + break; + case BTF_KIND_FUNC_PROTO: + skip = sizeof(struct btf_param) * vlen; + break; + case BTF_KIND_VAR: + skip = sizeof(struct btf_var); + break; + case BTF_KIND_DATASEC: + skip = sizeof(struct btf_var_secinfo) * vlen; + break; + default: + skip = 0; + } + + bytes_parsed += sizeof(struct btf_type) + skip; + idx++; + } + + return -1; +} + +#endif #if SYZ_EXECUTOR || __NR_syz_memcpy_off static long syz_memcpy_off(volatile long a0, volatile long a1, volatile long a2, volatile long a3, volatile long a4) { |
