//
// Syd: rock-solid unikernel
// src/config.rs: Static configuration, edit & recompile!
//
// Copyright (c) 2023, 2024 Ali Polatel <alip@chesswob.org>
// Based in part upon HardenedBSD's sys/hardenedbsd/hbsd_pax_segvguard.c which is:
//   Copyright (c) 2006 Elad Efrat <elad@NetBSD.org>
//   Copyright (c) 2013-2017, by Oliver Pinter <oliver.pinter@hardenedbsd.org>
//   Copyright (c) 2014, by Shawn Webb <shawn.webb@hardenedbsd.org>
//   Copyright (c) 2014, by Danilo Egea Gondolfo <danilo at FreeBSD.org>
//   All rights reserved.
//   SPDX-License-Identifier: BSD-3-Clause
// Based in part upon gVisor's kvm_const*.go which is:
//   Copyright 2018 The gVisor Authors.
//   SPDX-License-Identifier: Apache-2.0
// Based in part upon kvm-ioctls' kvm-ioctls.rs which is:
//   Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
//   SPDX-License-Identifier: Apache-2.0 OR MIT
//
// SPDX-License-Identifier: GPL-3.0-or-later

use std::time::Duration;

use nix::unistd::{sysconf, SysconfVar};
use once_cell::sync::Lazy;

use crate::{caps::Capability, landlock::ABI};

// Convenience type to list {io,pr}ctls with their names.
type KeyValue<'a> = (&'a str, u64);

/// Landlock API in use.
pub const LANDLOCK_ABI: ABI = ABI::V3;
/// Landlock API string representation.
pub const LANDLOCK_ABI_STR: &str = "v3";

/// Path to /etc.
pub const PATH_ETC: &str = "/etc";

/// Path to a temporary directory.
///
/// This directory is used to create temporary directories during
/// private shm & tmp creation so for the cleanup at exit to work
/// this directory must not be under /dev/shm or /tmp.
pub const PATH_TMP: &str = "/var/tmp";

/// The default shell to execute.
/// Change this if your system doesn't have /bin/sh,
/// or set the environment variable SYD_SH.
pub const SYD_SH: &str = "/bin/sh";

/// The environment variable to read the default shell from
pub const ENV_SH: &str = "SYD_SH";
/// The environment variable to read the log level from.
pub const ENV_LOG: &str = "SYD_LOG";

/// The environment variable to set to disable logging to syslog.
pub const ENV_NO_SYSLOG: &str = "SYD_NO_SYSLOG";

/// The environment variable to set to disable cross memory attach, and fallback to /proc/pid/mem.
pub const ENV_NO_CROSS_MEMORY_ATTACH: &str = "SYD_NO_CROSS_MEMORY_ATTACH";

/// The environment variable to set to log to a different fd than standard error.
pub const ENV_LOG_FD: &str = "SYD_LOG_FD";

/// The environment variable to set for quick boot.
///
/// This makes Syd startup noticably faster,
/// however it removes a layer of defense against some container breaks.
/// Use this if you frequently re-execute syd{,-oci} such as we do on
/// Exherbo during Paludis' generate metadata phase.
pub const ENV_QUICK_BOOT: &str = "SYD_QUICK_BOOT";

/// SafeSetID does not allow UID transitions for UIDs less than or equal to UID_MIN.
/// 11 is typically the `operator` user.
pub const UID_MIN: u64 = 11;

/// SafeSetID does not allow GID transitions for GIDs less than or equal to GID_MIN.
/// 14 is typically the `uucp` group.
pub const GID_MIN: u64 = 14;

/// Path prefix for magic stat commands.
pub const MAGIC_PREFIX: &str = "/dev/syd";

/// Path to the file which will be used as file status for magic stat commands.
pub const MAGIC_FILE: &str = "/dev/null";

/// syd version
pub static VERSION: Lazy<&'static str> = Lazy::new(|| {
    #[allow(clippy::if_same_then_else)]
    #[allow(clippy::branches_sharing_code)]
    if env!("SYD_GITHEAD").is_empty() {
        env!("CARGO_PKG_VERSION")
    } else {
        env!("SYD_GITHEAD")
    }
});

/// Api version of the configuration.
pub const API_VERSION: &str = env!("CARGO_PKG_VERSION_MAJOR");

/// System page size
#[allow(clippy::cast_sign_loss)]
pub static PAGE_SIZE: Lazy<u64> = Lazy::new(|| {
    sysconf(SysconfVar::PAGE_SIZE)
        .unwrap_or(Some(4096))
        .unwrap_or(4096) as u64
});

/// The system-interent limit for the size of one zero-copy operation
/// is 16 pages. If more data is to be sent to AF_ALG, user space
/// must slice the input into segments with a maximum size of 16
/// pages.
#[allow(clippy::cast_possible_truncation)]
pub static KCAPI_SIZE: Lazy<usize> = Lazy::new(|| 16 * (*PAGE_SIZE as usize));

/// Pipe buffer size.
///
/// Before Linux 2.6.11, the capacity of a pipe was the same as the
/// system page size (e.g., 4096 bytes on i386). Since Linux 2.6.11,
/// the pipe capacity is 16 pages (i.e., 65,536 bytes in a system
/// with a page size of 4096 bytes). Since Linux 2.6.35, the default
/// pipe capacity is 16 pages, but the capacity can be queried and set
/// using the fcntl(2) F_GETPIPE_SZ and F_SETPIPE_SZ operations.
#[allow(clippy::cast_possible_truncation)]
pub static PIPE_BUF: Lazy<usize> = Lazy::new(|| 16usize.saturating_mul(*PAGE_SIZE as usize));

/// Default buffer size used in `compat::get_directory_entries` function.
pub const GETDENTS_BUFFER_SIZE: usize = 8192;

/// The size of the syscall handler thread pool.
///
/// Note, the pool is self-growing/shrinking, and this constant defines
/// the number of core threads that are always alive and do not get
/// reaped-off even if they're idle.
pub static EMU_POOL_SIZE: Lazy<u16> =
    Lazy::new(|| u16::try_from(num_cpus::get()).unwrap_or(u16::MAX));

/// Specify the duration in milliseconds for which additional threads
/// outside the core pool remain alive while not receiving any work
/// before giving up and terminating.
/// Defaults to 15 seconds.
pub const EMU_KEEP_ALIVE: u16 = 15000;

/// Specify the cycle period of the monitor thread.
/// Defaults to 10 milliseconds.
pub const MON_CYCLE_TIME: Duration = Duration::from_millis(10);

/// Specify the graceful wait time for the monitor thread.
/// Defaults to 3 seconds.
pub const MON_GRACE_TIME: Duration = Duration::from_secs(3);

/// Stack size for the syscall handler threads.
/// Defaults to 296k.
pub const EMU_STACK_SIZE: usize = 296 * 1024;

/// Stack size for the syscall monitor thread.
/// Defaults to 32k.
pub const MON_STACK_SIZE: usize = 32 * 1024;

/// Stack size for the short-lived micro-threads Syd spawns during
/// system call emulation.
/// Defaults to 8k.
pub const MINI_STACK_SIZE: usize = 8 * 1024;

/// Stack size for the initial _clone_(2) to spawn the sandbox process.
/// Defaults to 2M.
pub const CHLD_STACK_SIZE: usize = 2 * 1024 * 1024;

// SegvGuard Defaults

/// SegvGuard entry expiry timeout.
pub const SEGVGUARD_EXPIRY: Duration = Duration::from_secs(2 * 60);
/// SegvGuard entry suspension timeout.
pub const SEGVGUARD_SUSPENSION: Duration = Duration::from_secs(10 * 60);
/// SegvGuard max number of crashes before expiry.
pub const SEGVGUARD_MAXCRASHES: u8 = 5;

// Sandbox Restrictions

