crates/mimir-ingest/src/boundary/class.rs
//! The syscall CLASSES: what part of the system a system call reaches.
//! One class per syscall, from explicit name lists (a syscall no list names
//! is `system`, and the table tests assert every x86_64 and aarch64 syscall
//! is named by exactly one list, so a new kernel table cannot slip in unclassed).
/// What part of the system a system call reaches.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum Class {
/// Files, directories, file descriptors as files (read / write / open /
/// stat / ioctl …).
File,
/// Sockets: create, connect, send, receive, options.
Network,
/// Processes and threads: create, exec, exit, wait, ids, limits,
/// scheduling, namespaces, tracing.
Process,
/// Signal delivery and handling.
Signal,
/// The address space: map, protect, advise, lock, break.
Memory,
/// Clocks, sleeps, timers.
Time,
/// Inter-process / inter-thread communication: futexes, pipes, eventfd,
/// SysV and POSIX message queues, shared memory.
Ipc,
/// Waiting on many descriptors: poll / select / epoll / inotify /
/// fanotify / aio / io_uring.
Event,
/// The kernel's random source.
Random,
/// Administration of the machine: mounts, modules, reboot, BPF, keys,
/// LSM, quotas, host name, swap …
System,
/// A system call whose number is chosen at run time (`libc::syscall`, a
/// raw `syscall` instruction): the graph cannot say which one.
Indirect,
}
impl Class {
pub const ALL: &'static [Class] = &[
Class::File,
Class::Network,
Class::Process,
Class::Signal,
Class::Memory,
Class::Time,
Class::Ipc,
Class::Event,
Class::Random,
Class::System,
Class::Indirect,
];
pub fn as_str(self) -> &'static str {
match self {
Class::File => "file",
Class::Network => "network",
Class::Process => "process",
Class::Signal => "signal",
Class::Memory => "memory",
Class::Time => "time",
Class::Ipc => "ipc",
Class::Event => "event",
Class::Random => "random",
Class::System => "system",
Class::Indirect => "indirect",
}
}
pub fn parse(s: &str) -> Option<Class> {
Class::ALL.iter().copied().find(|c| c.as_str() == s)
}
}
impl std::fmt::Display for Class {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}
pub(crate) const FILE: &[&str] = &[
"read", "write", "open", "close", "stat", "fstat", "lstat", "lseek", "ioctl", "pread64", "pwrite64", "readv", "writev",
"access", "dup", "dup2", "dup3", "sendfile", "fcntl", "flock", "fsync", "fdatasync", "truncate", "ftruncate", "getdents",
"getdents64", "getcwd", "chdir", "fchdir", "rename", "mkdir", "rmdir", "creat", "link", "unlink", "symlink", "readlink",
"chmod", "fchmod", "chown", "fchown", "lchown", "umask", "utime", "utimes", "mknod", "ustat", "statfs", "fstatfs", "sysfs",
"chroot", "sync", "syncfs", "sync_file_range", "readahead", "setxattr", "lsetxattr", "fsetxattr", "getxattr", "lgetxattr",
"fgetxattr", "listxattr", "llistxattr", "flistxattr", "removexattr", "lremovexattr", "fremovexattr", "fadvise64",
"openat", "mkdirat", "mknodat", "fchownat", "futimesat", "newfstatat", "unlinkat", "renameat", "renameat2", "linkat",
"symlinkat", "readlinkat", "fchmodat", "fchmodat2", "faccessat", "faccessat2", "splice", "tee", "vmsplice", "utimensat",
"fallocate", "preadv", "pwritev", "preadv2", "pwritev2", "name_to_handle_at", "open_by_handle_at", "copy_file_range",
"statx", "close_range", "openat2", "cachestat", "setxattrat", "getxattrat", "listxattrat", "removexattrat",
"file_getattr", "file_setattr", "lookup_dcookie",
];
pub(crate) const NETWORK: &[&str] = &[
"socket", "connect", "accept", "accept4", "sendto", "recvfrom", "sendmsg", "recvmsg", "sendmmsg", "recvmmsg", "shutdown",
"bind", "listen", "getsockname", "getpeername", "socketpair", "setsockopt", "getsockopt",
];
pub(crate) const PROCESS: &[&str] = &[
"clone", "clone3", "fork", "vfork", "execve", "execveat", "exit", "exit_group", "wait4", "waitid", "kill", "tkill", "tgkill",
"getpid", "getppid", "gettid", "getuid", "geteuid", "getgid", "getegid", "setuid", "setgid", "setreuid", "setregid",
"setresuid", "getresuid", "setresgid", "getresgid", "setfsuid", "setfsgid", "getgroups", "setgroups", "setpgid",
"getpgid", "getpgrp", "setsid", "getsid", "capget", "capset", "prctl", "arch_prctl", "ptrace", "personality",
"getrlimit", "setrlimit", "prlimit64", "getrusage", "times", "getpriority", "setpriority", "sched_setparam",
"sched_getparam", "sched_setscheduler", "sched_getscheduler", "sched_get_priority_max", "sched_get_priority_min",
"sched_rr_get_interval", "sched_yield", "sched_setaffinity", "sched_getaffinity", "sched_setattr", "sched_getattr",
"set_tid_address", "set_thread_area", "get_thread_area", "modify_ldt", "unshare", "setns", "set_robust_list",
"get_robust_list", "rseq", "rseq_slice_yield", "seccomp", "kcmp", "process_vm_readv", "process_vm_writev",
"pidfd_open", "pidfd_send_signal", "pidfd_getfd", "ioprio_set", "ioprio_get", "getcpu", "restart_syscall", "uselib",
"vhangup", "uretprobe", "uprobe",
];
pub(crate) const SIGNAL: &[&str] = &[
"rt_sigaction", "rt_sigprocmask", "rt_sigreturn", "rt_sigpending", "rt_sigtimedwait", "rt_sigqueueinfo",
"rt_tgsigqueueinfo", "rt_sigsuspend", "sigaltstack", "pause", "signalfd", "signalfd4",
];
pub(crate) const MEMORY: &[&str] = &[
"mmap", "mprotect", "munmap", "brk", "mremap", "msync", "mincore", "madvise", "mlock", "munlock", "mlockall", "munlockall",
"mlock2", "remap_file_pages", "mbind", "set_mempolicy", "get_mempolicy", "set_mempolicy_home_node", "migrate_pages",
"move_pages", "membarrier", "pkey_mprotect", "pkey_alloc", "pkey_free", "memfd_create", "memfd_secret", "userfaultfd",
"process_madvise", "process_mrelease", "map_shadow_stack", "mseal",
];
pub(crate) const TIME: &[&str] = &[
"nanosleep", "clock_nanosleep", "clock_gettime", "clock_settime", "clock_getres", "clock_adjtime", "gettimeofday",
"settimeofday", "time", "alarm", "getitimer", "setitimer", "adjtimex", "timer_create", "timer_settime", "timer_gettime",
"timer_getoverrun", "timer_delete", "timerfd_create", "timerfd_settime", "timerfd_gettime",
];
pub(crate) const IPC: &[&str] = &[
"futex", "futex_waitv", "futex_wake", "futex_wait", "futex_requeue", "pipe", "pipe2", "eventfd", "eventfd2", "shmget",
"shmat", "shmctl", "shmdt", "semget", "semop", "semctl", "semtimedop", "msgget", "msgsnd", "msgrcv", "msgctl", "mq_open",
"mq_unlink", "mq_timedsend", "mq_timedreceive", "mq_notify", "mq_getsetattr",
];
pub(crate) const EVENT: &[&str] = &[
"poll", "ppoll", "select", "pselect6", "epoll_create", "epoll_create1", "epoll_ctl", "epoll_wait", "epoll_pwait",
"epoll_pwait2", "epoll_ctl_old", "epoll_wait_old", "inotify_init", "inotify_init1", "inotify_add_watch",
"inotify_rm_watch", "fanotify_init", "fanotify_mark", "io_setup", "io_destroy", "io_getevents", "io_submit", "io_cancel",
"io_pgetevents", "io_uring_setup", "io_uring_enter", "io_uring_register",
];
pub(crate) const RANDOM: &[&str] = &["getrandom"];
pub(crate) const SYSTEM: &[&str] = &[
"uname", "sysinfo", "syslog", "pivot_root", "_sysctl", "acct", "mount", "umount2", "swapon", "swapoff", "reboot",
"sethostname", "setdomainname", "iopl", "ioperm", "create_module", "init_module", "finit_module", "delete_module",
"get_kernel_syms", "query_module", "quotactl", "quotactl_fd", "nfsservctl", "getpmsg", "putpmsg", "afs_syscall",
"tuxcall", "security", "vserver", "kexec_load", "kexec_file_load", "add_key", "request_key", "keyctl", "perf_event_open",
"bpf", "open_tree", "open_tree_attr", "move_mount", "fsopen", "fsconfig", "fsmount", "fspick", "mount_setattr",
"statmount", "listmount", "listns", "landlock_create_ruleset", "landlock_add_rule", "landlock_restrict_self",
"lsm_get_self_attr", "lsm_set_self_attr", "lsm_list_modules",
];
/// The class lists, by class.
pub(crate) const LISTS: &[(Class, &[&str])] = &[
(Class::File, FILE),
(Class::Network, NETWORK),
(Class::Process, PROCESS),
(Class::Signal, SIGNAL),
(Class::Memory, MEMORY),
(Class::Time, TIME),
(Class::Ipc, IPC),
(Class::Event, EVENT),
(Class::Random, RANDOM),
(Class::System, SYSTEM),
];
/// The class of the system call `name` (`system` for one no list names).
pub fn class_of(name: &str) -> Class {
if name == super::INDIRECT {
return Class::Indirect;
}
LISTS.iter().find(|(_, l)| l.contains(&name)).map_or(Class::System, |(c, _)| *c)
}