| // Copyright 2022 The ChromiumOS Authors | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #ifndef SECAGENTD_BPF_PROCESS_H_ | |
| #define SECAGENTD_BPF_PROCESS_H_ | |
| #ifdef __cplusplus | |
| #include <stdint.h> | |
| #define _Static_assert static_assert | |
| namespace secagentd::bpf { | |
| #endif | |
| // The max arg size set by limits.h is ~128KB. To avoid consuming an absurd | |
| // amount of memory arguments will be truncated to 512 bytes. If all 512 | |
| // bytes are used the consuming userspace daemon will scrape procfs for the | |
| // entire command line. | |
| #define CROS_MAX_REDUCED_ARG_SIZE (512) | |
| // Although the maximum path size defined in linux/limits.h is larger we | |
| // truncate path sizes to keep memory usage reasonable. If needed the full path | |
| // name can be regenerated from the inode in image_info. | |
| #define CROS_MAX_PATH_SIZE (512) | |
| // The size of the buffer allocated from the BPF ring buffer. The size must be | |
| // large enough to hold the largest BPF event structure and must also be of | |
| // 2^N size. | |
| #define CROS_MAX_STRUCT_SIZE (2048) | |
| typedef uint64_t time_ns_t; | |
| // TODO(b/243571230): all of these struct fields map to kernel types. | |
| // Since including vmlinux.h directly in this file causes numerous compilation | |
| // errors with a cpp compiler we must instead pick a standard type. There is a | |
| // risk that the kernel types do not map well into these standard types for | |
| // certain architectures; so add static asserts to make sure we detect this | |
| // failure at compile time. | |
| // Fixed width version of timespec. | |
| struct cros_timespec { | |
| int64_t tv_sec; | |
| int64_t tv_nsec; | |
| }; | |
| // The image_info struct contains the security metrics | |
| // of interest for an executable file. | |
| struct cros_image_info { | |
| char pathname[CROS_MAX_PATH_SIZE]; | |
| uint64_t mnt_ns; | |
| uint32_t inode_device_id; | |
| uint32_t inode; | |
| uint32_t uid; | |
| uint32_t gid; | |
| uint32_t pid_for_setns; | |
| uint16_t mode; | |
| struct cros_timespec mtime; | |
| struct cros_timespec ctime; | |
| }; | |
| // The namespace_info struct contains the namespace information for a process. | |
| struct cros_namespace_info { | |
| uint64_t cgroup_ns; | |
| uint64_t pid_ns; | |
| uint64_t user_ns; | |
| uint64_t uts_ns; | |
| uint64_t mnt_ns; | |
| uint64_t net_ns; | |
| uint64_t ipc_ns; | |
| }; | |
| // This is the process information collected when a process starts or exits. | |
| struct cros_process_task_info { | |
| uint32_t pid; // The tgid. | |
| uint32_t ppid; // The tgid of parent. | |
| time_ns_t start_time; // Nanoseconds since boot. | |
| time_ns_t parent_start_time; // Nanoseconds since boot. | |
| char commandline[CROS_MAX_REDUCED_ARG_SIZE]; | |
| uint32_t commandline_len; // At most CROS_MAX_REDUCED_ARG_SIZE. | |
| uint32_t uid; | |
| uint32_t gid; | |
| }; | |
| // This is the process information collected when a process starts. | |
| struct cros_process_start { | |
| struct cros_process_task_info task_info; | |
| struct cros_image_info image_info; | |
| struct cros_namespace_info spawn_namespace; | |
| }; | |
| // This is the process information collected when a process exits. | |
| struct cros_process_exit { | |
| struct cros_process_task_info task_info; | |
| bool is_leaf; // True if process has no children. | |
| }; | |
| struct cros_process_change_namespace { | |
| // PID and start_time together will form a unique identifier for a process. | |
| // This unique identifier can be used to retrieve the rest of the process | |
| // information from a userspace process cache. | |
| uint32_t pid; | |
| time_ns_t start_time; | |
| struct cros_namespace_info new_ns; // The new namespace. | |
| }; | |
| // Indicates the type of process event is contained within the | |
| // event structure. | |
| enum cros_process_event_type { | |
| kProcessStartEvent, | |
| kProcessExitEvent, | |
| kProcessChangeNamespaceEvent | |
| }; | |
| // Contains information needed to report process security | |
| // event telemetry regarding processes. | |
| struct cros_process_event { | |
| enum cros_process_event_type type; | |
| union { | |
| struct cros_process_start process_start; | |
| struct cros_process_exit process_exit; | |
| struct cros_process_change_namespace process_change_namespace; | |
| } data; | |
| }; | |
| // The type of security event an event structure contains. | |
| enum cros_event_type { kProcessEvent }; | |
| // The security event structure that contains security event information | |
| // provided by a BPF application. | |
| struct cros_event { | |
| union { | |
| struct cros_process_event process_event; | |
| } data; | |
| enum cros_event_type type; | |
| }; | |
| // Ensure that the ring-buffer sample that is allocated is large enough. | |
| _Static_assert(sizeof(struct cros_event) <= CROS_MAX_STRUCT_SIZE, | |
| "Event structure exceeds maximum size."); | |
| #ifdef __cplusplus | |
| } // namespace secagentd::bpf | |
| #endif | |
| #endif // SECAGENTD_BPF_PROCESS_H_ |