/// List of allowlisted prctl requests.
pub const ALLOWLIST_PRCTL: &[KeyValue] = &[
    ("PR_SET_PDEATHSIG", 1),
    ("PR_GET_PDEATHSIG", 2),
    ("PR_GET_DUMPABLE", 3),
    ("PR_SET_DUMPABLE", 4),
    ("PR_GET_ALIGN", 5),
    ("PR_GET_SETALIGN", 6),
    ("PR_GET_KEEPCAPS", 7),
    ("PR_SET_KEEPCAPS", 8),
    ("PR_GET_FPEMU", 9),
    ("PR_SET_FPEMU", 10),
    ("PR_GET_FPEXC", 11),
    ("PR_SET_FPEXC", 12),
    ("PR_GET_TIMING", 13),
    ("PR_SET_TIMING", 14),
    ("PR_SET_NAME", 15),
    ("PR_GET_NAME", 16),
    ("PR_GET_ENDIAN", 19),
    ("PR_SET_ENDIAN", 20),
    ("PR_GET_SECCOMP", 21),
    ("PR_SET_SECCOMP", 22),
    ("PR_CAPBSET_READ", 23),
    ("PR_CAPBSET_DROP", 24),
    ("PR_GET_TSC", 25),
    ("PR_SET_TSC", 26),
    ("PR_GET_SECUREBITS", 27),
    ("PR_SET_SECUREBITS", 28),
    ("PR_SET_TIMERSLACK", 29),
    ("PR_GET_TIMERSLACK", 30),
    // SAFETY: no perf! PR_TASK_PERF_EVENTS_DISABLE
    // SAFETY: no perf! PR_TASK_PERF_EVENTS_ENABLE
    ("PR_MCE_KILL", 33),
    ("PR_MCE_KILL_GET", 34),
    // SAFETY: no self modifying executables! PR_SET_MM
    // SAFETY: no ptrace! PR_SET_PTRACER
    ("PR_SET_CHILD_SUBREAPER", 36),
    ("PR_GET_CHILD_SUBREAPER", 37),
    ("PR_SET_NO_NEW_PRIVS", 38),
    ("PR_GET_NO_NEW_PRIVS", 39),
    ("PR_GET_TID_ADDRESS", 40),
    ("PR_SET_THP_DISABLE", 41),
    ("PR_GET_THP_DISABLE", 42),
    // SAFETY: unimplemented! PR_MPX_ENABLE_MANAGEMENT
    // SAFETY: unimplemented! PR_MPX_DISABLE_MANAGEMENT
    ("PR_SET_FP_MODE", 45),
    ("PR_GET_FP_MODE", 46),
    ("PR_CAP_AMBIENT", 47),
    ("PR_SVE_SET_VL", 50),
    ("PR_SVE_GET_VL", 51),
    // SAFETY: do not access speculation misfeature! PR_GET_SPECULATION_CTRL
    // SAFETY: do not change speculation misfeature! PR_SET_SPECULATION_CTRL
    ("PR_PAC_RESET_KEYS", 54),
    ("PR_SET_TAGGED_ADDR_CTRL", 55),
    ("PR_GET_TAGGED_ADDR_CTRL", 56),
    ("PR_SET_IO_FLUSHER", 57),
    ("PR_GET_IO_FLUSHER", 58),
    ("PR_SET_SYSCALL_USER_DISPATCH", 59),
    ("PR_PAC_SET_ENABLED_KEYS", 60),
    ("PR_PAC_GET_ENABLED_KEYS", 61),
    ("PR_SCHED_CORE", 62),
    ("PR_SET_MDWE", 65),
    ("PR_GET_MDWE", 66),
    ("PR_SET_VMA", 0x53564d41),
];

/// The list of Linux capabilities(7) to drop on startup.
pub const CAPS_DROP: &[Capability] = &[
    Capability::CAP_AUDIT_CONTROL,
    Capability::CAP_AUDIT_READ,
    Capability::CAP_AUDIT_WRITE,
    Capability::CAP_BLOCK_SUSPEND,
    Capability::CAP_BPF,
    Capability::CAP_CHECKPOINT_RESTORE,
    Capability::CAP_CHOWN,
    Capability::CAP_DAC_OVERRIDE,
    Capability::CAP_DAC_READ_SEARCH,
    Capability::CAP_FSETID,
    Capability::CAP_FOWNER,
    Capability::CAP_IPC_LOCK,
    Capability::CAP_IPC_OWNER,
    Capability::CAP_KILL,
    Capability::CAP_LEASE,
    Capability::CAP_LINUX_IMMUTABLE,
    Capability::CAP_MAC_ADMIN,
    Capability::CAP_MAC_OVERRIDE,
    Capability::CAP_MKNOD,
    Capability::CAP_NET_ADMIN,
    Capability::CAP_NET_BROADCAST,
    Capability::CAP_NET_RAW,
    Capability::CAP_PERFMON,
    Capability::CAP_SETGID,
    Capability::CAP_SETUID,
    Capability::CAP_SETFCAP,
    Capability::CAP_SETPCAP,
    Capability::CAP_NET_BIND_SERVICE,
    Capability::CAP_SYSLOG,
    Capability::CAP_SYS_ADMIN,
    Capability::CAP_SYS_BOOT,
    Capability::CAP_SYS_CHROOT,
    Capability::CAP_SYS_MODULE,
    Capability::CAP_SYS_NICE,
    Capability::CAP_SYS_PACCT,
    Capability::CAP_SYS_PTRACE,
    Capability::CAP_SYS_RAWIO,
    Capability::CAP_SYS_RESOURCE,
    Capability::CAP_SYS_TIME,
    Capability::CAP_SYS_TTY_CONFIG,
    Capability::CAP_WAKE_ALARM,
];

/// Equivalent to the list of environment variables that gl*bc removes for SUID programs.
pub const UNSAFE_ENV: &[&[u8]] = &[
    b"GCONV_PATH",
    b"GETCONF_DIR",
    b"GLIBC_TUNABLES",
    b"HOSTALIASES",
    b"LD_AOUT_LIBRARY_PATH",
    b"LD_AOUT_PRELOAD",
    b"LD_AUDIT",
    b"LD_BIND_NOT",
    b"LD_DEBUG",
    b"LD_DEBUG",
    b"LD_DEBUG_OUTPUT",
    b"LD_DYNAMIC_WEAK",
    b"LD_DYNAMIC_WEAK",
    b"LD_ELF_HINTS_PATH",
    b"LD_HWCAP_MASK",
    b"LD_LIBMAP",
    b"LD_LIBMAP_DISABLE",
    b"LD_LIBRARY_PATH",
    b"LD_LIBRARY_PATH_FDS",
    b"LD_LIBRARY_PATH_RPATH",
    b"LD_LOADFLTR",
    b"LD_ORIGIN_PATH",
    b"LD_PREFER_MAP_32BIT_EXEC",
    b"LD_PRELOAD",
    b"LD_PRELOAD_FDS",
    b"LD_PROFILE",
    b"LD_SHOW_AUXV",
    b"LD_USE_LOAD_BIAS",
    b"LOCALDOMAIN",
    b"LOCPATH",
    b"MALLOC_TRACE",
    b"NIS_PATH",
    b"NLSPATH",
    b"RESOLV_HOST_CONF",
    b"RES_OPTIONS",
    b"TMPDIR",
    b"TZDIR",
];

// Sandboxing profiles

/// Off sandboxing profile.
/// Used as shorthand to turn all sandboxing off.
pub const PROFILE_OFF: &[&str] = &["sandbox/read,stat,write,exec,ioctl,net,force,tpe,mem,pid:off"];

/// Libsyd helper sandboxing profile.
/// Turns all sandboxing off and set sandbox lock to Exec.
/// Useful to configure syd in the application via libsyd.
pub const PROFILE_LIB: &[&str] = &["include_profile off", "lock:exec"];

/// Silent sandboxing profile.
pub const PROFILE_SILENT: &[&str] = &[
    "default/mem:filter",
    "default/pid:filter",
    "default/tpe:filter",
    "default/force:filter",
    "default/segvguard:filter",
    "filter/read,stat,exec,ioctl,write+/***",
    "filter/net/bind+/***",
    "filter/net/bind+any!0-65535",
    "filter/net/connect+/***",
    "filter/net/connect+any!0-65535",
];

/// Trace sandboxing profile.
pub const PROFILE_TRACE: &[&str] = &[
    "sandbox/tpe,mem,pid:off",
    "sandbox/read,stat,write,exec,ioctl,net,force:on",
    "default/read,stat,write,exec,ioctl,net,force:warn",
];

/// No ipv4 sandboxing profile.
pub const PROFILE_NOIPV4: &[&str] = &[
    "sandbox/net:on",
    "allow/net/connect+any6!0-65535",
    "deny/net/connect+any4!0-65535",
];

/// No ipv6 sandboxing profile.
pub const PROFILE_NOIPV6: &[&str] = &[
    "sandbox/net:on",
    "allow/net/connect+any4!0-65535",
    "deny/net/connect+any6!0-65535",
];

/// Privileged sandboxing profile.
pub const PROFILE_PRIVILEGED: &[&str] = &["trace/allow_unsafe_caps:1"];

