elastic-ebpf/GPL/Events/EbpfEventProto.h (337 lines of code) (raw):

// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause /* * Copyright (C) 2021 Elasticsearch BV * * This software is dual-licensed under the BSD 2-Clause and GPL v2 licenses. * You may choose either one of them if you use this software. */ #ifndef EBPF_EVENTPROBE_EBPFEVENTPROTO_H #define EBPF_EVENTPROBE_EBPFEVENTPROTO_H #define TASK_COMM_LEN 16 // The theoretical max size of DNS packets over UDP is 512. // Like so many things in DNS this number probaby isn't 100% accurate. // DNS extensions in RFC2671 and RFC6891 mean the actual size can be larger. #define MAX_DNS_PACKET 4096 #ifndef __KERNEL__ #include <stdint.h> #else #include "vmlinux.h" #endif enum ebpf_event_type { EBPF_EVENT_PROCESS_INVALID = 0, EBPF_EVENT_PROCESS_FORK = (1 << 0), EBPF_EVENT_PROCESS_EXEC = (1 << 1), EBPF_EVENT_PROCESS_EXIT = (1 << 2), EBPF_EVENT_PROCESS_SETSID = (1 << 3), EBPF_EVENT_PROCESS_SETUID = (1 << 4), EBPF_EVENT_PROCESS_SETGID = (1 << 5), EBPF_EVENT_PROCESS_TTY_WRITE = (1 << 6), EBPF_EVENT_FILE_DELETE = (1 << 7), EBPF_EVENT_FILE_CREATE = (1 << 8), EBPF_EVENT_FILE_RENAME = (1 << 9), EBPF_EVENT_FILE_MODIFY = (1 << 10), EBPF_EVENT_FILE_MEMFD_OPEN = (1 << 11), EBPF_EVENT_FILE_SHMEM_OPEN = (1 << 12), EBPF_EVENT_NETWORK_CONNECTION_ACCEPTED = (1 << 13), EBPF_EVENT_NETWORK_CONNECTION_ATTEMPTED = (1 << 14), EBPF_EVENT_NETWORK_CONNECTION_CLOSED = (1 << 15), EBPF_EVENT_PROCESS_MEMFD_CREATE = (1 << 16), EBPF_EVENT_PROCESS_SHMGET = (1 << 17), EBPF_EVENT_PROCESS_PTRACE = (1 << 18), EBPF_EVENT_PROCESS_LOAD_MODULE = (1 << 19), EBPF_EVENT_NETWORK_DNS_PKT = (1 << 20), }; struct ebpf_event_header { uint64_t ts; uint64_t ts_boot; uint64_t type; } __attribute__((packed)); // Some fields passed up (e.g. argv, path names) have a high maximum size but // most instances of them won't come close to hitting the maximum. Instead of // wasting a huge amount of memory by using a fixed-size buffer that's the // maximum possible size, we pack these fields into variable-length buffers at // the end of each event. If a new field to be added has a large maximum size // that won't often be reached, it should be added as a variable length field. enum ebpf_varlen_field_type { EBPF_VL_FIELD_CWD, EBPF_VL_FIELD_ARGV, EBPF_VL_FIELD_ENV, EBPF_VL_FIELD_FILENAME, EBPF_VL_FIELD_PATH, EBPF_VL_FIELD_OLD_PATH, EBPF_VL_FIELD_NEW_PATH, EBPF_VL_FIELD_TTY_OUT, EBPF_VL_FIELD_PIDS_SS_CGROUP_PATH, EBPF_VL_FIELD_SYMLINK_TARGET_PATH, EBPF_VL_FIELD_MOD_VERSION, EBPF_VL_FIELD_MOD_SRCVERSION, EBPF_VL_FIELD_DNS_BODY, }; // Convenience macro to iterate all the variable length fields in an event #define FOR_EACH_VARLEN_FIELD(vl_fields_start, cursor) \ cursor = (struct ebpf_varlen_field *)vl_fields_start.data; \ for (uint32_t __i = 0; __i < vl_fields_start.nfields; \ cursor = (struct ebpf_varlen_field *)((char *)cursor + cursor->size + \ sizeof(struct ebpf_varlen_field)), \ __i++) struct ebpf_varlen_fields_start { uint32_t nfields; size_t size; char data[]; } __attribute__((packed)); struct ebpf_varlen_field { enum ebpf_varlen_field_type type; uint32_t size; char data[]; } __attribute__((packed)); struct ebpf_pid_info { uint64_t start_time_ns; uint32_t tid; uint32_t tgid; uint32_t ppid; uint32_t pgid; uint32_t sid; } __attribute__((packed)); struct ebpf_cred_info { uint32_t ruid; // Real user ID uint32_t rgid; // Real group ID uint32_t euid; // Effective user ID uint32_t egid; // Effective group ID uint32_t suid; // Saved user ID uint32_t sgid; // Saved group ID uint64_t cap_permitted; uint64_t cap_effective; } __attribute__((packed)); struct ebpf_tty_winsize { uint16_t rows; uint16_t cols; } __attribute__((packed)); struct ebpf_tty_termios { uint32_t c_iflag; uint32_t c_oflag; uint32_t c_lflag; uint32_t c_cflag; } __attribute__((packed)); struct ebpf_tty_dev { uint16_t minor; uint16_t major; struct ebpf_tty_winsize winsize; struct ebpf_tty_termios termios; } __attribute__((packed)); enum ebpf_file_type { EBPF_FILE_TYPE_UNKNOWN = 0, EBPF_FILE_TYPE_FILE = 1, EBPF_FILE_TYPE_DIR = 2, EBPF_FILE_TYPE_SYMLINK = 3, EBPF_FILE_TYPE_CHARACTER_DEVICE = 4, EBPF_FILE_TYPE_BLOCK_DEVICE = 5, EBPF_FILE_TYPE_NAMED_PIPE = 6, EBPF_FILE_TYPE_SOCKET = 7, }; struct ebpf_file_info { enum ebpf_file_type type; uint64_t inode; uint16_t mode; uint64_t size; uint32_t uid; uint32_t gid; uint64_t atime; uint64_t mtime; uint64_t ctime; } __attribute__((packed)); struct ebpf_namespace_info { uint32_t uts_inonum; uint32_t ipc_inonum; uint32_t mnt_inonum; uint32_t net_inonum; uint32_t cgroup_inonum; uint32_t time_inonum; uint32_t pid_inonum; } __attribute__((packed)); // Full events follow struct ebpf_file_delete_event { struct ebpf_event_header hdr; struct ebpf_pid_info pids; struct ebpf_cred_info creds; struct ebpf_file_info finfo; uint32_t mntns; char comm[TASK_COMM_LEN]; // Variable length fields: path, symlink_target_path, pids_ss_cgroup_path struct ebpf_varlen_fields_start vl_fields; } __attribute__((packed)); // reused by memfd_open and shmem_open events struct ebpf_file_create_event { struct ebpf_event_header hdr; struct ebpf_pid_info pids; struct ebpf_cred_info creds; struct ebpf_file_info finfo; uint32_t mntns; char comm[TASK_COMM_LEN]; // Variable length fields: path, symlink_target_path, pids_ss_cgroup_path struct ebpf_varlen_fields_start vl_fields; } __attribute__((packed)); struct ebpf_file_rename_event { struct ebpf_event_header hdr; struct ebpf_pid_info pids; struct ebpf_cred_info creds; struct ebpf_file_info finfo; uint32_t mntns; char comm[TASK_COMM_LEN]; // Variable length fields: old_path, new_path, symlink_target_path, pids_ss_cgroup_path struct ebpf_varlen_fields_start vl_fields; } __attribute__((packed)); enum ebpf_file_change_type { EBPF_FILE_CHANGE_TYPE_UNKNOWN = 0, EBPF_FILE_CHANGE_TYPE_CONTENT = 1, EBPF_FILE_CHANGE_TYPE_PERMISSIONS = 2, EBPF_FILE_CHANGE_TYPE_OWNER = 3, EBPF_FILE_CHANGE_TYPE_XATTRS = 4, }; struct ebpf_file_modify_event { struct ebpf_event_header hdr; struct ebpf_pid_info pids; struct ebpf_cred_info creds; struct ebpf_file_info finfo; enum ebpf_file_change_type change_type; uint32_t mntns; char comm[TASK_COMM_LEN]; // Variable length fields: path, symlink_target_path, pids_ss_cgroup_path struct ebpf_varlen_fields_start vl_fields; } __attribute__((packed)); struct ebpf_process_fork_event { struct ebpf_event_header hdr; struct ebpf_pid_info parent_pids; struct ebpf_pid_info child_pids; struct ebpf_cred_info creds; struct ebpf_tty_dev ctty; char comm[TASK_COMM_LEN]; struct ebpf_namespace_info ns; // Variable length fields: pids_ss_cgroup_path struct ebpf_varlen_fields_start vl_fields; } __attribute__((packed)); #define EXEC_F_SETUID (1 << 0) #define EXEC_F_SETGID (1 << 1) #define EXEC_F_MEMFD (1 << 2) struct ebpf_process_exec_event { struct ebpf_event_header hdr; struct ebpf_pid_info pids; struct ebpf_cred_info creds; struct ebpf_tty_dev ctty; char comm[TASK_COMM_LEN]; struct ebpf_namespace_info ns; uint32_t inode_nlink; uint32_t flags; // Variable length fields: cwd, argv, env, filename, pids_ss_cgroup_path struct ebpf_varlen_fields_start vl_fields; } __attribute__((packed)); struct ebpf_process_exit_event { struct ebpf_event_header hdr; struct ebpf_pid_info pids; struct ebpf_cred_info creds; struct ebpf_tty_dev ctty; char comm[TASK_COMM_LEN]; struct ebpf_namespace_info ns; int32_t exit_code; // Variable length fields: pids_ss_cgroup_path struct ebpf_varlen_fields_start vl_fields; } __attribute__((packed)); struct ebpf_process_setsid_event { struct ebpf_event_header hdr; struct ebpf_pid_info pids; } __attribute__((packed)); struct ebpf_process_setuid_event { struct ebpf_event_header hdr; struct ebpf_pid_info pids; uint32_t new_ruid; uint32_t new_euid; uint32_t new_rgid; uint32_t new_egid; } __attribute__((packed)); struct ebpf_process_tty_write_event { struct ebpf_event_header hdr; struct ebpf_pid_info pids; uint64_t tty_out_truncated; // Controlling TTY. struct ebpf_tty_dev ctty; // Destination TTY. struct ebpf_tty_dev tty; char comm[TASK_COMM_LEN]; // Variable length fields: tty_out struct ebpf_varlen_fields_start vl_fields; } __attribute__((packed)); struct ebpf_process_setgid_event { struct ebpf_event_header hdr; struct ebpf_pid_info pids; uint32_t new_rgid; uint32_t new_egid; uint32_t new_ruid; uint32_t new_euid; } __attribute__((packed)); // from linux/memfd.h: // /* flags for memfd_create(2) (unsigned int) */ #ifndef MFD_CLOEXEC #define MFD_CLOEXEC 0x0001U #endif #ifndef MFD_ALLOW_SEALING #define MFD_ALLOW_SEALING 0x0002U #endif #ifndef MFD_HUGETLB #define MFD_HUGETLB 0x0004U #endif /* not executable and sealed to prevent changing to executable. */ #ifndef MFD_NOEXEC_SEAL #define MFD_NOEXEC_SEAL 0x0008U #endif /* executable */ #ifndef MFD_EXEC #define MFD_EXEC 0x0010U #endif struct ebpf_process_memfd_create_event { struct ebpf_event_header hdr; struct ebpf_pid_info pids; uint32_t flags; // memfd_create flags // Variable length fields: memfd name struct ebpf_varlen_fields_start vl_fields; } __attribute__((packed)); struct ebpf_process_shmget_event { struct ebpf_event_header hdr; struct ebpf_pid_info pids; int64_t key; uint64_t size; int64_t shmflg; // shmget() flags } __attribute__((packed)); struct ebpf_process_ptrace_event { struct ebpf_event_header hdr; struct ebpf_pid_info pids; uint32_t child_pid; int64_t request; } __attribute__((packed)); struct ebpf_process_load_module_event { struct ebpf_event_header hdr; struct ebpf_pid_info pids; // Variable length fields: filename, mod version, mod srcversion struct ebpf_varlen_fields_start vl_fields; } __attribute__((packed)); enum ebpf_net_info_transport { EBPF_NETWORK_EVENT_TRANSPORT_TCP = 1, EBPF_NETWORK_EVENT_TRANSPORT_UDP = 2, }; enum ebpf_net_info_af { EBPF_NETWORK_EVENT_AF_INET = 1, EBPF_NETWORK_EVENT_AF_INET6 = 2, }; enum ebpf_net_udp_info { EBPF_NETWORK_EVENT_SKB_CONSUME_UDP = 1, EBPF_NETWORK_EVENT_IP_SEND_UDP = 2, }; enum ebpf_net_packet_direction { EBPF_NETWORK_DIR_EGRESS = 1, EBPF_NETWORK_DIR_INGRESS = 2, }; struct ebpf_net_info_tcp_close { uint64_t bytes_sent; uint64_t bytes_received; } __attribute__((packed)); struct ebpf_net_info { enum ebpf_net_info_transport transport; enum ebpf_net_info_af family; union { uint8_t saddr[4]; uint8_t saddr6[16]; }; // Network byte order union { uint8_t daddr[4]; uint8_t daddr6[16]; }; // Network byte order uint16_t sport; // Host byte order uint16_t dport; // Host byte order uint32_t netns; union { struct ebpf_net_info_tcp_close close; } tcp; } __attribute__((packed)); struct ebpf_net_event { struct ebpf_event_header hdr; struct ebpf_pid_info pids; struct ebpf_net_info net; char comm[TASK_COMM_LEN]; } __attribute__((packed)); struct ebpf_dns_event { struct ebpf_event_header hdr; uint32_t tgid; uint32_t cap_len; uint32_t orig_len; enum ebpf_net_packet_direction direction; struct ebpf_varlen_fields_start vl_fields; } __attribute__((packed)); // Basic event statistics struct ebpf_event_stats { uint64_t lost; // lost events due to a full ringbuffer uint64_t sent; // events sent through the ringbuffer uint64_t dns_zero_body; // indicates that the dns body of a sk_buff was unavailable }; #endif // EBPF_EVENTPROBE_EBPFEVENTPROTO_H