/// No core dump restrictions profile.
pub const PROFILE_CORE: &[&str] = &["trace/allow_unsafe_prlimit:1"];

/// Debug sandboxing profile.
pub const PROFILE_DEBUG: &[&str] = &["trace/allow_unsafe_debug:1"];

/// No exec(3) restrictions sandboxing profile.
pub const PROFILE_NOEXE: &[&str] = &["trace/allow_unsafe_exec:1"];

/// No memory restrictions sandboxing profile.
pub const PROFILE_NOMEM: &[&str] = &["trace/allow_unsafe_memory:1"];

/// No PIE sandboxing profile.
pub const PROFILE_NOPIE: &[&str] = &["trace/allow_unsafe_nopie:1"];

/// Container sandboxing profile, activated with:
/// `syd --profile container`
pub const PROFILE_CONTAINER: &[&str] = &[
    "unshare/user,mount,uts,ipc,pid,net,cgroup,time:1",
    "deny/read,stat,write+/proc/1/**",
    "allow/read,stat+/proc/1/comm",
];

/// Immutable container sandboxing profile, activated with:
/// `syd --profile immutable`
pub const PROFILE_IMMUTABLE: &[&str] = &[
    "unshare/user,mount,uts,ipc,pid,net,cgroup,time:1",
    "bind+tmpfs:/dev/shm:nodev,nosuid,noexec,mode=1777",
    "bind+tmpfs:/tmp:nodev,nosuid,mode=1777",
    "bind+/etc:/etc:ro,nodev,noexec,nosuid",
    "bind+/home:/home:ro,nodev,noexec,nosuid",
    "bind+/media:/media:ro,nodev,noexec,nosuid",
    "bind+/mnt:/mnt:ro,nodev,noexec,nosuid",
    "bind+/opt:/opt:ro,nodev,nosuid",
    "bind+/srv:/srv:ro,nodev,noexec,nosuid",
    "bind+/usr:/usr:ro,nodev",
    "bind+/etc/shells:/proc/kcore:ro,nodev,noexec,nosuid",
    "bind+/etc/shells:/proc/keys:ro,nodev,noexec,nosuid",
    "bind+/etc/shells:/proc/latency_stats:ro,nodev,noexec,nosuid",
    "bind+/etc/shells:/proc/sysrq-trigger:ro,nodev,noexec,nosuid",
    "bind+/etc/shells:/proc/timer_list:ro,nodev,noexec,nosuid",
    "bind+/etc/shells:/proc/timer_stats:ro,nodev,noexec,nosuid",
    "bind+/var/empty:/proc/acpi:ro,nodev,noexec,nosuid",
    "bind+/var/empty:/proc/asound:ro,nodev,noexec,nosuid",
    "bind+/var/empty:/proc/bus:ro,nodev,noexec,nosuid",
    "bind+/var/empty:/proc/driver:ro,nodev,noexec,nosuid",
    "bind+/var/empty:/proc/dynamic_debug:ro,nodev,noexec,nosuid",
    "bind+/var/empty:/proc/fs:ro,nodev,noexec,nosuid",
    "bind+/var/empty:/proc/irq:ro,nodev,noexec,nosuid",
    "bind+/var/empty:/proc/pressure:ro,nodev,noexec,nosuid",
    "bind+/var/empty:/proc/scsi:ro,nodev,noexec,nosuid",
    "bind+/var/empty:/proc/sys/debug:ro,nodev,noexec,nosuid",
    "bind+/var/empty:/proc/sys/dev:ro,nodev,noexec,nosuid",
    "bind+/proc/sys/fs:/proc/sys/fs:ro,nodev,noexec,nosuid",
    "bind+/proc/sys/kernel:/proc/sys/kernel:ro,nodev,noexec,nosuid",
    "bind+/proc/sys/vm:/proc/sys/vm:ro,nodev,noexec,nosuid",
    "bind+/var/empty:/proc/sysvipc:ro,nodev,noexec,nosuid",
    "bind+/var/empty:/proc/tty:ro,nodev,noexec,nosuid",
    "bind+/var/empty:/sys/dev/block:ro,nodev,noexec,nosuid",
    "bind+/var/empty:/sys/devices/virtual/powercap:ro,nodev,noexec,nosuid",
    "bind+/var/empty:/sys/firmware:ro,nodev,noexec,nosuid",
    "bind+/var/empty:/sys/fs/bpf:ro,nodev,noexec,nosuid",
    "bind+/var/empty:/sys/fs/ext4:ro,nodev,noexec,nosuid",
    "bind+/var/empty:/sys/fs/fuse:ro,nodev,noexec,nosuid",
    "bind+/var/empty:/sys/fs/pstore:ro,nodev,noexec,nosuid",
    "bind+/var/empty:/sys/fs/selinux:ro,nodev,noexec,nosuid",
    "bind+/var/empty:/sys/fs/smackfs:ro,nodev,noexec,nosuid",
    "deny/read,stat,write+/proc/1/**",
    "allow/read,stat+/proc/1/comm",
];

/// Landlock sandboxing profile, activated with:
/// `syd --profile landlock`.
pub const PROFILE_LANDLOCK: &[&str] = &[
    "sandbox/lock:on",
    "allow/lock/read+/bin",
    "allow/lock/read+/dev",
    "allow/lock/read+/etc",
    "allow/lock/read+/lib",
    "allow/lock/read+/opt",
    "allow/lock/read+/proc",
    "allow/lock/read+/run",
    "allow/lock/read+/sbin",
    "allow/lock/read+/snap",
    "allow/lock/read+/sys",
    "allow/lock/read+/usr",
    "allow/lock/read+/var",
    "allow/lock/write+/dev/console",
    "allow/lock/write+/dev/fd",
    "allow/lock/write+/dev/full",
    "allow/lock/write+/dev/null",
    "allow/lock/write+/dev/ptmx",
    "allow/lock/write+/dev/pts",
    "allow/lock/write+/dev/shm",
    "allow/lock/write+/dev/tts",
    "allow/lock/write+/dev/tty",
    "allow/lock/write+/dev/zero",
    "allow/lock/write+/selinux/context",
    "allow/lock/write+/tmp",
];

/// Common Linux system profile, used by oci, paludis and user profiles.
pub const PROFILE_LINUX: &[&str] = &[
    // Safe defaults for Ioctl sandboxing.
    r"allow/ioctl+/proc/[0-9]*/fd/pipe:\[[0-9]*\]",
    r"allow/ioctl+/proc/[0-9]*/fd/socket:\[[0-9]*\]",
    "allow/ioctl+/dev/full",
    "allow/ioctl+/dev/null",
    "allow/ioctl+/dev/zero",
    // Allow read,write,stat for memfds but not exec.
    "allow/read,write,stat+/memfd:*",
    // Safe defaults for Read & Stat sandboxing.
    "allow/read,stat+/",
    "allow/read,stat+/bin/***",
    "allow/read,stat+/etc/***",
    "allow/read,stat+/lib*/***",
    "allow/read,stat+/opt/***",
    "allow/read,stat+/proc/***",
    "allow/read,stat+/sbin/***",
    "allow/read,stat+/tmp/***",
    "allow/read,stat+/usr/***",
    "allow/read,stat+/var/***",
    "allow/read,stat+/dev",
    "allow/read,stat+/proc",
    "allow/read,stat+/run",
    "allow/read,stat+/sys",
    "deny/read,stat+/etc/crypttab",
    "deny/read,stat+/etc/gshadow*",
    "deny/read,stat+/etc/shadow*",
    "deny/read,stat+/var/log/***",
    "allow/read,stat+/dev/console",
    "allow/read,stat+/dev/full",
    "allow/read,stat+/dev/null",
    "allow/read,stat+/dev/ptmx",
    "allow/read,stat+/dev/pty*",
    "allow/read,stat+/dev/stderr",
    "allow/read,stat+/dev/stdout",
    "allow/read,stat+/dev/stdin",
    "allow/read,stat+/dev/tts",
    "allow/read,stat+/dev/tty*",
    "allow/read,stat+/dev/random",
    "allow/read,stat+/dev/urandom",
    "allow/read,stat+/dev/zero",
    "allow/read,stat+/dev/fd/***",
    "allow/read,stat+/dev/pts/***",
    "allow/read,stat+/dev/shm/***",
    "allow/read,stat+/proc/[0-9]*",
    "allow/read,stat+/proc/[0-9]*/attr/***",
    "allow/read,stat+/proc/[0-9]*/cgroup",
    "allow/read,stat+/proc/[0-9]*/cmdline",
    "allow/read,stat+/proc/[0-9]*/comm",
    "allow/read,stat+/proc/[0-9]*/coredump_filter",
    "allow/read,stat+/proc/[0-9]*/cpuset",
    "allow/read,stat+/proc/[0-9]*/cwd",
    "allow/read,stat+/proc/[0-9]*/exe",
    "allow/read,stat+/proc/[0-9]*/io",
    "allow/read,stat+/proc/[0-9]*/limits",
    "allow/read,stat+/proc/[0-9]*/loginuid",
    "allow/read,stat+/proc/[0-9]*/mountinfo",
    "allow/read,stat+/proc/[0-9]*/oom_*",
    "allow/read,stat+/proc/[0-9]*/root",
    "allow/read,stat+/proc/[0-9]*/sched",
    "allow/read,stat+/proc/[0-9]*/schedstat",
    "allow/read,stat+/proc/[0-9]*/seccomp",
    "allow/read,stat+/proc/[0-9]*/sessionid",
    "allow/read,stat+/proc/[0-9]*/setgroups",
    "allow/read,stat+/proc/[0-9]*/stat",
    "allow/read,stat+/proc/[0-9]*/statm",
    "allow/read,stat+/proc/[0-9]*/status",
    "allow/read,stat+/proc/[0-9]*/time*",
    "allow/read,stat+/proc/[0-9]*/[ug]id_map",
    "allow/read,stat+/proc/[0-9]*/fd/***",
    "allow/read,stat+/proc/[0-9]*/fdinfo/***",
    "allow/read,stat+/proc/[0-9]*/map_files/***",
    "allow/read,stat+/proc/[0-9]*/mounts/***",
    "allow/read,stat+/proc/[0-9]*/net/***",
    "allow/read,stat+/proc/[0-9]*/ns/***",
    "allow/read,stat+/proc/[0-9]*/task/***",
    "allow/read,stat+/proc/self",
    "allow/read,stat+/proc/thread-self",
    "allow/read,stat+/proc/cgroups",
    "allow/read,stat+/proc/cmdline",
    "allow/read,stat+/proc/consoles",
    "allow/read,stat+/proc/cpuinfo",
    "allow/read,stat+/proc/devices",
    "allow/read,stat+/proc/diskstats",
    "allow/read,stat+/proc/execdomains",
    "allow/read,stat+/proc/fb",
    "allow/read,stat+/proc/filesystems",
    "allow/read,stat+/proc/interrupts",
    "allow/read,stat+/proc/kmsg",
    "allow/read,stat+/proc/loadavg",
    "allow/read,stat+/proc/meminfo",
    "allow/read,stat+/proc/stat",
    "allow/read,stat+/proc/uptime",
    "allow/read,stat+/proc/version",
    "allow/read,stat+/proc/mounts/***",
    "allow/read,stat+/proc/net/***",
    "allow/read,stat+/proc/sys",
    "allow/read,stat+/proc/sys/fs/***",
    "allow/read,stat+/proc/sys/kernel/***",
    "allow/read,stat+/proc/sys/vm/***",
    "allow/read,stat+/sys/bus",
    "allow/read,stat+/sys/bus/cpu/***",
    "allow/read,stat+/sys/bus/event_source/***",
    "allow/read,stat+/sys/class",
    "allow/read,stat+/sys/class/i2c-adapter",
    "allow/read,stat+/sys/class/power_supply/***",
    "allow/read,stat+/sys/devices",
    "allow/read,stat+/sys/devices/system",
    "allow/read,stat+/sys/devices/system/cpu",
    "allow/read,stat+/sys/devices/system/cpu/isolated",
    "allow/read,stat+/sys/devices/system/cpu/kernel_max",
    "allow/read,stat+/sys/devices/system/cpu/online",
    "allow/read,stat+/sys/devices/system/cpu/offline",
    "allow/read,stat+/sys/devices/system/cpu/possible",
    "allow/read,stat+/sys/devices/system/cpu/present",
    "allow/read,stat+/sys/devices/system/node/***",
    "allow/read,stat+/sys/fs",
    "allow/read,stat+/sys/fs/cgroup/***",
    "allow/read,stat+/sys/kernel",
    "allow/read,stat+/sys/kernel/mm",
    "allow/read,stat+/sys/kernel/security",
    "allow/read,stat+/sys/kernel/mm/transparent_hugepage/***",
    "allow/read,stat+/sys/kernel/security/apparmor/***",
    "allow/read,stat+/run/systemd",
    "allow/read,stat+/run/systemd/resolve",
    "allow/read,stat+/run/systemd/resolve/*.conf",
    // Safe defaults for Write sandboxing.
    "allow/write+/dev/console",
    "allow/write+/dev/full",
    "allow/write+/dev/null",
    "allow/write+/dev/ptmx",
    "allow/write+/dev/pty*",
    "allow/write+/dev/stderr",
    "allow/write+/dev/stdout",
    "allow/write+/dev/stdin",
    "allow/write+/dev/tts",
    "allow/write+/dev/tty*",
    "allow/write+/dev/zero",
    "allow/write+/dev/fd/**",
    "allow/write+/dev/pts/**",
    "allow/write+/dev/shm/**",
    "allow/write+/proc/[0-9]*/attr/***",
    "allow/write+/proc/[0-9]*/fd/***",
    "allow/write+/proc/[0-9]*/task/***",
    "allow/write+/proc/[0-9]*/oom_score_adj",
    "allow/write+/selinux/context/**",
    "allow/write+/tmp/**",
    "allow/write+/var/cache/**",
    "allow/write+/var/tmp/**",
    // Safe defaults for Network sandboxing.
    "allow/net/connect+/run/nscd/socket",
    "allow/net/connect+/var/lib/sss/pipes/nss",
    "allow/net/connect+/var/run/nscd/socket",
    // allow NETLINK_ROUTE.
    "allow/net/link+route",
    // allow getaddrinfo() with AI_ADDRCONFIG on musl systems.
    "allow/net/connect+loopback!65535",
];

/// Profile to allowlist TTY ioctls without path check, used by oci,
/// paludis and user profiles.
pub const PROFILE_TTY: &[&str] = &[
    "allow/read,stat,write,ioctl+/dev/ptmx",
    "allow/read,stat,write,ioctl+/dev/pts/ptmx",
    "allow/read,stat,write,ioctl+/dev/pts/[0-9]*",
    // PTY handling
    "ioctl/allow+0x5410",     // TIOCSPGRP
    "ioctl/allow+0x5432",     // TCGETX
    "ioctl/allow+0x5433",     // TCSETX
    "ioctl/allow+0x5434",     // TCSETXF
    "ioctl/allow+0x5435",     // TCSETXW
    "ioctl/allow+0x5456",     // TIOCGLCKTRMIOS
    "ioctl/allow+0x5457",     // TIOCSLCKTRMIOS
    "ioctl/allow+0x5413",     // TIOCGWINSZ
    "ioctl/allow+0x5414",     // TIOCSWINSZ
    "ioctl/allow+0x80045432", // TIOCGDEV
    "ioctl/allow+0x80045440", // TIOCGEXCL
    "ioctl/allow+0x80045438", // TIOCGPKT
    "ioctl/allow+0x80045439", // TIOCGPTLCK
    "ioctl/allow+0x80045430", // TIOCGPTN
    "ioctl/allow+0x5441",     // TIOCGPTPEER
    "ioctl/allow+0x540e",     // TIOCSCTTY
    "ioctl/allow+0x40045436", // TIOCSIG
    "ioctl/allow+0x5437",     // TIOCVHANGUP
    // Pseudoterminal ioctls
    "ioctl/allow+0x80045438", // TIOCGPKT
    "ioctl/allow+0x80045439", // TIOCGPTLCK
    "ioctl/allow+0x5441",     // TIOCGPTPEER
    "ioctl/allow+0x5420",     // TIOCPKT
    "ioctl/allow+0x40045431", // TIOCSPTLCK
];

/// Profile to allowlist KVM ioctls without path check.
/// Read: https://www.kernel.org/doc/Documentation/virtual/kvm/api.txt
pub const PROFILE_KVM: &[&str] = &[
    "allow/read,stat,write,ioctl+/dev/kvm",
    "include_profile kvm_native",
    "ioctl/allow+0x0000ae00", // KVM_GET_API_VERSION
    "ioctl/allow+0xae01",     // KVM_CREATE_VM
    "ioctl/allow+0xae04",     // KVM_GET_VCPU_MMAP_SIZE
    "ioctl/allow+0xae41",     // KVM_CREATE_VCPU
    "ioctl/allow+0x4010ae42", // KVM_GET_DIRTY_LOG
    "ioctl/allow+0xae47",     // KVM_SET_TSS_ADDR
    "ioctl/allow+0xae80",     // KVM_RUN
    "ioctl/allow+0xae9a",     // KVM_NMI
    "ioctl/allow+0xae03",     // KVM_CHECK_EXTENSION
    "ioctl/allow+0xaea3",     // KVM_GET_TSC_KHZ
    "ioctl/allow+0xaea2",     // KVM_SET_TSC_KHZ
    "ioctl/allow+0x4004ae86", // KVM_INTERRUPT
    "ioctl/allow+0x4008ae89", // KVM_SET_MSRS
    "ioctl/allow+0x4020ae46", // KVM_SET_USER_MEMORY_REGION
    "ioctl/allow+0x4090ae82", // KVM_SET_REGS
    "ioctl/allow+0x4138ae84", // KVM_SET_SREGS
    "ioctl/allow+0xc008ae88", // KVM_GET_MSRS
    "ioctl/allow+0x8090ae81", // KVM_GET_REGS
    "ioctl/allow+0x8138ae83", // KVM_GET_SREGS
    "ioctl/allow+0xc008ae05", // KVM_GET_SUPPORTED_CPUID
    "ioctl/allow+0xc008ae09", // KVM_GET_EMULATED_CPUID
    "ioctl/allow+0x4008ae90", // KVM_SET_CPUID2
    "ioctl/allow+0x4004ae8b", // KVM_SET_SIGNAL_MASK
    "ioctl/allow+0x8040ae9f", // KVM_GET_VCPU_EVENTS
    "ioctl/allow+0x4040aea0", // KVM_SET_VCPU_EVENTS
    "ioctl/allow+0x4018aee1", // KVM_SET_DEVICE_ATTR
    "ioctl/allow+0x4008ae48", // KVM_SET_IDENTITY_MAP_ADDR
    "ioctl/allow+0x0000ae60", // KVM_CREATE_IRQCHIP
    "ioctl/allow+0x4008ae61", // KVM_IRQ_LINE
    "ioctl/allow+0x4010ae67", // KVM_REGISTER_COALESCED_MMIO
    "ioctl/allow+0x4010ae68", // KVM_UNREGISTER_COALESCED_MMIO
    "ioctl/allow+0x4030ae6a", // KVM_SET_GSI_ROUTING
    "ioctl/allow+0x4020ae76", // KVM_IRQFD
    "ioctl/allow+0x4040ae79", // KVM_IOEVENTFD
    "ioctl/allow+0x8004ae98", // KVM_GET_MP_STATE
    "ioctl/allow+0x4004ae99", // KVM_SET_MP_STATE
    "ioctl/allow+0x4200aea5", // KVM_SIGNAL_MSI
    "ioctl/allow+0x404ae09b", // KVM_SET_GUEST_DEBUG
    "ioctl/allow+0xc00caee0", // KVM_CREATE_DEVICE
    "ioctl/allow+0x4018aee1", // KVM_SET_DEVICE_ATTR
    "ioctl/allow+0x8018aee2", // KVM_GET_DEVICE_ATTR
    "ioctl/allow+0x4018aee3", // KVM_HAS_DEVICE_ATTR
];

/// Profile to allowlist KVM arch-native ioctls without path check.
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
pub const PROFILE_KVM_NATIVE: &[&str] = &[
    "ioctl/allow+0x4680aea3",         // _KVM_ENABLE_CAP
    "ioctl/allow+0x4010aeab",         // _KVM_GET_ONE_REG
    "ioctl/allow+0x4010aeac",         // _KVM_SET_ONE_REG
    "ioctl/allow+0xc008aeb0",         // _KVM_GET_REG_LIST
    "ioctl/allow+5",                  // _KVM_ARM_TARGET_GENERIC_V8
    "ioctl/allow+0x8020aeaf",         // _KVM_ARM_PREFERRED_TARGET
    "ioctl/allow+0x4020aeae",         // _KVM_ARM_VCPU_INIT
    "ioctl/allow+0x4040aec2",         // _KVM_ARM_VCPU_FINALIZE
    "ioctl/allow+0x6030000000100042", // _KVM_ARM64_REGS_PSTATE
    "ioctl/allow+0x6030000000100044", // _KVM_ARM64_REGS_SP_EL1
    "ioctl/allow+0x6030000000100000", // _KVM_ARM64_REGS_R0
    "ioctl/allow+0x6030000000100002", // _KVM_ARM64_REGS_R1
    "ioctl/allow+0x6030000000100004", // _KVM_ARM64_REGS_R2
    "ioctl/allow+0x6030000000100006", // _KVM_ARM64_REGS_R3
    "ioctl/allow+0x6030000000100010", // _KVM_ARM64_REGS_R8
    "ioctl/allow+0x6030000000100024", // _KVM_ARM64_REGS_R18
    "ioctl/allow+0x6030000000100040", // _KVM_ARM64_REGS_PC
    "ioctl/allow+0x603000000013c510", // _KVM_ARM64_REGS_MAIR_EL1
    "ioctl/allow+0x603000000013c102", // _KVM_ARM64_REGS_TCR_EL1
    "ioctl/allow+0x603000000013c100", // _KVM_ARM64_REGS_TTBR0_EL1
    "ioctl/allow+0x603000000013c101", // _KVM_ARM64_REGS_TTBR1_EL1
    "ioctl/allow+0x603000000013c080", // _KVM_ARM64_REGS_SCTLR_EL1
    "ioctl/allow+0x603000000013c082", // _KVM_ARM64_REGS_CPACR_EL1
    "ioctl/allow+0x603000000013c600", // _KVM_ARM64_REGS_VBAR_EL1
    "ioctl/allow+0x603000000013df1a", // _KVM_ARM64_REGS_TIMER_CNT
    "ioctl/allow+0x603000000013df00", // _KVM_ARM64_REGS_CNTFRQ_EL0
    "ioctl/allow+0x6030000000138012", // _KVM_ARM64_REGS_MDSCR_EL1
    "ioctl/allow+0x603000000013c708", // _KVM_ARM64_REGS_CNTKCTL_EL1
    "ioctl/allow+0x603000000013c684", // _KVM_ARM64_REGS_TPIDR_EL1
];

/// Profile to allowlist KVM arch-native ioctls without path check.
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
pub const PROFILE_KVM_NATIVE: &[&str] = &[
    "ioctl/allow+0x0",        // _KVM_VCPU_TSC_CTRL
    "ioctl/allow+0x0",        // _KVM_VCPU_TSC_OFFSET
    "ioctl/allow+0xc004ae02", // _KVM_GET_MSR_INDEX_LIST
    "ioctl/allow+0xc004ae0a", // _KVM_GET_MSR_FEATURE_INDEX_LIST
    "ioctl/allow+0x4040ae77", // _KVM_CREATE_PIT2
    "ioctl/allow+0xc208ae62", // _KVM_GET_IRQCHIP
    "ioctl/allow+0x4208ae63", // _KVM_SET_IRQCHIP
    "ioctl/allow+0x4030ae7b", // _KVM_SET_CLOCK
    "ioctl/allow+0x8030ae7c", // _KVM_GET_CLOCK
    "ioctl/allow+0x8070ae9f", // _KVM_GET_PIT2
    "ioctl/allow+0x4070aea0", // _KVM_SET_PIT2
    "ioctl/allow+0xc008aeba", // _KVM_MEMORY_ENCRYPT_OP
    "ioctl/allow+0x8010aebb", // _KVM_MEMORY_ENCRYPT_REG_REGION
    "ioctl/allow+0x8010aebc", // _KVM_MEMORY_ENCRYPT_UNREG_REGION
    "ioctl/allow+0xc018ae85", // _KVM_TRANSLATE
    "ioctl/allow+0x81a0ae8c", // _KVM_GET_FPU
    "ioctl/allow+0x41a0ae8d", // _KVM_SET_FPU
    "ioctl/allow+0x8400ae8e", // _KVM_GET_LAPIC
    "ioctl/allow+0x4400ae8f", // _KVM_SET_LAPIC
    "ioctl/allow+0x4008ae90", // _KVM_SET_CPUID2
    "ioctl/allow+0xc008ae91", // _KVM_GET_CPUID2
    "ioctl/allow+0x8080aea1", // _KVM_GET_DEBUGREGS
    "ioctl/allow+0x4080aea2", // _KVM_SET_DEBUGREGS
    "ioctl/allow+0x9000aea4", // _KVM_GET_XSAVE
    "ioctl/allow+0x5000aea5", // _KVM_SET_XSAVE
    "ioctl/allow+0x8188aea6", // _KVM_GET_XCRS
    "ioctl/allow+0x4188aea7", // _KVM_SET_XCRS
    "ioctl/allow+0xaead",     // _KVM_KVMCLOCK_CTRL
];

/// Profile to allowlist KVM arch-native ioctls without path check.
#[cfg(not(any(
    target_arch = "arm",
    target_arch = "x86",
    target_arch = "x86_64",
    target_arch = "aarch64"
)))]
pub const PROFILE_KVM_NATIVE: &[&str] = &[];

/// OCI default sandboxing profile
/// Use `syd -p oci`
pub const PROFILE_OCI: &[&str] = &[
    "include_profile linux",
    "include_profile tty",
    // Safe defaults for Exec sandboxing
    "allow/exec+/bin/**",
    "allow/exec+/lib*/**",
    "allow/exec+/sbin/**",
    "allow/exec+/snap/**",
    "allow/exec+/usr/**/bin/**",
    "allow/exec+/usr/**/lib*/**",
    "allow/exec+/usr/**/sbin/**",
    "allow/exec+/usr/games/**",
    // hide pid=1 aka syd-oci.
    "deny/read,stat,write+/proc/1/***",
    // hide /.dockerenv, /.oci.syd-3 et al.
    r"deny/read,stat,write+/.*",
];

/// Pand☮ra sandboxing profile.
pub const PROFILE_PANDORA: &[&str] = &["sandbox/read,stat,write,exec,ioctl,net:on"];

/// Paludis sandboxing profile, activated with:
/// `syd --profile paludis`.
pub const PROFILE_PALUDIS: &[&str] = &[
    "include_profile linux",
    "include_profile tty",
    "name/host:localhost", // only effective when combined with unshare/uts:1
    "lock:exec",           // esandbox
    "trace/allow_safe_bind:true",
    "trace/allow_safe_kcapi:true",
    "trace/allow_unsafe_debug:true", // implies unsafe_{exec,memory}:1
    "trace/allow_unsafe_dumpable:true", // allows strace -f syd
    "trace/allow_unsafe_env:true",
    "trace/allow_unsafe_filename:true", // sydbox#118
    "trace/allow_unsafe_nopie:true",
    "trace/allow_unsafe_stack:true",
    "trace/allow_unsafe_msgsnd:true",
    "trace/allow_unsafe_open:true",
    "trace/allow_unsafe_prlimit:true",
    "trace/allow_unsafe_socket:true",
    "trace/allow_unsupp_socket:true",
    "trace/allow_unsafe_time:true",
    // Turned on by esandbox in metadata phase.
    "sandbox/exec:off",
    // Unnecessary for package builds.
    "sandbox/tpe:off",
    // Allow dynamic libraries,
    // Paludis does not know how to handle them yet.
    "allow/exec+/lib*/**/*.so*",
    "allow/exec+/opt/**/*.so*",
    "allow/exec+/usr/**/*.so*",
    "allow/exec+/var/**/*.so*",
    // filter noisy systemd access
    "filter/net/connect+/run/systemd/userdb/io.systemd.DynamicUser",
    // Defaults for network sandboxing.
    // Note: safe_bind:1 disables the accept(2) hook!
    "allow/net/bind+loopback!0",
    "allow/net/bind+loopback!1024-65535",
];

/// User sandboxing profile, activated with:
/// `syd --profile user`.
pub const PROFILE_USER: &[&str] = &[
    "include_profile landlock",
    "include_profile linux",
    "include_profile tty",
    // Allow read access to /home.
    // Write access will be dynamically configured.
    "allow/read,stat+/home",
    // Safe defaults for Exec sandboxing
    "allow/exec+/bin/**",
    "allow/exec+/lib*/**",
    "allow/exec+/sbin/**",
    "allow/exec+/snap/**",
    "allow/exec+/usr/**/bin/**",
    "allow/exec+/usr/**/lib*/**",
    "allow/exec+/usr/**/sbin/**",
    "allow/exec+/usr/games/**",
    // Allow access to DRI and sound
    "allow/lock/write+/dev/dri",
    "allow/lock/write+/dev/input",
    "allow/lock/write+/dev/snd",
    "allow/read,stat,write+/dev/dri/**",
    "allow/read,stat,write+/dev/input/**",
    "allow/read,stat,write+/dev/snd/**",
    // Allow access to HID devices
    // FIXME: Landlock for hidraw?
    "allow/read,stat,write+/dev/hidraw[0-9]*",
    // Allow access to syslog
    "allow/net/connect+/dev/log",
    // Allow access to systemd journal
    "allow/read,stat+/var/log/journal/***",
    // Allow access to PulseAudio
    "allow/net/connect+/run/pulse/native",
    "allow/net/connect+/var/run/pulse/native",
];

/// The list of perf/debugging system calls.
pub const PERF_SYSCALLS: &[&str] = &[
    "lookup_dcookie",
    "perf_event_open",
    "rtas",
    "s390_runtime_instr",
    "sys_debug_setcontext",
];

/// The list of ptrace system calls.
pub const PTRACE_SYSCALLS: &[&str] = &["ptrace", "process_vm_readv", "process_vm_writev"];

/// The list of system calls which are of the getid family.
pub const GET_ID_SYSCALLS: &[&str] = &[
    "getuid",
    "getuid32",
    "getgid",
    "getgid32",
    "geteuid",
    "geteuid32",
    "getegid",
    "getegid32",
    "getresuid",
    "getresuid32",
    "getresgid",
    "getresgid32",
];

/// The list of system calls which are of the setid family.
pub const SET_ID_SYSCALLS: &[&str] = &[
    "setuid",
    "setuid32",
    "setgid",
    "setgid32",
    "setreuid",
    "setreuid32",
    "setregid",
    "setregid32",
    "setresuid",
    "setresuid32",
    "setresgid",
    "setresgid32",
];

/// SAFETY: We do not support diverging FsID from Effective ID.
/// SAFETY: We do not support setgroups (due to pointer deref -> TOCTOU vector)
pub const UNSAFE_ID_SYSCALLS: &[&str] = &[
    "setfsgid",
    "setfsgid32",
    "setfsuid",
    "setfsuid32",
    "setgroups",
    "setgroups32",
];

/// The list of system calls which syd has a `UNotify` callback for
pub const HOOK_SYSCALLS: &[&str] = &[
    "accept",
    "accept4",
    "bind",
    "connect",
    "getsockname",
    "sendto",
    "sendmsg",
    "sendmmsg",
    "socket",
    "execve",
    "execveat",
    "getdents",
    "getdents64",
    "stat",
    "stat64",
    "lstat",
    "statx",
    "newfstatat",
    "access",
    "faccessat",
    "faccessat2",
    "chmod",
    "fchmod",
    "fchmodat",
    "fchmodat2",
    "fchown",
    "fchown32",
    "chown",
    "lchown",
    "fchownat",
    "creat",
    "link",
    "symlink",
    "unlink",
    "linkat",
    "symlinkat",
    "unlinkat",
    "mkdir",
    "rmdir",
    "mkdirat",
    "mknod",
    "mknodat",
    "open",
    "openat",
    "openat2",
    "rename",
    "renameat",
    "renameat2",
    "utime",
    "utimes",
    "futimesat",
    "utimensat",
    "truncate",
    "truncate64",
    "ftruncate",
    "ftruncate64",
    "getxattr",
    "fgetxattr",
    "lgetxattr",
    "setxattr",
    "fsetxattr",
    "lsetxattr",
    "listxattr",
    "flistxattr",
    "llistxattr",
    "removexattr",
    "fremovexattr",
    "lremovexattr",
    "getrandom",
    "ioctl",
    "prctl",
    "kill",
    "tkill",
    "tgkill",
    "pidfd_open",
    "brk",
    "mmap",
    "mmap2",
    "mremap",
    "sync",
    "syncfs",
    "setrlimit",
    "prlimit64",
    "statfs",
    "statfs64",
    "fallocate",
    "uname",
    "fanotify_mark",
    "inotify_add_watch",
    "memfd_create",
];

/// The list of system calls which are no-ops.
///
/// SAFETY: sync, syncfs are no-ops to prevent potential local DoS.
/// SAFETY: chroot, pivot_root are no-ops for compat with old daemons,
/// that change root into empty directory once all path access is done.
pub const NOOP_SYSCALLS: &[&str] = &["chroot", "pivot_root", "sync", "syncfs"];

/// The list of system calls that are denied in syd parent seccomp filter.
/// This filter is inherited by the sandbox process.
/// These system calls must not be used by syd.
pub const DEAD_SYSCALLS: &[&str] = &[
    "_sysctl",
    "acct",
    "afs_syscall",
    // Allows direct eBPF use, unpriv use is permitted since Linux-4.4.
    // Frequent source of vulnerabilities due to churn,
    // complexity, improper validation and complexity of
    // validation.
    "bpf",
    // Hard disabled due to pointer-indirection during NS check.
    "clone3",
    "create_module",
    "delete_module",
    "finit_module",
    "fsconfig",
    "fsmount",
    "fsopen",
    "fspick",
    "get_kernel_syms",
    "init_module",
    "ioperm",
    "iopl",
    "kexec_file_load",
    "kexec_load",
    "mbind",
    "migrate_pages",
    "mincore",
    "mount_setattr",
    "move_pages",
    "name_to_handle_at",
    "nfsservctl",
    "oldlstat",
    "oldolduname",
    "oldstat",
    "olduname",
    "open_tree",
    "pciconfig_iobase",
    "pciconfig_read",
    "pciconfig_write",
    "putpmsg",
    "query_module",
    "quotactl",
    "quotactl_fd",
    "reboot",
    "request_key",
    "set_mempolicy",
    "sgetmask",
    "ssetmask",
    "stime",       // deprecated use clock_settime
    "swapcontext", // ppc
    "swapoff",
    "swapon",
    "sysfs",
    "tuxcall",
    "uselib",
    // Added in Linux-4.3
    // (Ab)used by most Project Zero Linux kernel exploits.
    "userfaultfd",
    "ustat",
    "vhangup",
    "vmsplice", // https://lore.kernel.org/linux-mm/X+PoXCizo392PBX7@redhat.com/
    "vserver",
];

/// The list of system calls which are for CPU emulation functionality.
pub const CPU_SYSCALLS: &[&str] = &[
    "modify_ldt",
    "subpage_prot",
    "switch_endian",
    "vm86",
    "vm86old",
];

/// The list of system calls which are for Kernel keyring access.
pub const KEYRING_SYSCALLS: &[&str] = &["add_key", "keyctl", "request_key"];

/// The list of system calls which are used for memory protection keys.
pub const PKEY_SYSCALLS: &[&str] = &["pkey_alloc", "pkey_free", "pkey_mprotect"];

/// The list of system calls which are part of time/clock adjustment.
pub const TIME_SYSCALLS: &[&str] = &[
    "adjtimex",
    "clock_adjtime",
    "clock_adjtime64",
    "clock_settime",
    "clock_settime64",
    "settimeofday",
    //"stime", deprecated do not use!
];

/// The list of system calls which are part of the io_uring interface.
pub const IOURING_SYSCALLS: &[&str] = &["io_uring_enter", "io_uring_register", "io_uring_setup"];

/// The list of system calls which are allowlisted without any filtering.
pub const SAFE_SYSCALLS: &[&str] = &[
    "_llseek",
    "_newselect",
    //"_sysctl",
    //"accept",
    //"accept4",
    //"acct",
    //add_key, restrictions applied, see setup_seccomp.
    //adjtimex, restrictions applied, see setup_seccomp.
    //afs_syscall
    "alarm",
    "arch_prctl", // Used during platform-specific initialization by ld-linux.so.
    "arm_fadvise64_64",
    "arm_sync_file_range",
    //"bpf",
    "breakpoint", // arm
    //"brk",
    "cachestat",  // fd-only.
    "cacheflush", // arm
    "capget",
    "capset",
    "chdir", // TODO: Hook into chdir, once kernel bug 218501 is fixed.
    //"chroot",
    //clock_adjtime, restrictions applied, see setup_seccomp.
    //clock_adjtime64, restrictions applied, see setup_seccomp.
    "clock_getres",
    "clock_getres_time64",
    "clock_gettime",
    "clock_gettime64",
    "clock_nanosleep",
    "clock_nanosleep_time64",
    //"clock_settime", restrictions applied, see setup_seccomp.
    //"clock_settime64", ditto
    // "clone", subject to fork protection
    // "clone3", subject to fork protection
    "close",
    "close_range",
    "copy_file_range",
    //create_module
    //delete_module
    "dup",
    "dup2",
    "dup3",
    "epoll_create",
    "epoll_create1",
    "epoll_ctl",
    "epoll_ctl_old",
    "epoll_pwait",
    "epoll_pwait2",
    "epoll_wait",
    "epoll_wait_old",
    "eventfd",
    "eventfd2",
    "exit",
    "exit_group",
    "fadvise64",
    "fadvise64_64",
    //"fallocate",
    "fanotify_init",
    //"fanotify_mark", device side-channel mitigations
    "fchdir", // fd-only stat call: read implies stat we dont hook.
    //"fchmod",
    //"fchown",
    //"fchown32",
    "fcntl",
    "fcntl64",
    "fdatasync",
    //finit_module
    "flock",
    //"fork", subject to fork protection
    //fsconfig
    //fsmount
    //fsopen
    //fspick
    "fstat",     // fd-only stat call: read implies stat we dont hook.
    "oldfstat",  // ditto
    "fstat64",   // ditto
    "fstatfs",   // ditto
    "fstatfs64", // ditto
    "fsync",
    //"ftruncate",
    //"ftruncate64",
    "futex",
    "futex_time64",
    "futex_waitv",
    //get_kernel_syms
    "get_mempolicy",
    "get_robust_list",
    "get_thread_area",
    "getcpu",
    "getcwd",
    //"getdents",
    //"getdents64",
    //"getegid",
    //"getegid32",
    //"geteuid",
    //"geteuid32",
    //"getgid",
    //"getgid32",
    "getgroups",
    "getgroups32",
    "getitimer",
    "getpeername",
    "getpgid",
    "getpgrp",
    "getpid",
    "getpmsg",
    "getppid",
    "getpriority",
    //"getrandom", restrictions applied, see setup_seccomp.
    "getresgid",
    "getresuid",
    "getrlimit",
    "getrusage",
    "getsid",
    "getuid",
    "getuid32",
    //"getsockname",
    "getsockopt",
    "gettid",
    "gettimeofday",
    //init_module
    //"inotify_add_watch",
    "inotify_init",
    "inotify_init1",
    "inotify_rm_watch",
    "io_cancel",
    "io_destroy",
    "io_getevents",
    "io_pgetevents",
    "io_pgetevents_time64",
    "io_setup",
    "io_submit",
    /*
     * io-uring: restrictions applied, see setup_seccomp
    "io_uring_enter",
    "io_uring_register",
    "io_uring_setup",
    */
    //"ioctl", restrictions applied, see setup_seccomp.
    //"ioperm",
    //"iopl",
    "ioprio_get",
    "ioprio_set",
    "kcmp",
    //kexec_file_load,
    //kexec_load,
    //keyctl, restrictions applied, see setup_seccomp
    //"kill", restrictions applied, see setup_seccomp
    "landlock_add_rule",
    "landlock_create_ruleset",
    "landlock_restrict_self",
    "listen",
    //"lookup_dcookie", restrictions applied, see setup_seccomp.
    "lseek",
    "madvise",
    //"mbind",
    "membarrier",
    //"memfd_create",
    //"memfd_secret",
    //"migrate_pages",
    //"mincore", NO! https://arxiv.org/pdf/1901.01161
    "mlock",
    "mlock2",
    "mlockall",
    //"mmap",
    //"mmap2",
    //"modify_ldt", restrictions applied, see setup_seccomp.
    "mount",         // restrictions applied in load_seccomp_parent.
    "mount_setattr", // ditto
    //"move_pages",
    "mprotect",
    "mq_getsetattr",
    "mq_notify",
    "mq_open",
    "mq_timedreceive",
    "mq_timedreceive_time64",
    "mq_timedsend",
    "mq_timedsend_time64",
    "mq_unlink",
    //"mremap",
    "msgctl",
    "msgget",
    "msgrcv",
    //"msgsnd", restrictions applied, see setup_seccomp.
    "msync",
    "munlock",
    "munlockall",
    "munmap",
    //name_to_handle_at
    "nanosleep",
    //nfsservctl,
    //"open_by_handle_at",
    //open_tree
    "pause",
    //"perf_event_open", restrictions applied see load_seccomp_parent and setup_seccomp.
    "personality", // restrictions applied in load_seccomp_parent.
    "pidfd_getfd",
    //"pidfd_open", restrictions applied, see setup_seccomp
    "pidfd_send_signal",
    "pipe",
    "pipe2",
    //pivot_root,
    //"pkey_alloc", restrictions applied, see setup_seccomp.
    //"pkey_free", ditto
    //"pkey_mprotect", ditto
    "poll",
    "ppoll",
    "ppoll_time64",
    // "prctl", restrictions applied, see setup_seccomp.
    "pread64",
    "preadv",
    "preadv2",
    //"prlimit64",
    "process_madvise",
    "process_mrelease",
    //process_vm_readv // restrictions applied, see setup_seccomp.
    //process_vm_writev // ditto.
    "pselect6",
    "pselect6_time64",
    //"ptrace", // restrictions applied see load_seccomp_parent and setup_seccomp.
    //"putpmsg",
    "pwrite64",
    "pwritev",
    "pwritev2",
    //query_module,
    //quotactl
    //quotactl_fd
    "read",
    "readahead",
    "readlink",
    "readlinkat",
    "readv",
    //reboot
    "recv",
    "recvfrom",
    "recvmmsg",
    "recvmmsg_time64",
    "recvmsg",
    "remap_file_pages",
    //request_key, restrictions applied, see setup_seccomp.
    "restart_syscall",
    "riscv_flush_icache",
    "riscv_hwprobe",
    "rseq",
    "rt_sigaction",
    "rt_sigpending",
    "rt_sigprocmask",
    "rt_sigqueueinfo",
    "rt_sigreturn",
    "rt_sigsuspend",
    "rt_sigtimedwait",
    "rt_sigtimedwait_time64",
    "rt_tgsigqueueinfo",
    "s390_pci_mmio_read",
    "s390_pci_mmio_write",
    "s390_runtime_instr",
    "sched_get_priority_max",
    "sched_get_priority_min",
    "sched_getaffinity",
    "sched_getattr",
    "sched_rr_get_interval",
    "sched_rr_get_interval_time64",
    "sched_getparam",
    "sched_getscheduler",
    "sched_setaffinity",
    "sched_setattr",
    "sched_setscheduler",
    "sched_setparam",
    "sched_yield",
    "seccomp",
    //security
    "select",
    "semctl",
    "semget",
    "semop",
    "semtimedop",
    "semtimedop_time64",
    "send",
    "sendfile",
    "sendfile64",
    //"sendmmsg", emulated.
    //"sendmsg", emulated.
    //"set_mempolicy",
    "set_robust_list",
    "set_thread_area",
    "set_tid_address",
    "setdomainname",
    //"setfsgid",
    //"setfsgid32",
    //"setfsuid",
    //"setfsuid32",
    //"setgid",
    //"setgid32",
    //"setgroups",
    //"setgroups32",
    "sethostname",
    "setitimer",
    "setns", // restrictions applied in load_seccomp_parent.
    "setpgid",
    "setpriority",
    //"setregid",
    //"setregid32",
    //"setresgid",
    //"setresgid32",
    //"setresuid",
    //"setresuid32",
    //"setreuid",
    //"setreuid32",
    //"setrlimit",
    "setsid",
    "setsockopt",
    //"settimeofday"
    //"setuid",
    //"setuid32",
    "set_tls", // arm
    //"sgetmask", // x86, OBSOLETE!
    //"ssetmask", // x86, OBSOLETE!
    "shmat",
    "shmctl",
    "shmdt",
    "shmget",
    "shutdown",
    "signal",
    "sigaction",
    "sigaltstack",
    "signalfd",
    "signalfd4",
    "sigpending",
    "sigprocmask",
    "sigsuspend",
    "sigreturn",
    //"socket",
    "socketpair",
    "splice",
    //"statfs",
    //"statfs64",
    //swapoff
    //swapon
    //"sync",
    "sync_file_range",
    //"syncfs",
    "sysinfo",
    //"syslog",
    "tee",
    //"tgkill", restrictions applied, see setup_seccomp
    "time",
    "timer_create",
    "timer_delete",
    "timer_getoverrun",
    "timer_gettime",
    "timer_gettime64",
    "timer_settime",
    "timer_settime64",
    "timerfd_create",
    "timerfd_gettime",
    "timerfd_gettime64",
    "timerfd_settime",
    "timerfd_settime64",
    "times",
    //"tkill", an obsolete predecessor to tgkill, should be avoided.
    //tuxcall
    "ugetrlimit",
    "umask",
    //"uname", restrictions applied, see setup_seccomp
    //olduname,
    //oldolduname,
    "umount",  // restrictions applied in load_seccomp_parent.
    "umount2", // ditto
    "unshare", // ditto
    //"uselib",
    //"userfaultfd",
    //"ustat",
    //"vfork", subject to fork protection
    //"vhangup",
    //"vmsplice", // see DEAD_SYSCALLS!
    //vserver
    "wait4",
    "waitid",
    "waitpid",
    "write",
    "writev",
];

/// System calls allowed for emulator threads.
// TODO: Further restrict open & socket calls.
pub const EMU_SYSCALLS: &[&str] = &[
    "_llseek",
    "accept4",
    "bind",
    "brk",
    "chmod",
    "chown",
    "clock_gettime",
    "clock_gettime64",
    "clock_nanosleep",
    "clone",
    "close",
    "connect",
    "epoll_pwait",
    "epoll_wait",
    "exit",
    "faccessat2",
    "fanotify_mark",
    "fchdir",
    "fchmod",
    "fchmodat",
    "fchmodat2",
    "fchown",
    "fchownat",
    "fcntl",
    "fcntl64",
    "fgetxattr",
    "flistxattr",
    "fremovexattr",
    "fsetxattr",
    "fstat",
    "fstat64",
    "fstatfs",
    "fstatfs64",
    "ftruncate",
    "ftruncate64",
    "futex",
    "get_robust_list",
    "getdents64",
    "getpgid",
    "getpgrp",
    "getpid",
    "getrandom",
    "getsockname",
    "getsockopt",
    "gettid",
    "inotify_add_watch",
    "ioctl",
    "kill",
    "landlock_create_ruleset",
    "landlock_restrict_self",
    "lgetxattr",
    "linkat",
    "llistxattr",
    "lseek",
    "lstat",
    "madvise",
    "memfd_create",
    "mkdirat",
    "mknodat",
    "mlock",
    "mmap",
    "mmap2",
    "mprotect",
    "mremap",
    "munlock",
    "munmap",
    "nanosleep",
    "newfstatat",
    "open",
    "openat",
    "openat2",
    "pidfd_getfd",
    "pidfd_open",
    "pidfd_send_signal",
    "pipe2",
    "prctl",
    "process_vm_readv",
    "process_vm_writev",
    "read",
    "readlink",
    "readlinkat",
    "readv",
    "renameat",
    "renameat2",
    "restart_syscall",
    "rseq",
    "rt_sigprocmask",
    "sched_getaffinity",
    "sched_yield",
    "seccomp",
    "send",
    "sendmsg",
    "sendto",
    "set_robust_list",
    "sigaltstack",
    "sigprocmask",
    "socket",
    "statx",
    "symlinkat",
    "tgkill",
    "tkill",
    "umask",
    "uname",
    "unlinkat",
    "utimensat",
    "waitid",
    "write",
    "writev",
];

/// System calls allowed for main wait thread.
pub const MAIN_SYSCALLS: &[&str] = &[
    "_llseek",
    "brk",
    "clock_gettime",
    "clock_gettime64",
    "clock_nanosleep",
    "close",
    "exit_group",
    "fcntl",
    "fcntl64",
    "fstat",
    "fstat64",
    "fstatfs",
    "fstatfs64",
    "futex",
    "get_robust_list",
    "getpgid",
    "getpgrp",
    "getpid",
    "getrandom",
    "gettid",
    "kill",
    "lseek",
    "madvise",
    "mmap",
    "mmap2",
    "mprotect",
    "mremap",
    "munlock",
    "munmap",
    "nanosleep",
    "open",
    "openat",
    "openat2",
    "ptrace",
    "read",
    "readlink",
    "readlinkat",
    "readv",
    "restart_syscall",
    "rseq",
    "rt_sigprocmask",
    "sched_getaffinity",
    "sched_yield",
    "set_robust_list",
    "sigaltstack",
    "sigprocmask",
    "statx",
    "tgkill",
    "tkill",
    "waitid",
    "write",
    "writev",
];
