//
// Syd: rock-solid unikernel
// src/sandbox.rs: Sandbox configuration
//
// 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
//
// SPDX-License-Identifier: GPL-3.0-or-later

#[allow(clippy::disallowed_types)]
use std::{
    clone::Clone,
    collections::VecDeque,
    env,
    ffi::{OsStr, OsString},
    fmt,
    fs::File,
    io::{BufRead, BufReader, Read},
    net::{IpAddr, Ipv4Addr, Ipv6Addr},
    ops::{Deref, DerefMut},
    os::{
        fd::{AsRawFd, OwnedFd, RawFd},
        unix::{ffi::OsStrExt, process::CommandExt},
    },
    path::{Path, PathBuf},
    process::{Command, Stdio},
    str::FromStr,
    sync::atomic::{AtomicBool, Ordering},
    time::Duration,
};

use bitflags::bitflags;
use expiringmap::ExpiringMap;
use hex::{DisplayHex, FromHex};
use indexmap::IndexSet;
use ipnet::{IpNet, Ipv4Net, Ipv6Net};
use iprange::IpRange;
use lexis::ToName;
use nix::{
    errno::Errno,
    fcntl::OFlag,
    mount::MsFlags,
    sys::{socket::UnixAddr, stat::Mode},
    unistd::{getgroups, getpid, setsid, Gid, Pid, Uid},
};
#[cfg(feature = "oci")]
use oci_spec::runtime::Spec;
use once_cell::sync::Lazy;
use parking_lot::{RwLockReadGuard, RwLockUpgradableReadGuard, RwLockWriteGuard};
use regex::{Captures, Regex, RegexBuilder};
use rustc_hash::{FxHashMap, FxHashSet};
use serde::{
    ser::{SerializeMap, SerializeStruct},
    Serialize, Serializer,
};
use smallvec::SmallVec;

use crate::{
    compat::{fstatx, STATX_INO, STATX_MODE, STATX_UID},
    config::*,
    err::{err2no, SydError, SydResult},
    error, extend_ioctl,
    fs::{
        mask_path, path_exists, path_has_control_chars, path_split, retry_on_eintr, safe_open,
        safe_open_path, FileInformation, SmallPathBuf,
    },
    hash::HashAlgorithm,
    hook::{RemoteProcess, UNotifyEventRequest},
    human_size, info, parse_group, parse_user,
    proc::proc_unix_get_inodes,
    wildmatch::{get_prefix, globmatch, is_literal, litmatch, MatchMethod},
    ScmpNotifReq, SydMsFlags, CLONE_NEWTIME, NAMESPACE_FLAGS_ALL,
};

const LINE_MAX: usize = 4096;
const PORT_MIN: u16 = 0;
const PORT_MAX: u16 = 0xFFFF;

static RE_BIND: Lazy<Regex> = Lazy::new(|| {
    #[allow(clippy::disallowed_methods)]
    RegexBuilder::new(
        r"
        \A
        bind
        (?P<mod>[-+^])
        (?P<src>[^:]+)
        :
        (?P<dst>[^:]+)
        (?::
            (?P<opt>([^,]+)(,[^,]+)*)
        )?
        \z
    ",
    )
    .ignore_whitespace(true)
    .build()
    .expect("Invalid bind mount regex, please file a bug!")
});

static RE_FORCE: Lazy<Regex> = Lazy::new(|| {
    #[allow(clippy::disallowed_methods)]
    RegexBuilder::new(
        r"
        \A
        force
        (?P<mod>[-+^])
        (?P<src>/[^:]*)?
        (?:
            :
            (?P<key>([0-9a-fA-F]{32}|[0-9a-fA-F]{40}|[0-9a-fA-F]{64}|[0-9a-fA-F]{96}|[0-9a-fA-F]{128}))
            :
            (?P<act>warn|stop|kill)
        )?
        \z
    ",
    )
    .ignore_whitespace(true)
    .build()
    .expect("Invalid integrity force regex, please file a bug!")
});

static RE_SETID_0: Lazy<Regex> = Lazy::new(|| {
    #[allow(clippy::disallowed_methods)]
    RegexBuilder::new(
        r"
        \A
        set(?P<id>[ug])id
        (?P<mod>[-+])
        (?P<src>[^:]+)
        :
        (?P<dst>[^:]+)
        \z
    ",
    )
    .ignore_whitespace(true)
    .build()
    .expect("Invalid integrity setid-0 regex, please file a bug!")
});

static RE_SETID_1: Lazy<Regex> = Lazy::new(|| {
    #[allow(clippy::disallowed_methods)]
    RegexBuilder::new(
        r"
        \A
        set(?P<id>[ug])id
        (?P<mod>\^)
        (?P<src>[^:]+)?
        \z
    ",
    )
    .ignore_whitespace(true)
    .build()
    .expect("Invalid integrity setid-1 regex, please file a bug!")
});

static RE_RULE: Lazy<Regex> = Lazy::new(|| {
    #[allow(clippy::disallowed_methods)]
    RegexBuilder::new(
        r"
        \A
        (
            # We have an action with a capability.
            (?P<act>
                allow |
                deny |
                filter |
                warn |
                stop |
                kill |
                exit
            )/
            (
                # Match combinations of read, write, exec, stat, and ioctl
                (?P<cap_many>
                    (
                        read |
                        write |
                        exec |
                        stat |
                        ioctl
                    )
                    (,
                        (
                            read |
                            write |
                            exec |
                            stat |
                            ioctl
                        )
                    )*
                ) |
                # Other capabilities, not allowing combinations
                (?P<cap_single>
                    lock/read |
                    lock/write |
                    net/bind |
                    net/connect
                )
            )
        )
        (?P<mod>[-+:^])
        (
            (?P<addr>[A-Fa-f0-9:\.]+(/[0-9]+)?[!@][0-9]+(-[0-9]+)?) |
            (?P<path>.+)
        )
        \z
    ",
    )
    .ignore_whitespace(true)
    .build()
    .expect("Invalid sandbox rule regex, please file a bug!")
});

static RE_NETALIAS: Lazy<Regex> = Lazy::new(|| {
    #[allow(clippy::disallowed_methods)]
    RegexBuilder::new(
        r"
        \A
        (?P<command>
            (
                allow |
                deny |
                filter |
                warn |
                stop |
                kill
            )
            /net/
            (
                bind |
                connect
            )
            [-+^]
            # SAFETY: Every item in the regex group `alias' below,
            # must have a corresponding item in the MAP_NETALIAS hash map!
            (?P<alias>
                ([aA][nN][yY][46]?) |
                ([lL][oO][cC][aA][lL][46]?) |
                ([lL][oO][oO][pP][bB][aA][cC][kK][46]?) |
                ([lL][iI][nN][kK][lL][oO][cC][aA][lL][46]?)
            )
            [!@]
            [0-9]+
            (-[0-9]+)?
        )
        \z
    ",
    )
    .ignore_whitespace(true)
    .build()
    .expect("Invalid network alias regex, please file a bug!")
});

type AliasMap<'a> = FxHashMap<&'a str, Vec<&'a str>>;
static MAP_NETALIAS: Lazy<AliasMap> = Lazy::new(|| {
    let mut map = FxHashMap::default();
    map.insert("any4", vec!["0.0.0.0/0"]);
    map.insert("any6", vec!["::/0"]);
    map.insert("any", vec!["0.0.0.0/0", "::/0"]);
    map.insert("linklocal4", vec!["fe80::/10"]);
    map.insert("linklocal6", vec!["fe80::/10"]);
    map.insert("linklocal", vec!["169.254.0.0/16", "fe80::/10"]);
    map.insert(
        "local4",
        vec![
            "127.0.0.0/8",
            "10.0.0.0/8",
            "172.16.0.0/12",
            "192.168.0.0/16",
        ],
    );
    map.insert("local6", vec!["::1", "fe80::/7", "fc00::/7", "fec0::/7"]);
    map.insert(
        "local",
        vec![
            "127.0.0.0/8",
            "10.0.0.0/8",
            "172.16.0.0/12",
            "192.168.0.0/16",
            "::1/128",
            "fe80::/7",
            "fc00::/7",
            "fec0::/7",
        ],
    );
    map.insert("loopback4", vec!["127.0.0.0/8"]);
    map.insert("loopback6", vec!["::1/128"]);
    map.insert("loopback", vec!["127.0.0.0/8", "::1/128"]);

    map
});

static RE_RULE_NETLINK: Lazy<Regex> = Lazy::new(|| {
    #[allow(clippy::disallowed_methods)]
    RegexBuilder::new(
        r"
        \A
        allow/net/link
        (
            (?P<clr>^) |
            (
                ((?P<add>[+])|(?P<del>[-]))
                (?P<fml>
                    (
                        route |
                        usersock |
                        firewall |
                        inet_diag |
                        sock_diag |
                        nflog |
                        xfrm |
                        selinux |
                        iscsi |
                        audit |
                        fib_lookup |
                        connector |
                        netfilter |
                        ip6_fw |
                        dnrtmsg |
                        kobject_uevent |
                        generic |
                        scsitransport |
                        ecryptfs |
                        rdma |
                        crypto
                    )
                    (,
                        (
                            route |
                            usersock |
                            firewall |
                            inet_diag |
                            sock_diag |
                            nflog |
                            xfrm |
                            selinux |
                            iscsi |
                            audit |
                            fib_lookup |
                            connector |
                            netfilter |
                            ip6_fw |
                            dnrtmsg |
                            kobject_uevent |
                            generic |
                            scsitransport |
                            ecryptfs |
                            rdma |
                            crypto
                        )
                    )*
                )
            )
        )
        \z
    ",
    )
    .ignore_whitespace(true)
    .build()
    .expect("Invalid sandbox rule regex, please file a bug!")
});

const ROOT_UID: Uid = Uid::from_raw(0);
const ROOT_GID: Gid = Gid::from_raw(0);

#[inline]
fn strbool(s: &str) -> Result<bool, Errno> {
    match s.to_ascii_lowercase().as_str() {
        "1" | "on" | "t" | "tr" | "tru" | "true" | "✓" => Ok(true),
        "0" | "off" | "f" | "fa" | "fal" | "fals" | "false" | "✗" => Ok(false),
        "" => Err(Errno::ENOENT),
        _ => Err(Errno::EINVAL),
    }
}

#[allow(clippy::disallowed_types)]
type LandlockPathPair = (Vec<PathBuf>, Vec<PathBuf>);

bitflags! {
    /// Represents allowlisted netlink families.
    #[derive(Clone, Copy, Debug, Eq, PartialEq)]
    pub(crate) struct NetlinkFamily: u32 {
        const NETLINK_ROUTE = 1 << 0;
        const NETLINK_USERSOCK = 1 << 1;
        const NETLINK_FIREWALL = 1 << 2;
        // sock_diag = inet_diag
        const NETLINK_SOCK_DIAG = 1 << 3;
        const NETLINK_NFLOG = 1 << 4;
        const NETLINK_XFRM = 1 << 5;
        const NETLINK_SELINUX = 1 << 6;
        const NETLINK_ISCSI = 1 << 7;
        const NETLINK_AUDIT = 1 << 8;
        const NETLINK_FIB_LOOKUP = 1 << 9;
        const NETLINK_CONNECTOR = 1 << 10;
        const NETLINK_NETFILTER = 1 << 11;
        const NETLINK_IP6_FW = 1 << 12;
        const NETLINK_DNRTMSG = 1 << 13;
        const NETLINK_KOBJECT_UEVENT = 1 << 14;
        const NETLINK_GENERIC = 1 << 15;
        const NETLINK_SCSITRANSPORT = 1 << 16;
        const NETLINK_ECRYPTFS = 1 << 17;
        const NETLINK_RDMA = 1 << 18;
        const NETLINK_CRYPTO = 1 << 19;
    }
}

impl FromStr for NetlinkFamily {
    type Err = Errno;

    fn from_str(value: &str) -> Result<Self, Self::Err> {
        let mut families = NetlinkFamily::empty();
        for family in value.split(',') {
            // Let's be as lax as possible but not more.
            let family = family.trim();
            if family.is_empty() {
                continue;
            }
            families |= match family.to_ascii_lowercase().as_str() {
                "route" => Self::NETLINK_ROUTE,
                "usersock" => Self::NETLINK_USERSOCK,
                "firewall" => Self::NETLINK_FIREWALL,
                "inet_diag" | "sock_diag" => Self::NETLINK_SOCK_DIAG,
                "nflog" => Self::NETLINK_NFLOG,
                "xfrm" => Self::NETLINK_XFRM,
                "selinux" => Self::NETLINK_SELINUX,
                "iscsi" => Self::NETLINK_ISCSI,
                "audit" => Self::NETLINK_AUDIT,
                "fib_lookup" => Self::NETLINK_FIB_LOOKUP,
                "connector" => Self::NETLINK_CONNECTOR,
                "netfilter" => Self::NETLINK_NETFILTER,
                "ip6_fw" => Self::NETLINK_IP6_FW,
                "dnrtmsg" => Self::NETLINK_DNRTMSG,
                "kobject_uevent" => Self::NETLINK_KOBJECT_UEVENT,
                "generic" => Self::NETLINK_GENERIC,
                "scsitransport" => Self::NETLINK_SCSITRANSPORT,
                "ecryptfs" => Self::NETLINK_ECRYPTFS,
                "rdma" => Self::NETLINK_RDMA,
                "crypto" => Self::NETLINK_CRYPTO,
                _ => return Err(Errno::EINVAL),
            };
        }

        if !families.is_empty() {
            Ok(families)
        } else {
            Err(Errno::ENOENT)
        }
    }
}

impl NetlinkFamily {
    const ALL: [Self; 20] = [
        Self::NETLINK_ROUTE,
        Self::NETLINK_USERSOCK,
        Self::NETLINK_FIREWALL,
        Self::NETLINK_SOCK_DIAG,
        Self::NETLINK_NFLOG,
        Self::NETLINK_XFRM,
        Self::NETLINK_SELINUX,
        Self::NETLINK_ISCSI,
        Self::NETLINK_AUDIT,
        Self::NETLINK_FIB_LOOKUP,
        Self::NETLINK_CONNECTOR,
        Self::NETLINK_NETFILTER,
        Self::NETLINK_IP6_FW,
        Self::NETLINK_DNRTMSG,
        Self::NETLINK_KOBJECT_UEVENT,
        Self::NETLINK_GENERIC,
        Self::NETLINK_SCSITRANSPORT,
        Self::NETLINK_ECRYPTFS,
        Self::NETLINK_RDMA,
        Self::NETLINK_CRYPTO,
    ];

    pub(crate) fn max() -> nix::libc::c_int {
        nix::libc::NETLINK_CRYPTO.saturating_add(1)
    }

    pub(crate) fn to_vec(self) -> Vec<nix::libc::c_int> {
        let mut vec = Vec::new();

        if self.is_empty() {
            // Do nothing.
        } else {
            for netlink_family in Self::ALL {
                if self.contains(netlink_family) {
                    vec.push(netlink_family.to_raw_int());
                }
            }
        }

        vec
    }

    fn to_raw_int(self) -> nix::libc::c_int {
        match self {
            Self::NETLINK_ROUTE => nix::libc::NETLINK_ROUTE,
            Self::NETLINK_USERSOCK => nix::libc::NETLINK_USERSOCK,
            Self::NETLINK_FIREWALL => nix::libc::NETLINK_FIREWALL,
            Self::NETLINK_SOCK_DIAG => nix::libc::NETLINK_SOCK_DIAG,
            Self::NETLINK_NFLOG => nix::libc::NETLINK_NFLOG,
            Self::NETLINK_XFRM => nix::libc::NETLINK_XFRM,
            Self::NETLINK_SELINUX => nix::libc::NETLINK_SELINUX,
            Self::NETLINK_ISCSI => nix::libc::NETLINK_ISCSI,
            Self::NETLINK_AUDIT => nix::libc::NETLINK_AUDIT,
            Self::NETLINK_FIB_LOOKUP => nix::libc::NETLINK_FIB_LOOKUP,
            Self::NETLINK_CONNECTOR => nix::libc::NETLINK_CONNECTOR,
            Self::NETLINK_NETFILTER => nix::libc::NETLINK_NETFILTER,
            Self::NETLINK_IP6_FW => nix::libc::NETLINK_IP6_FW,
            Self::NETLINK_DNRTMSG => nix::libc::NETLINK_DNRTMSG,
            Self::NETLINK_KOBJECT_UEVENT => nix::libc::NETLINK_KOBJECT_UEVENT,
            Self::NETLINK_GENERIC => nix::libc::NETLINK_GENERIC,
            Self::NETLINK_SCSITRANSPORT => nix::libc::NETLINK_SCSITRANSPORT,
            Self::NETLINK_ECRYPTFS => nix::libc::NETLINK_ECRYPTFS,
            Self::NETLINK_RDMA => nix::libc::NETLINK_RDMA,
            Self::NETLINK_CRYPTO => nix::libc::NETLINK_CRYPTO,
            _ => unreachable!(),
        }
    }
}

/// Represents an integrity error, used by Force Sandboxing.
#[derive(Debug)]
pub enum IntegrityError {
    /// System error, represented by an Errno.
    Sys(Errno),
    /// Hash mismatch.
    Hash {
        /// The action to take on mismatch.
        action: Action,
        /// Expected hash as hex-encoded string.
        expected: String,
        /// Found hash as hex-encoded string.
        found: String,
    },
}

impl From<Errno> for IntegrityError {
    fn from(errno: Errno) -> Self {
        IntegrityError::Sys(errno)
    }
}

impl From<SydError> for IntegrityError {
    fn from(error: SydError) -> Self {
        Self::Sys(error.errno().unwrap_or(Errno::ENOSYS))
    }
}

/// Represents a recursive bind mount operation.
#[allow(clippy::disallowed_types)]
#[derive(Debug)]
pub struct BindMount {
    /// Source directory
    pub src: PathBuf,
    /// Target directory, can be the same as source
    pub dst: PathBuf,
    /// The options that are allowed are:
    /// ro, nosuid, nodev, noexec, noatime, nodiratime and relatime
    /// kernel is going to ignore other options.
    pub opt: MsFlags,
    /// Optional filesystem specific data, useful for tmpfs.
    pub dat: Option<PathBuf>,
}

impl PartialEq for BindMount {
    // Flags are not used in equality check.
    fn eq(&self, other: &Self) -> bool {
        self.src == other.src && self.dst == other.dst
    }
}

// Eq can be derived as well since PartialEq is implemented
impl Eq for BindMount {}

#[allow(clippy::disallowed_types)]
impl TryFrom<&Captures<'_>> for BindMount {
    type Error = Errno;

    fn try_from(captures: &Captures) -> Result<Self, Self::Error> {
        let src = &captures["src"];
        let dst = &captures["dst"];

        // SAFETY: Do not allow custom proc mounts.
        if src == "proc" {
            return Err(Errno::EPERM);
        }

        let src = PathBuf::from(src);
        let dst = PathBuf::from(dst);
        let mut opt = MsFlags::empty();
        let mut dat = Vec::new();

        // SAFETY:
        // 1. Deny relative destination paths.
        // 2. Deny ../ traversal in bind paths.
        if dst.is_relative()
            || src
                .components()
                .any(|p| p == std::path::Component::ParentDir)
            || dst
                .components()
                .any(|p| p == std::path::Component::ParentDir)
        {
            return Err(Errno::EINVAL);
        }

        if let Some(opt_match) = captures.name("opt") {
            for flag in opt_match.as_str().split(',') {
                match SydMsFlags::from_name(flag) {
                    Some(flag) => opt |= flag.0,
                    None => {
                        if !dat.is_empty() {
                            // Separate unrecognized flags with a comma
                            dat.push(b',');
                        }
                        dat.extend_from_slice(flag.as_bytes());
                    }
                }
            }
        }

        let dat = if dat.is_empty() {
            None
        } else {
            Some(PathBuf::from(OsStr::from_bytes(&dat)))
        };

        Ok(Self { src, dst, opt, dat })
    }
}

impl Serialize for BindMount {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let mut map = serializer.serialize_map(Some(4))?; // We expect 4 fields.

        // Serialize src field
        map.serialize_entry("src", &self.src.to_string_lossy())?;

        // Serialize dst field
        map.serialize_entry("dst", &self.dst.to_string_lossy())?;

        // Serialize opt field using to_names from SydMsFlags
        let syd_flags = SydMsFlags(self.opt);
        let flags_names = syd_flags.to_names();
        map.serialize_entry("opt", &flags_names)?;

        // Serialize dat field
        match &self.dat {
            Some(dat) => map.serialize_entry("dat", &dat.to_string_lossy())?,
            None => map.serialize_entry("dat", &None::<String>)?,
        };

        map.end()
    }
}

bitflags! {
    /// Sandboxing capabilities
    #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
    pub struct Capability: u16 {
        /// Pseudo capabilities for Append and Mask.
        const CAP_APPEND = u16::MIN;
        /// These flags must _never_ be checked with contains or intersects!
        /// These are used in Path Action Cache only where it is safe.
        const CAP_MASK = u16::MAX;

        /// Read capability
        const CAP_READ = 1 << 0;
        /// List capability
        const CAP_STAT = 1 << 1;
        /// Write capability
        const CAP_WRITE = 1 << 2;
        /// Execute capability
        const CAP_EXEC = 1 << 3;
        /// Ioctl capability
        const CAP_IOCTL = 1 << 4;
        /// Network connect capability
        const CAP_CONNECT = 1 << 5;
        /// Network bind capability
        const CAP_BIND = 1 << 6;
        /// Memory capability
        const CAP_MEM = 1 << 7;
        /// Pid capability
        const CAP_PID = 1 << 8;
        /// Force capability
        const CAP_FORCE = 1 << 9;
        /// Trusted Path Execution (TPE) capability
        const CAP_TPE = 1 << 10;
        /// Proxy sandboxing
        const CAP_PROXY = 1 << 11;
        /// Landlock read capability
        const CAP_LOCK_RO = 1 << 12;
        /// Landlock read-write capability
        const CAP_LOCK_RW = 1 << 13;
        /// Landlock capability
        const CAP_LOCK = Self::CAP_LOCK_RO.bits() | Self::CAP_LOCK_RW.bits();
    }
}

impl Capability {
    /// Define a static array containing all capabilities with path/glob rules
    const GLOB: [Self; 7] = [
        Self::CAP_READ,
        Self::CAP_STAT,
        Self::CAP_WRITE,
        Self::CAP_EXEC,
        Self::CAP_IOCTL,
        Self::CAP_CONNECT,
        Self::CAP_BIND,
    ];

    /// Returns true if the Capability relates to filesystem read.
    pub fn can_read(self) -> bool {
        self == Self::CAP_READ
    }

    /// Returns true if the Capability relates to filesystem stat.
    pub fn can_stat(self) -> bool {
        self == Self::CAP_STAT
    }

    /// Returns true if the Capability relates to filesystem write.
    pub fn can_write(self) -> bool {
        // bind is for UNIX sockets whose creation is filesystem write.
        matches!(self, Self::CAP_WRITE | Self::CAP_BIND)
    }

    /// Returns true if the Capability relates to networking.
    pub fn can_net(self) -> bool {
        matches!(self, Self::CAP_BIND | Self::CAP_CONNECT)
    }

    /// Returns true if the Capability relates to the Landlock LSM.
    pub fn can_lock(self) -> bool {
        matches!(self, Self::CAP_LOCK_RO | Self::CAP_LOCK_RW)
    }

    /// Returns true if the Capability must be set at startup.
    pub fn is_startup(self) -> bool {
        self.intersects(Self::CAP_PROXY | Self::CAP_LOCK)
    }
}

impl FromStr for Capability {
    type Err = Errno;

    fn from_str(value: &str) -> Result<Self, Self::Err> {
        let mut caps = Self::empty();
        for cap in value.split(',') {
            // Let's be as lax as possible but not more.
            let cap = cap.trim();
            if cap.is_empty() {
                continue;
            }
            caps |= match cap.to_ascii_lowercase().as_str() {
                "exec" => Self::CAP_EXEC,
                "force" => Self::CAP_FORCE,
                "lock" => Self::CAP_LOCK,
                "mem" => Self::CAP_MEM,
                "pid" => Self::CAP_PID,
                "proxy" => Self::CAP_PROXY,
                "read" => Self::CAP_READ,
                "stat" => Self::CAP_STAT,
                "ioctl" => Self::CAP_IOCTL,
                "tpe" => Self::CAP_TPE,
                "write" => Self::CAP_WRITE,
                "net" => Self::CAP_BIND | Capability::CAP_CONNECT,
                /* Network sandboxing but only for one of Bind, Connect */
                "net/bind" => Self::CAP_BIND,
                "net/connect" => Self::CAP_CONNECT,
                _ => return Err(Errno::EINVAL),
            };
        }

        if !caps.is_empty() {
            Ok(caps)
        } else {
            Err(Errno::ENOENT)
        }
    }
}

#[allow(clippy::cognitive_complexity)]
impl fmt::Display for Capability {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut capabilities: SmallVec<[&str; 15]> = SmallVec::new();

        if self.contains(Self::CAP_READ) {
            capabilities.push("Read");
        }
        if self.contains(Self::CAP_STAT) {
            capabilities.push("Stat");
        }
        if self.contains(Self::CAP_WRITE) {
            capabilities.push("Write");
        }
        if self.contains(Self::CAP_EXEC) {
            capabilities.push("Execute");
        }
        if self.contains(Self::CAP_IOCTL) {
            capabilities.push("Ioctl");
        }
        if self.contains(Self::CAP_FORCE) {
            capabilities.push("Force");
        }
        if self.contains(Self::CAP_TPE) {
            capabilities.push("Trusted Path Execution (TPE)");
        }
        if self.contains(Self::CAP_PROXY) {
            capabilities.push("Proxy");
        }
        if self.contains(Self::CAP_CONNECT) {
            capabilities.push("Connect");
        }
        if self.contains(Self::CAP_MEM) {
            capabilities.push("Memory");
        }
        if self.contains(Self::CAP_PID) {
            capabilities.push("Pid");
        }
        if self.contains(Self::CAP_BIND) {
            capabilities.push("Bind");
        }
        if self.contains(Self::CAP_LOCK_RO) {
            capabilities.push("Landlock read-only");
        }
        if self.contains(Self::CAP_LOCK_RW) {
            capabilities.push("Landlock read-write");
        }

        write!(f, "{}", capabilities.join(", "))
    }
}

impl Serialize for Capability {
    #[allow(clippy::cognitive_complexity)]
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        let mut capabilities = String::new();

        if self.contains(Self::CAP_READ) {
            capabilities.push('r');
        }
        if self.contains(Self::CAP_STAT) {
            capabilities.push('s');
        }
        if self.contains(Self::CAP_WRITE) {
            capabilities.push('w');
        }
        if self.contains(Self::CAP_EXEC) {
            capabilities.push('x');
        }
        if self.contains(Self::CAP_IOCTL) {
            capabilities.push('i');
        }
        if self.contains(Self::CAP_FORCE) {
            capabilities.push('f');
        }
        if self.contains(Self::CAP_TPE) {
            capabilities.push('t');
        }
        if self.contains(Self::CAP_PROXY) {
            capabilities.push('@');
        }
        if self.contains(Self::CAP_BIND) {
            capabilities.push('b');
        }
        if self.contains(Self::CAP_CONNECT) {
            capabilities.push('c');
        }
        if self.contains(Self::CAP_MEM) {
            capabilities.push('m');
        }
        if self.contains(Self::CAP_PID) {
            capabilities.push('p');
        }
        if self.contains(Self::CAP_LOCK) {
            capabilities.push('l');
        }

        if capabilities.is_empty() {
            serializer.serialize_none()
        } else {
            serializer.serialize_str(&capabilities)
        }
    }
}

impl From<&Captures<'_>> for Capability {
    fn from(captures: &Captures) -> Self {
        // Note, we do not use CAP_FORCE here.
        // Force rules are defined elsewhere.
        // We do not use CAP_PROXY here either,
        // it's irrelevant (has no rules).
        // We do not use CAP_MEM, CAP_PID, or
        // CAP_TPE either as they only have a
        // single default Action.
        if let Some(cap) = captures.name("cap_single") {
            match cap.as_str() {
                "lock/read" => Self::CAP_LOCK_RO,
                "lock/write" => Self::CAP_LOCK_RW,
                "net/bind" => Self::CAP_BIND,
                "net/connect" => Self::CAP_CONNECT,
                _ => unreachable!(),
            }
        } else if let Some(caps) = captures.name("cap_many") {
            caps.as_str()
                .split(',')
                .map(|cap| match cap {
                    "read" => Self::CAP_READ,
                    "write" => Self::CAP_WRITE,
                    "exec" => Self::CAP_EXEC,
                    "stat" => Self::CAP_STAT,
                    "ioctl" => Self::CAP_IOCTL,
                    _ => unreachable!(),
                })
                .fold(Self::empty(), |acc, cap| acc | cap)
        } else {
            unreachable!("Invalid rule regex!");
        }
    }
}

impl TryFrom<(&RemoteProcess, &UNotifyEventRequest, &ScmpNotifReq, &str)> for Capability {
    type Error = Errno;

    // Find out capabilities of the system call using the system call name and seccomp request.
    fn try_from(
        value: (&RemoteProcess, &UNotifyEventRequest, &ScmpNotifReq, &str),
    ) -> Result<Self, Errno> {
        let (proc, request, req, syscall_name) = value;
        match syscall_name {
            name if Self::exec(name) => Ok(Self::CAP_EXEC),
            name if Self::stat(name) => Ok(Self::CAP_STAT),
            "ioctl" => Ok(Self::CAP_IOCTL),
            "bind" => Ok(Self::CAP_BIND),
            "accept" | "accept4" | "connect" | "sendto" | "sendmsg" | "sendmmsg" => {
                Ok(Self::CAP_CONNECT)
            }
            "open" | "openat" | "openat2" => Self::open(syscall_name, req, proc, request),
            _ => Ok(Self::CAP_WRITE),
        }
    }
}

impl Capability {
    fn open(
        syscall_name: &str,
        req: &ScmpNotifReq,
        proc: &RemoteProcess,
        request: &UNotifyEventRequest,
    ) -> Result<Self, Errno> {
        Ok(match syscall_name {
            "open" | "openat" => {
                let flidx = if syscall_name == "open" { 1 } else { 2 };
                #[allow(clippy::cast_possible_truncation)]
                let flags = OFlag::from_bits_truncate(req.data.args[flidx] as nix::libc::c_int);
                match flags & OFlag::O_ACCMODE {
                    OFlag::O_RDONLY => Self::CAP_READ,
                    _ => Self::CAP_WRITE,
                }
            }
            "openat2" => {
                let rohow = proc.remote_ohow(req.data.args[2], req.data.args[3], request)?;
                #[allow(clippy::cast_possible_truncation)]
                let flags = OFlag::from_bits_truncate(rohow.flags as nix::libc::c_int);
                match flags & OFlag::O_ACCMODE {
                    OFlag::O_RDONLY => Self::CAP_READ,
                    _ => Self::CAP_WRITE,
                }
            }
            _ => unreachable!(),
        })
    }

    fn exec(syscall_name: &str) -> bool {
        matches!(syscall_name, "execve" | "execveat")
    }

    fn stat(syscall_name: &str) -> bool {
        matches!(
            syscall_name,
            "access"
                | "faccessat"
                | "faccessat2"
                | "getdents"
                | "getdents64"
                | "stat"
                | "stat64"
                | "statfs"
                | "statfs64"
                | "statx"
                | "lstat"
                | "lstat64"
                | "fstatat64"
                | "newfstatat"
                | "getxattr"
                | "fgetxattr"
                | "lgetxattr"
                | "listxattr"
                | "flistxattr"
                | "llistxattr"
                | "fanotify_mark"
                | "inotify_add_watch"
        )
    }

    #[inline]
    pub(crate) fn mem(syscall_name: &str) -> bool {
        syscall_name == "memfd_create"
    }
}

bitflags! {
    /// Sandboxing options
    #[derive(Clone, Copy, Debug, Eq, PartialEq)]
    pub struct Flag: u64 {
        /// Force O_CLOEXEC flag for open(2) family calls.
        const FL_FORCE_CLOEXEC = 1 << 0;
        /// Deny .. in path resolution for open(2) family calls.
        const FL_DENY_DOTDOT = 1 << 1;
        /// Apply CONTINUE on O_PATH file descriptors rather than
        /// turning them into O_RDONLY.
        const FL_ALLOW_UNSAFE_OPEN = 1 << 2;
        /// Allow unsafe debug (perf, ptrace, etc) calls
        /// Keeps the capability CAP_SYS_PTRACE.
        /// Allows required paths such as /proc/kallsyms, /proc/self/m{aps,mem}.
        const FL_ALLOW_UNSAFE_DEBUG = 1 << 3;
        /// Allow execution of non-PIE binaries.
        const FL_ALLOW_UNSAFE_NOPIE = 1 << 4;
        /// Allow executable stack for ELF binaries.
        const FL_ALLOW_UNSAFE_STACK = 1 << 5;
        /// Deny execution of 32-bit ELF binaries.
        const FL_DENY_ELF32 = 1 << 6;
        /// Deny execution of dynamically linked binaries.
        const FL_DENY_ELF_DYNAMIC = 1 << 7;
        /// Deny execution of statically linked binaries.
        const FL_DENY_ELF_STATIC = 1 << 8;
        /// Deny execution of scripts using an interpreter via #!<path>.
        const FL_DENY_SCRIPT = 1 << 9;
        /// Allow access to the Linux kernel crypto API
        const FL_ALLOW_SAFE_KCAPI = 1 << 10;
        /// Allow socket families which are unsupported
        const FL_ALLOW_UNSUPP_SOCKET = 1 << 11;
        /// Allow filenames with control characters in them.
        const FL_ALLOW_UNSAFE_FILENAME = 1 << 12;
        /// Allow secret memfds and executable memfds.
        const FL_ALLOW_UNSAFE_MEMFD = 1 << 13;
        /// Negate TPE GID logic.
        const FL_TPE_NEGATE = 1 << 14;
        /// Ensure TPE directory is root owned.
        const FL_TPE_ROOT_OWNED = 1 << 15;
        /// Ensure TPE directory is user owned.
        const FL_TPE_USER_OWNED = 1 << 16;
        /// Wait for all processes before exiting.
        const FL_EXIT_WAIT_ALL = 1 << 17;

        /// If set at startup, all id system calls return 0 in the sandbox.
        const FL_FAKE_ROOT = 1 << 24;
        /// If set at startup, root is mapped to current user in the user namespace.
        const FL_MAP_ROOT = 1 << 25;
        /// Lock personality(2) changes.
        const FL_LOCK_PERSONALITY = 1 << 26;
        /// Retain capability CAP_SETUID
        const FL_ALLOW_SAFE_SETUID = 1 << 27;
        /// Retain capability CAP_SETGID
        const FL_ALLOW_SAFE_SETGID = 1 << 28;
        /// Allow successful bind calls for subsequent connect calls
        const FL_ALLOW_SAFE_BIND = 1 << 29;
        /// Retain capability CAP_NET_BIND_SERVICE
        const FL_ALLOW_UNSAFE_BIND = 1 << 30;
        /// Retain capability CAP_CHOWN
        const FL_ALLOW_UNSAFE_CHOWN = 1 << 31;
        /// Allow system calls for CPU emulation functionality
        const FL_ALLOW_UNSAFE_CPU = 1 << 32;
        /// Allow core dumps and ptracing for the Syd process.
        /// Together with FL_ALLOW_UNSAFE_EXEC allows strace -f syd.
        const FL_ALLOW_UNSAFE_DUMPABLE = 1 << 33;
        /// Disable exec-TOCTOU mitigator.
        /// Together with FL_ALLOW_UNSAFE_DUMPABLE allows strace -f syd.
        const FL_ALLOW_UNSAFE_EXEC = 1 << 34;
        /// Allow Kernel keyring access.
        const FL_ALLOW_UNSAFE_KEYRING = 1 << 35;
        /// Allow unsafe memory manipulation.
        const FL_ALLOW_UNSAFE_MEMORY = 1 << 36;
        /// Allow system calls used for memory protection keys.
        const FL_ALLOW_UNSAFE_PKEY = 1 << 37;
        /// Retain _all_ Linux capabilities.
        const FL_ALLOW_UNSAFE_CAPS = 1 << 38;
        /// Allow unsafe environment variables.
        const FL_ALLOW_UNSAFE_ENV = 1 << 39;
        /// Allow unsafe socket families (RAW and PACKET).
        const FL_ALLOW_UNSAFE_SOCKET = 1 << 40;
        /// Allow unsafe syslog calls (reading /proc/kmsg etc.)
        const FL_ALLOW_UNSAFE_SYSLOG = 1 << 41;
        /// Allow unsafe msgsnd calls.
        const FL_ALLOW_UNSAFE_MSGSND = 1 << 42;
        /// Allow unsafe prctl calls
        const FL_ALLOW_UNSAFE_PRCTL = 1 << 43;
        /// Allow unsafe prlimit calls
        const FL_ALLOW_UNSAFE_PRLIMIT = 1 << 44;
        /// Allow unsafe adjtimex and clock_adjtime calls,
        /// and keep the CAP_SYS_TIME capability.
        const FL_ALLOW_UNSAFE_TIME = 1 << 45;
        /// Allow the unsafe io-uring interface
        const FL_ALLOW_UNSAFE_IOURING = 1 << 46;
        /// Deny reading the timestamp counter (x86 only)
        const FL_DENY_TSC = 1 << 47;

        /// Allow mount namespace
        const FL_ALLOW_UNSAFE_UNSHARE_MOUNT = 1 << 48;
        /// Allow uts namespace
        const FL_ALLOW_UNSAFE_UNSHARE_UTS = 1 << 49;
        /// Allow ipc namespace
        const FL_ALLOW_UNSAFE_UNSHARE_IPC = 1 << 50;
        /// Allow user namespace
        const FL_ALLOW_UNSAFE_UNSHARE_USER = 1 << 51;
        /// Allow pid namespace
        const FL_ALLOW_UNSAFE_UNSHARE_PID = 1 << 52;
        /// Allow net namespace
        const FL_ALLOW_UNSAFE_UNSHARE_NET = 1 << 53;
        /// Allow cgroup namespace
        const FL_ALLOW_UNSAFE_UNSHARE_CGROUP = 1 << 54;
        /// Allow time namespace
        const FL_ALLOW_UNSAFE_UNSHARE_TIME = 1 << 55;

        /// Unshare mount namespace
        const FL_UNSHARE_MOUNT = 1 << 56;
        /// Unshare uts namespace
        const FL_UNSHARE_UTS = 1 << 57;
        /// Unshare ipc namespace
        const FL_UNSHARE_IPC = 1 << 58;
        /// Unshare user namespace
        const FL_UNSHARE_USER = 1 << 59;
        /// Unshare pid namespace
        const FL_UNSHARE_PID = 1 << 60;
        /// Unshare net namespace
        const FL_UNSHARE_NET = 1 << 61;
        /// Unshare cgroup namespace
        const FL_UNSHARE_CGROUP = 1 << 62;
        /// Unshare time namespace
        const FL_UNSHARE_TIME = 1 << 63;
    }
}

impl fmt::Display for Flag {
    #[allow(clippy::cognitive_complexity)]
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut flags: SmallVec<[&str; 64]> = SmallVec::new();

        if self.contains(Flag::FL_UNSHARE_MOUNT) {
            flags.push("Unshare Mount");
        }
        if self.contains(Flag::FL_UNSHARE_UTS) {
            flags.push("Unshare UTS");
        }
        if self.contains(Flag::FL_UNSHARE_IPC) {
            flags.push("Unshare Ipc");
        }
        if self.contains(Flag::FL_UNSHARE_USER) {
            flags.push("Unshare User");
        }
        if self.contains(Flag::FL_UNSHARE_PID) {
            flags.push("Unshare Pid");
        }
        if self.contains(Flag::FL_UNSHARE_NET) {
            flags.push("Unshare Net");
        }
        if self.contains(Flag::FL_UNSHARE_CGROUP) {
            flags.push("Unshare CGroup");
        }
        if self.contains(Flag::FL_UNSHARE_TIME) {
            flags.push("Unshare Time");
        }
        if self.contains(Flag::FL_EXIT_WAIT_ALL) {
            flags.push("Exit Wait All");
        }
        if self.contains(Flag::FL_TPE_NEGATE) {
            flags.push("Negate TPE GID Logic");
        }
        if self.contains(Flag::FL_TPE_ROOT_OWNED) {
            flags.push("Ensure TPE directory is root-owned");
        }
        if self.contains(Flag::FL_TPE_USER_OWNED) {
            flags.push("Ensure TPE directory is user-owned");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_BIND) {
            flags.push("Allow Unsafe Bind");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_CHOWN) {
            flags.push("Allow Unsafe Chown");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_CPU) {
            flags.push("Allow Unsafe CPU Emulation");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_DUMPABLE) {
            flags.push("Allow Unsafe Dumpable");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_EXEC) {
            flags.push("Allow Unsafe Exec");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_KEYRING) {
            flags.push("Allow Unsafe Kernel keyring");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_MEMORY) {
            flags.push("Allow Unsafe Memory");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_PKEY) {
            flags.push("Allow Unsafe Memory Protection Keys");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_CAPS) {
            flags.push("Allow Unsafe Capabilities");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_ENV) {
            flags.push("Allow Unsafe Environment");
        }
        if self.contains(Flag::FL_FAKE_ROOT) {
            flags.push("Fake Root");
        }
        if self.contains(Flag::FL_MAP_ROOT) {
            flags.push("Map Root");
        }
        if self.contains(Flag::FL_ALLOW_SAFE_BIND) {
            flags.push("Allow Safe Bind");
        }
        if self.contains(Flag::FL_ALLOW_SAFE_KCAPI) {
            flags.push("Allow Safe Kernel Crypto API");
        }
        if self.contains(Flag::FL_ALLOW_SAFE_SETUID) {
            flags.push("Allow Safe SetUID");
        }
        if self.contains(Flag::FL_ALLOW_SAFE_SETGID) {
            flags.push("Allow Safe SetGID");
        }
        if self.contains(Flag::FL_ALLOW_UNSUPP_SOCKET) {
            flags.push("Allow Unsupported Socket Families");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_SOCKET) {
            flags.push("Allow Unsafe Socket Families");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_SYSLOG) {
            flags.push("Allow Unsafe Syslog");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_MSGSND) {
            flags.push("Allow Unsafe MsgSnd");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_PRCTL) {
            flags.push("Allow Unsafe PRctl");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_PRLIMIT) {
            flags.push("Allow Unsafe PRlimit");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_TIME) {
            flags.push("Allow Unsafe Time");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_DEBUG) {
            flags.push("Allow Unsafe Debug");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_NOPIE) {
            flags.push("Allow Unsafe No-PIE");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_STACK) {
            flags.push("Allow Unsafe Stack");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_OPEN) {
            flags.push("Allow Unsafe Open");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_FILENAME) {
            flags.push("Allow Unsafe Filename");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_IOURING) {
            flags.push("Allow Unsafe IO_Uring");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_MEMFD) {
            flags.push("Allow Unsafe MemFD");
        }
        if self.contains(Flag::FL_FORCE_CLOEXEC) {
            flags.push("Force Close on Exec");
        }
        if self.contains(Flag::FL_DENY_DOTDOT) {
            flags.push("Deny DotDot");
        }
        if self.contains(Flag::FL_DENY_ELF32) {
            flags.push("Deny Elf32");
        }
        if self.contains(Flag::FL_DENY_ELF_DYNAMIC) {
            flags.push("Deny Dynamically Linked Elf");
        }
        if self.contains(Flag::FL_DENY_ELF_STATIC) {
            flags.push("Deny Statically Linked Elf");
        }
        if self.contains(Flag::FL_DENY_SCRIPT) {
            flags.push("Deny Script");
        }
        if self.contains(Flag::FL_DENY_TSC) {
            flags.push("Deny TSC");
        }
        if self.contains(Flag::FL_LOCK_PERSONALITY) {
            flags.push("Lock Personality");
        }

        flags.sort();
        write!(f, "{}", flags.join(", "))
    }
}

impl Serialize for Flag {
    #[allow(clippy::cognitive_complexity)]
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        let mut flags: SmallVec<[&str; 64]> = SmallVec::new();
        if self.is_empty() {
            return serializer.collect_seq(flags);
        }
        if self.contains(Flag::FL_UNSHARE_MOUNT) {
            flags.push("unshare-mount");
        }
        if self.contains(Flag::FL_UNSHARE_UTS) {
            flags.push("unshare-uts");
        }
        if self.contains(Flag::FL_UNSHARE_IPC) {
            flags.push("unshare-ipc");
        }
        if self.contains(Flag::FL_UNSHARE_USER) {
            flags.push("unshare-user");
        }
        if self.contains(Flag::FL_UNSHARE_PID) {
            flags.push("unshare-pid");
        }
        if self.contains(Flag::FL_UNSHARE_NET) {
            flags.push("unshare-net");
        }
        if self.contains(Flag::FL_UNSHARE_TIME) {
            flags.push("unshare-time");
        }
        if self.contains(Flag::FL_FAKE_ROOT) {
            flags.push("fake-root");
        }
        if self.contains(Flag::FL_MAP_ROOT) {
            flags.push("map-root");
        }
        if self.contains(Flag::FL_EXIT_WAIT_ALL) {
            flags.push("exit-wait-all");
        }
        if self.contains(Flag::FL_TPE_NEGATE) {
            flags.push("tpe-negate");
        }
        if self.contains(Flag::FL_TPE_ROOT_OWNED) {
            flags.push("tpe-root-owned");
        }
        if self.contains(Flag::FL_TPE_USER_OWNED) {
            flags.push("tpe-user-owned");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_BIND) {
            flags.push("allow-unsafe-bind");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_CHOWN) {
            flags.push("allow-unsafe-chown");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_CPU) {
            flags.push("allow-unsafe-cpu");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_DUMPABLE) {
            flags.push("allow-unsafe-dumpable");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_EXEC) {
            flags.push("allow-unsafe-exec");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_KEYRING) {
            flags.push("allow-unsafe-keyring");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_MEMORY) {
            flags.push("allow-unsafe-memory");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_PKEY) {
            flags.push("allow-unsafe-pkey");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_CAPS) {
            flags.push("allow-unsafe-caps");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_ENV) {
            flags.push("allow-unsafe-env");
        }
        if self.contains(Flag::FL_ALLOW_SAFE_BIND) {
            flags.push("allow-safe-bind");
        }
        if self.contains(Flag::FL_ALLOW_SAFE_KCAPI) {
            flags.push("allow-safe-kcapi");
        }
        if self.contains(Flag::FL_ALLOW_SAFE_SETUID) {
            flags.push("allow-safe-setuid");
        }
        if self.contains(Flag::FL_ALLOW_SAFE_SETGID) {
            flags.push("allow-safe-setgid");
        }
        if self.contains(Flag::FL_ALLOW_UNSUPP_SOCKET) {
            flags.push("allow-unsupp-socket");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_SOCKET) {
            flags.push("allow-unsafe-socket");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_SYSLOG) {
            flags.push("allow-unsafe-syslog");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_MSGSND) {
            flags.push("allow-unsafe-msgsnd");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_PRCTL) {
            flags.push("allow-unsafe-prctl");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_PRLIMIT) {
            flags.push("allow-unsafe-prlimit");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_DEBUG) {
            flags.push("allow-unsafe-debug");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_NOPIE) {
            flags.push("allow-unsafe-nopie");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_STACK) {
            flags.push("allow-unsafe-stack");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_TIME) {
            flags.push("allow-unsafe-time");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_OPEN) {
            flags.push("allow-unsafe-open");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_FILENAME) {
            flags.push("allow-unsafe-filename");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_IOURING) {
            flags.push("allow-unsafe-uring");
        }
        if self.contains(Flag::FL_ALLOW_UNSAFE_MEMFD) {
            flags.push("allow-unsafe-memfd");
        }
        if self.contains(Flag::FL_FORCE_CLOEXEC) {
            flags.push("force-cloexec");
        }
        if self.contains(Flag::FL_DENY_DOTDOT) {
            flags.push("deny-dotdot");
        }
        if self.contains(Flag::FL_DENY_ELF32) {
            flags.push("deny-elf32");
        }
        if self.contains(Flag::FL_DENY_ELF_DYNAMIC) {
            flags.push("deny-elf-dynamic");
        }
        if self.contains(Flag::FL_DENY_ELF_STATIC) {
            flags.push("deny-elf-static");
        }
        if self.contains(Flag::FL_DENY_SCRIPT) {
            flags.push("deny-script");
        }
        if self.contains(Flag::FL_DENY_TSC) {
            flags.push("deny-tsc");
        }
        if self.contains(Flag::FL_LOCK_PERSONALITY) {
            flags.push("lock-personality");
        }

        flags.sort();
        serializer.collect_seq(flags)
    }
}

impl Flag {
    // Returns true if the Flag must be set at startup.
    fn is_startup(self) -> bool {
        self.intersects(
            Self::FL_MAP_ROOT
                | Self::FL_FAKE_ROOT
                | Self::FL_EXIT_WAIT_ALL
                | Self::FL_ALLOW_UNSAFE_BIND
                | Self::FL_ALLOW_UNSAFE_CPU
                | Self::FL_ALLOW_UNSAFE_DUMPABLE
                | Self::FL_ALLOW_UNSAFE_EXEC
                | Self::FL_ALLOW_UNSAFE_KEYRING
                | Self::FL_ALLOW_UNSAFE_MEMORY
                | Self::FL_ALLOW_UNSAFE_PKEY
                | Self::FL_ALLOW_UNSAFE_CAPS
                | Self::FL_ALLOW_UNSAFE_CHOWN
                | Self::FL_ALLOW_UNSAFE_ENV
                | Self::FL_ALLOW_SAFE_BIND
                | Self::FL_ALLOW_SAFE_SETUID
                | Self::FL_ALLOW_SAFE_SETGID
                | Self::FL_ALLOW_UNSAFE_MSGSND
                | Self::FL_ALLOW_UNSAFE_SOCKET
                | Self::FL_ALLOW_UNSAFE_SYSLOG
                | Self::FL_ALLOW_UNSAFE_PRCTL
                | Self::FL_ALLOW_UNSAFE_PRLIMIT
                | Self::FL_ALLOW_UNSAFE_DEBUG
                | Self::FL_ALLOW_UNSAFE_TIME
                | Self::FL_ALLOW_UNSAFE_IOURING
                | Self::FL_DENY_TSC
                | Self::FL_LOCK_PERSONALITY,
        )
    }

    fn ns_from_str(value: &str, unsafe_: bool) -> Result<Self, Errno> {
        let mut flags = Flag::empty();
        for flag in value.split(',') {
            // Let's be as lax as possible but not more.
            let flag = flag.trim();
            if flag.is_empty() {
                continue;
            }
            flags |= match flag.to_ascii_lowercase().as_str() {
                "mount" if unsafe_ => Flag::FL_ALLOW_UNSAFE_UNSHARE_MOUNT,
                "uts" if unsafe_ => Flag::FL_ALLOW_UNSAFE_UNSHARE_UTS,
                "ipc" if unsafe_ => Flag::FL_ALLOW_UNSAFE_UNSHARE_IPC,
                "user" if unsafe_ => Flag::FL_ALLOW_UNSAFE_UNSHARE_USER,
                "pid" if unsafe_ => Flag::FL_ALLOW_UNSAFE_UNSHARE_PID,
                "net" if unsafe_ => Flag::FL_ALLOW_UNSAFE_UNSHARE_NET,
                "cgroup" if unsafe_ => Flag::FL_ALLOW_UNSAFE_UNSHARE_CGROUP,
                "time" if unsafe_ => Flag::FL_ALLOW_UNSAFE_UNSHARE_TIME,
                "mount" => Flag::FL_UNSHARE_MOUNT,
                "uts" => Flag::FL_UNSHARE_UTS,
                "ipc" => Flag::FL_UNSHARE_IPC,
                "user" => Flag::FL_UNSHARE_USER,
                "pid" => Flag::FL_UNSHARE_PID,
                "net" => Flag::FL_UNSHARE_NET,
                "cgroup" => Flag::FL_UNSHARE_CGROUP,
                "time" => Flag::FL_UNSHARE_TIME,
                _ => return Err(Errno::EINVAL),
            };
        }

        if !flags.is_empty() {
            Ok(flags)
        } else {
            Err(Errno::ENOENT)
        }
    }
}

#[derive(Debug)]
enum AddrParseError {
    Addr(std::net::AddrParseError),
    Cidr(ipnet::AddrParseError),
    Plen(ipnet::PrefixLenError),
}

impl std::error::Error for AddrParseError {}

impl fmt::Display for AddrParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Self::Addr(ref e) => write!(f, "AddrParseError: {e}"),
            Self::Cidr(ref e) => write!(f, "CidrParseError: {e}"),
            Self::Plen(ref e) => write!(f, "PrefixLenError: {e}"),
        }
    }
}

impl From<std::net::AddrParseError> for AddrParseError {
    fn from(err: std::net::AddrParseError) -> Self {
        Self::Addr(err)
    }
}

impl From<ipnet::AddrParseError> for AddrParseError {
    fn from(err: ipnet::AddrParseError) -> Self {
        Self::Cidr(err)
    }
}

impl From<ipnet::PrefixLenError> for AddrParseError {
    fn from(err: ipnet::PrefixLenError) -> Self {
        Self::Plen(err)
    }
}

fn parse_ipnet(ip: &str) -> Result<IpNet, AddrParseError> {
    if memchr::memchr(b'/', ip.as_bytes()).is_some() {
        Ok(ip.parse::<IpNet>()?)
    } else if memchr::memchr(b':', ip.as_bytes()).is_some() {
        Ok(IpNet::from(Ipv6Net::new(ip.parse::<Ipv6Addr>()?, 128)?))
    } else {
        Ok(IpNet::from(Ipv4Net::new(ip.parse::<Ipv4Addr>()?, 32)?))
    }
}

/// Represents a network address pattern
#[derive(Debug, Eq, PartialEq)]
pub struct AddressPattern {
    addr: IpNet,
    port: Option<[u16; 2]>,
}

impl fmt::Display for AddressPattern {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self.port {
            None => write!(f, "{}", self.addr),
            Some(ports) if ports[0] == ports[1] => write!(f, "{}!{}", self.addr, ports[0]),
            Some(ports) => write!(f, "{}!{}-{}", self.addr, ports[0], ports[1]),
        }
    }
}

impl Serialize for AddressPattern {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let mut map = serializer.serialize_map(Some(2))?;
        map.serialize_entry("addr", &format!("{}", self.addr))?;
        match self.port {
            None => {}
            Some(ports) if ports[0] == ports[1] => map.serialize_entry("port", &ports[0])?,
            Some(ports) => map.serialize_entry("port", &ports)?,
        };
        map.end()
    }
}

impl FromStr for AddressPattern {
    type Err = Errno;

    fn from_str(pat: &str) -> Result<Self, Self::Err> {
        let mut split = pat.splitn(2, ['!', '@']);
        if let (Some(addr), Some(port)) = (split.next(), split.next()) {
            let mut split = port.splitn(2, '-');
            if let Some(port0) = split.next() {
                if let Ok(port0) = port0.parse::<u16>() {
                    let port1 = if let Some(port1) = split.next() {
                        port1.parse::<u16>()
                    } else {
                        Ok(port0)
                    };
                    if let Ok(port1) = port1 {
                        if let Ok(addr) = parse_ipnet(addr) {
                            let port = if port0 == PORT_MIN && port1 == PORT_MAX {
                                None
                            } else {
                                Some([port0, port1])
                            };
                            return Ok(Self { addr, port });
                        }
                    }
                }
            }
        }

        Err(Errno::EINVAL)
    }
}

/// Represents a rule action.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
pub enum Action {
    /// Allow system call.
    Allow,
    /// Allow system call and warn.
    Warn,
    /// Deny system call silently.
    Filter,
    /// Deny system call and warn.
    Deny,
    /// Deny system call, warn and stop offending process.
    Stop,
    /// Deny system call, warn and kill offending process.
    Kill,
    /// Warn, and exit Syd immediately with deny errno as exit value.
    Exit,
}

impl FromStr for Action {
    type Err = Errno;

    fn from_str(value: &str) -> Result<Self, Self::Err> {
        Ok(match value.to_ascii_lowercase().as_str() {
            "allow" => Action::Allow,
            "warn" => Action::Warn,
            "filter" => Action::Filter,
            "deny" => Action::Deny,
            "stop" => Action::Stop,
            "kill" => Action::Kill,
            "exit" => Action::Exit,
            _ => return Err(Errno::EINVAL),
        })
    }
}

impl fmt::Display for Action {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            Action::Allow => write!(f, "Allow"),
            Action::Warn => write!(f, "Warn"),
            Action::Filter => write!(f, "Filter"),
            Action::Deny => write!(f, "Deny"),
            Action::Stop => write!(f, "Stop"),
            Action::Kill => write!(f, "Kill"),
            Action::Exit => write!(f, "Exit"),
        }
    }
}

impl Serialize for Action {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        serializer.serialize_str(&self.to_string())
    }
}

impl From<&Captures<'_>> for Action {
    fn from(captures: &Captures) -> Self {
        if let Some(act) = captures.name("act") {
            Action::from_str(act.as_str()).unwrap_or(Action::Deny)
        } else {
            Action::Deny
        }
    }
}

impl Action {
    /// Return true if Action is allowing.
    pub fn is_allowing(self) -> bool {
        matches!(self, Self::Allow | Self::Warn)
    }

    /// Return true if Action is denying.
    pub fn is_denying(self) -> bool {
        !self.is_allowing()
    }

    /// Return true if Action is signaling.
    pub fn is_signaling(self) -> bool {
        matches!(self, Self::Stop | Self::Kill)
    }
}

/// Represents a network address sandboxing rule.
#[derive(Debug, Eq, PartialEq)]
pub struct CidrRule {
    act: Action,
    cap: Capability,
    pat: AddressPattern,
}

/// Represents a glob sandboxing rule.
#[derive(Debug)]
pub struct GlobRule {
    act: Action,
    cap: Capability,
    pat: String,
}

/// Represents a simple sandboxing rule.
#[derive(Debug)]
pub struct Rule(String);

impl CidrRule {
    /// Create a network address sandboxing rule.
    pub fn new(act: Action, cap: Capability, addr: IpNet, port: [u16; 2]) -> Self {
        let port = if port[0] == PORT_MIN && port[1] == PORT_MAX {
            None
        } else {
            Some(port)
        };
        Self {
            act,
            cap,
            pat: AddressPattern { addr, port },
        }
    }
}

impl fmt::Display for CidrRule {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(
            f,
            "Action: {}, Capability: {}, Pattern: {}",
            self.act, self.cap, self.pat
        )
    }
}

impl fmt::Display for GlobRule {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(
            f,
            "Action: {}, Capability: {}, Pattern: {}",
            self.act, self.cap, self.pat
        )
    }
}

impl fmt::Display for Rule {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "Pattern: {}", self.0)
    }
}

impl Serialize for CidrRule {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        let mut state = serializer.serialize_struct("cidr", 3)?;
        state.serialize_field("act", &self.act)?;
        state.serialize_field("cap", &self.cap)?;
        state.serialize_field("pat", &self.pat)?;
        state.end()
    }
}

impl Serialize for GlobRule {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        let mut state = serializer.serialize_struct("glob", 3)?;
        state.serialize_field("act", &self.act)?;
        state.serialize_field("cap", &self.cap)?;
        state.serialize_field("pat", &self.pat)?;
        state.end()
    }
}

impl Serialize for Rule {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        let mut state = serializer.serialize_struct("rule", 1)?;
        state.serialize_field("pat", &self.0)?;
        state.end()
    }
}

// Once the sandbox is locked, there is no going back,
// to efficiently check for that without having to lock
// the sandbox, we use this global atomic.
// true is LockState::Set.
// false is one of Exec or Off.
static LOCKED: AtomicBool = AtomicBool::new(false);

/// Represents the state of the magic command lock.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum LockState {
    /// Lock is off, sandbox commands are allowed.
    Off,
    /// Sandbox commands are only allowed to the syd execve child.
    Exec,
    /// Lock is set, sandbox commands are not allowed.
    Set,
}

impl Serialize for LockState {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        serializer.serialize_str(match self {
            LockState::Exec => "exec",
            LockState::Set => "set",
            LockState::Off => "off",
        })
    }
}

type AclRule = (String, MatchMethod, Action);
type ArrRule = (String, MatchMethod);
type Acl = VecDeque<AclRule>;
type Arr = VecDeque<ArrRule>;

/// Sandbox
#[allow(clippy::disallowed_types)]
pub struct Sandbox {
    /// Sandbox options represented using a set of `Flag` flags.
    pub flags: Flag,

    /// Sandbox state represented using a set of `Capability` flags.
    pub state: Capability,

    /// State of the magic lock.
    /// SAFETY: If None, set to LockState::Set the moment cpid is set.
    pub lock: Option<LockState>,

    // Item and weight capacities for path and address caches.
    pub(crate) cache_path_icap: usize,
    pub(crate) cache_path_wcap: u64,
    pub(crate) cache_addr_icap: usize,
    pub(crate) cache_addr_wcap: u64,

    // [inode,path] map of unix binds
    bind_map: FxHashMap<u64, UnixAddr>,

    /// Process ID of the syd execve child.
    /// SAFETY: This is 0 before the sandbox process has been executed.
    cpid: nix::libc::pid_t,

    /// PID file descriptor of the syd execve child.
    fpid: RawFd,

    /// Change root to this directory on startup.
    pub root: Option<PathBuf>,

    /// Mountpoint for the proc filesystem.
    pub proc: Option<PathBuf>,

    /// Mount propagation flags.
    pub propagation: Option<MsFlags>,

    /// Hostname in UTS namespace.
    pub hostname: String,

    /// Domainname in UTS namespace.
    pub domainname: String,

    /// Timestamp for BOOTTIME in Time namespace.
    pub time: Option<i64>,

    /// Per-process memory limit in bytes for memory sandboxing.
    pub mem_max: u64,

    /// Per-process virtual memory limit in bytes for memory sandboxing.
    pub mem_vm_max: u64,

    /// Pid limit for PID sandboxing.
    pub pid_max: usize,

    /// Umask mode to force, None to disable.
    pub umask: Option<Mode>,

    /// Proxy internal port (defaults to 9050).
    pub proxy_port: u16,

    /// Proxy internal address (defaults to 127.0.0.1).
    pub proxy_addr: IpAddr,

    /// Proxy external port (defaults to 9050).
    pub proxy_ext_port: u16,

    /// Proxy external address (defaults to 127.0.0.1).
    pub proxy_ext_addr: IpAddr,

    /// Default action for Read sandboxing.
    read_act: Action,

    /// Default action for Write sandboxing.
    write_act: Action,

    /// Default action for Stat sandboxing.
    stat_act: Action,

    /// Default action for Exec sandboxing.
    exec_act: Action,

    /// Default action for Ioctl sandboxing.
    ioctl_act: Action,

    /// Default action for Net/Bind sandboxing.
    bind_act: Action,

    /// Default action for Net/Connect sandboxing.
    connect_act: Action,

    /// Default action for Memory sandboxing.
    mem_act: Action,

    /// Default action for PID sandboxing.
    pid_act: Action,

    /// Default action for TPE sandboxing.
    tpe_act: Action,

    /// Integrity force defalt mode.
    force_act: Action,

    /// SegvGuard default mode.
    segvguard_act: Action,

    /// IP block default mode.
    block_act: Action,

    /// Ip blocklists for Ipv4 and Ipv6.
    block_net: (IpRange<Ipv4Net>, IpRange<Ipv6Net>),

    // Set of allowlisted/denylisted ioctl(2) requests.
    // true: deny, false: allow.
    ioctl_set: FxHashMap<u64, bool>,

    // TPE GID
    tpe_gid: Option<Gid>,

    // Vector of safe {U,G}ID transitions.
    // source_{u,g}id->target_{u,g}id
    pub(crate) transit_uids: Vec<(Uid, Uid)>,
    pub(crate) transit_gids: Vec<(Gid, Gid)>,

    // SegvGuard entry expiry timeout.
    segvguard_expiry: Duration,

    // SegvGuard entry suspension timeout.
    segvguard_suspension: Duration,

    // SegvGuard max number of crashes before suspension.
    segvguard_maxcrashes: u8,

    // SegvGuard Lists: map is used for expiry, set is used for suspension.
    segvguard_map_expiry: ExpiringMap<PathBuf, u8>,
    segvguard_map_suspension: ExpiringMap<PathBuf, ()>,

    // Integrity force check map.
    force_map: FxHashMap<PathBuf, (Action, Vec<u8>)>,

    // List of bind mounts.
    bind_mounts: Option<Vec<BindMount>>,

    // List of allowlisted Netlink families.
    pub(crate) netlink_families: NetlinkFamily,

    // List of network address sandboxing rules.
    cidr_rules: VecDeque<CidrRule>,
    // Set of Landlock read rules.
    lock_rules_ro: Option<Vec<PathBuf>>,
    // Set of Landlock write rules.
    lock_rules_rw: Option<Vec<PathBuf>>,

    // Access control lists and filters:
    // read, stat, write, execute,
    // ioctl, network bind, network connect.
    acl_r: Acl,
    arr_r: Arr,
    acl_s: Acl,
    arr_s: Arr,
    acl_w: Acl,
    arr_w: Arr,
    acl_x: Acl,
    arr_x: Arr,
    acl_i: Acl,
    arr_i: Arr,
    acl_nb: Acl,
    arr_nb: Arr,
    acl_nc: Acl,
    arr_nc: Arr,

    // ACL for Append-only.
    acl_append: Arr,
    // ACL for Path masking.
    acl_mask: Arr,
}

/// Sandbox Lock types.
#[derive(Debug)]
pub enum SandboxLock {
    /// Read Lock
    Read,
    /// Upgradable read lock
    UpgradableRead,
    /// Write lock
    Write,
}

/// Sandbox guard to use it practically under a read/write lock.
#[derive(Debug)]
pub enum SandboxGuard<'a> {
    /// Sandbox locked for read
    Read(RwLockReadGuard<'a, Sandbox>),
    /// Sandbox locked for upgradable read
    UpgradableRead(RwLockUpgradableReadGuard<'a, Sandbox>),
    /// Sandbox locked for write
    Write(RwLockWriteGuard<'a, Sandbox>),
}

impl Default for Flag {
    fn default() -> Self {
        Self::empty()
    }
}

impl Default for Capability {
    fn default() -> Self {
        Self::CAP_READ
            | Self::CAP_WRITE
            | Self::CAP_EXEC
            | Self::CAP_STAT
            | Self::CAP_BIND
            | Self::CAP_CONNECT
            | Self::CAP_TPE
    }
}

impl Default for LockState {
    fn default() -> Self {
        Self::Exec
    }
}

impl FromStr for LockState {
    type Err = Errno;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "off" => Ok(Self::Off),
            "on" => Ok(Self::Set),
            "exec" => Ok(Self::Exec),
            _ => Err(Errno::EINVAL),
        }
    }
}

impl<'a> Deref for SandboxGuard<'a> {
    type Target = Sandbox;
    fn deref(&self) -> &Self::Target {
        match self {
            SandboxGuard::Read(guard) => guard,
            SandboxGuard::UpgradableRead(guard) => guard,
            SandboxGuard::Write(guard) => guard,
        }
    }
}

impl<'a> DerefMut for SandboxGuard<'a> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        match self {
            SandboxGuard::Write(guard) => guard,
            _ => panic!("Cannot mutate a read-locked Sandbox!"),
        }
    }
}

impl<'a> SandboxGuard<'a> {
    /// Upgrades an upgradable read lock to a write lock.
    /// This function is a no-op if the lock is a write lock.
    /// Panics if not upgradable.
    pub fn upgrade(self) -> SandboxGuard<'a> {
        match self {
            SandboxGuard::Write(guard) => SandboxGuard::Write(guard),
            SandboxGuard::UpgradableRead(guard) => {
                SandboxGuard::Write(RwLockUpgradableReadGuard::upgrade(guard))
            }
            _ => panic!("Attempted to upgrade a non-upgradable guard!"),
        }
    }

    /// Downgrades a write or upgradable read lock to a read lock or upgradable read lock.
    /// This function is a no-op if the lock is a read lock.
    /// Panics if not applicable.
    pub fn downgrade(self) -> SandboxGuard<'a> {
        match self {
            SandboxGuard::Write(guard) => SandboxGuard::Read(RwLockWriteGuard::downgrade(guard)),
            SandboxGuard::UpgradableRead(guard) => {
                SandboxGuard::Read(RwLockUpgradableReadGuard::downgrade(guard))
            }
            SandboxGuard::Read(guard) => SandboxGuard::Read(guard),
        }
    }
}

impl Default for Sandbox {
    #[allow(clippy::disallowed_methods)]
    #[allow(clippy::disallowed_types)]
    fn default() -> Self {
        #[allow(clippy::cast_sign_loss)]
        #[allow(clippy::decimal_literal_representation)]
        let mut sbox = Sandbox {
            flags: Flag::default(),
            state: Capability::default(),
            lock: None,
            cpid: 0,
            fpid: nix::libc::AT_FDCWD,
            bind_map: FxHashMap::default(),
            cache_path_icap: 1024,
            cache_path_wcap: 36684,
            cache_addr_icap: 4096,
            cache_addr_wcap: 65536,
            proc: Some(PathBuf::from("/proc")),
            root: None,
            propagation: Some(MsFlags::MS_PRIVATE | MsFlags::MS_REC),
            hostname: (getpid().as_raw() as u64).to_name(),
            domainname: format!("syd-{API_VERSION}"),
            time: None,
            read_act: Action::Deny,
            write_act: Action::Deny,
            stat_act: Action::Deny,
            exec_act: Action::Deny,
            ioctl_act: Action::Deny,
            bind_act: Action::Deny,
            connect_act: Action::Deny,
            mem_act: Action::Deny,
            mem_max: 128_u64 * 1024 * 1024,
            mem_vm_max: 0,
            pid_act: Action::Kill,
            pid_max: 128,
            block_act: Action::Deny,
            block_net: (IpRange::new(), IpRange::new()),
            umask: None,
            // Allowlisted ioctls:
            // FIOASYNC, FIOCLEX, FIONBIO, FIONCLEX, FIONREAD,
            // FIOGETOWN, FIOSETOWN, SIOCGPGRP, SIOCSPGRP,
            // GIO_UNIMAP,
            // TCGETA, TCGETS, TCSETA,
            // TCSETAF, TCSETAW,
            // TCSETS, TCSETSF, TCSETSW,
            // TIOCGPGRP, TIOCGSID
            // TCSBRK, TCSBRKP, TIOCCBRK, TIOCSBRK,
            // TCXONC,
            // TIOCINQ, TCFLSH, TIOCOUTQ,
            // FICLONE, FICLONERANGE, FIDEDUPERANGE
            // FS_IOC_GETFLAGS,
            // FIOQSIZE, FIBMAP,
            // FS_IOC_FIEMAP,
            // TIOCGETD,
            //
            // Denylisted ioctls:
            // KDSIGACCEPT, TIOCSETD, TIOCSTI, TIOCCONS and TIOCLINUX.
            // FS_IOC_FSGETXATTR, FS_IOC_FSSETXATTR (SAFETY: xattr restrictions).
            // FS_IOC_SETFLAGS (to deny immutable and append-only flag changes).
            ioctl_set: FxHashMap::from_iter([
                (0x5452, false),
                (0x5451, false),
                (0x5421, false),
                (0x5450, false),
                (0x541b, false),
                (0x8903, false),
                (0x8901, false),
                (0x8904, false),
                (0x8902, false),
                (0x4b66, false),
                (0x5405, false),
                (0x5401, false),
                (0x5406, false),
                (0x5408, false),
                (0x5407, false),
                (0x5402, false),
                (0x5404, false),
                (0x5403, false),
                (0x540f, false),
                (0x5429, false),
                (0x5409, false),
                (0x5425, false),
                (0x5428, false),
                (0x5427, false),
                (0x540a, false),
                (0x541b, false),
                (0x540b, false),
                (0x5411, false),
                (0x40049409, false),
                (0xffffffff40049409, false),
                (0x4020940d, false),
                (0xffffffff4020940d, false),
                (0xc0189436, false),
                (0xffffffffc0189436, false),
                (0x80086601, false),
                (0xffffffff80086601, false),
                (0x5460, false),
                (0x1, false),
                (0xc020660b, false),
                (0xffffffffc020660b, false),
                (0x5424, false),
                (0x4b4e, true),
                (0x5423, true),
                (0x5412, true),
                (0x541c, true),
                (0x541d, true),
                (0x801c581f, true),
                (0xffffffff801c581f, true),
                (0x401c5820, true),
                (0xffffffff401c5820, true),
                (0x40086602, true),
                (0xffffffff40086602, true),
            ]),
            proxy_port: 9050,
            proxy_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
            proxy_ext_port: 9050,
            proxy_ext_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
            tpe_act: Action::Deny,
            tpe_gid: None,
            transit_uids: Vec::new(),
            transit_gids: Vec::new(),
            segvguard_act: Action::Kill,
            segvguard_expiry: SEGVGUARD_EXPIRY,
            segvguard_suspension: SEGVGUARD_SUSPENSION,
            segvguard_maxcrashes: SEGVGUARD_MAXCRASHES,
            segvguard_map_expiry: ExpiringMap::new(),
            segvguard_map_suspension: ExpiringMap::new(),
            force_act: Action::Kill,
            force_map: FxHashMap::default(),
            bind_mounts: None,
            netlink_families: NetlinkFamily::empty(),
            cidr_rules: VecDeque::new(),
            lock_rules_ro: None,
            lock_rules_rw: None,
            acl_r: VecDeque::new(),
            acl_s: VecDeque::new(),
            acl_w: VecDeque::new(),
            acl_x: VecDeque::new(),
            acl_i: VecDeque::new(),
            acl_nb: VecDeque::new(),
            acl_nc: VecDeque::new(),
            arr_r: VecDeque::new(),
            arr_s: VecDeque::new(),
            arr_w: VecDeque::new(),
            arr_x: VecDeque::new(),
            arr_i: VecDeque::new(),
            arr_nb: VecDeque::new(),
            arr_nc: VecDeque::new(),
            acl_append: VecDeque::new(),
            acl_mask: VecDeque::new(),
        };

        // SAFETY: We provide an empty file in place of /proc/cmdline
        // for compatibility rather than denying outright. In any case,
        // syd does not leak the contents of this file to the sandbox
        // process. See: https://gitlab.exherbo.org/sydbox/sydbox/-/issues/106
        // SAFETY: We add a mask rule here rather than checking it with a
        // hardcoded clause so as to give the user a chance allow access
        // to /proc/cmdline using "mask-/proc/cmdline" should there be a
        // need to pass boot parameters into the sandbox.
        sbox.rule_add_mask("/proc/cmdline")
            .expect("mask /proc/cmdline");

        // SAFETY: We provide an empty file in place of /{dev,proc}/kmsg
        // for convenience rather than denying outright. In any case Syd
        // does not leak kernel log information to the sandbox process.
        // Without this rule in place, the user is going to get a
        // "Function not implemented" error on dmesg(1) as it fallsback
        // to the syslog(2) system call if /{dev,proc}/kmsg is not
        // available and Syd denies this system call.
        // Again, these rules may be removed from Syd using e.g.
        // "mask-/proc/kmsg". This is necessary when containing a
        // program that interacts with kernel's log buffer such as
        // syslogd.
        sbox.rule_add_mask("/dev/kmsg").expect("mask /dev/kmsg");
        sbox.rule_add_mask("/proc/kmsg").expect("mask /proc/kmsg");

        // SAFETY: We allow /dev/null for write and /proc for read by
        // default in the Landlock sandbox, because Syd is included in
        // the Landlock sandbox and Syd requires access to this file to
        // function correctly.
        sbox.rule_add_glob(Action::Allow, Capability::CAP_LOCK_RO, "/proc")
            .expect("allow/lock/read+/proc");
        sbox.rule_add_glob(Action::Allow, Capability::CAP_LOCK_RW, "/dev/null")
            .expect("allow/lock/write+/dev/null");

        sbox
    }
}

impl fmt::Display for Sandbox {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        writeln!(f, "Syd:")?;
        writeln!(f, "  Process ID: {}", self.cpid)?;
        writeln!(f, "  Lock: {:?}", self.lock)?;
        writeln!(f, "  Capabilities: {}", self.state)?;
        writeln!(f, "  Options: {}", self.flags)?;

        #[allow(clippy::cast_possible_truncation)]
        let mem_max = human_size(self.mem_max as usize);
        #[allow(clippy::cast_possible_truncation)]
        let mem_vm_max = human_size(self.mem_vm_max as usize);
        writeln!(f, "  Memory Max: {mem_max}")?;
        writeln!(f, "  Virtual Memory Max: {mem_vm_max}")?;

        writeln!(f, "  Pid Max: {}", self.pid_max)?;
        writeln!(f, "  SegvGuard Max Crashes: {}", self.segvguard_maxcrashes)?;
        writeln!(
            f,
            "  SegvGuard Expiry: {} seconds",
            self.segvguard_expiry.as_secs()
        )?;
        writeln!(
            f,
            "  SegvGuard Suspension: {} seconds",
            self.segvguard_suspension.as_secs()
        )?;
        writeln!(
            f,
            "  Allowed UID Transitions: (total: {}, source -> target)",
            self.transit_uids.len()
        )?;
        for (source_uid, target_uid) in &self.transit_uids {
            writeln!(f, "    - {source_uid} -> {target_uid}")?;
        }
        writeln!(
            f,
            "  Allowed GID Transitions: (total: {}, source -> target)",
            self.transit_gids.len()
        )?;
        for (source_gid, target_gid) in &self.transit_gids {
            writeln!(f, "    - {source_gid} -> {target_gid}")?;
        }

        let len4 = self.block_net.0.iter().count();
        let len6 = self.block_net.1.iter().count();
        let lall = len4.saturating_add(len6);
        writeln!(f, "  IP Blocklist: {len4} IPv4, {len6} IPv6, {lall} total")?;

        let size = self
            .cidr_rules
            .capacity()
            .saturating_mul(std::mem::size_of::<CidrRule>());
        writeln!(
            f,
            "  Cidr Rules: ({}, total {}, highest precedence first)",
            human_size(size),
            self.cidr_rules.len()
        )?;
        for (idx, rule) in self.cidr_rules.iter().enumerate() {
            // rev() because last matching rule wins.
            let idx = idx.saturating_add(1);
            writeln!(f, "    {idx}. {rule}")?;
        }

        let glob_rules = self.glob_rules();
        let size = glob_rules
            .capacity()
            .saturating_mul(std::mem::size_of::<GlobRule>());
        writeln!(
            f,
            "  Glob Rules: ({}, total {}, highest precedence first)",
            human_size(size),
            glob_rules.len()
        )?;
        for (idx, rule) in glob_rules.iter().enumerate() {
            let idx = idx.saturating_add(1);
            writeln!(f, "    {idx}. {rule}")?;
        }

        let size = self
            .acl_append
            .capacity()
            .saturating_mul(std::mem::size_of::<AclRule>());
        writeln!(
            f,
            "  Append-only Rules: ({}, total {})",
            human_size(size),
            self.acl_append.len()
        )?;
        for (idx, (rule, _)) in self.acl_append.iter().enumerate() {
            let idx = idx.saturating_add(1);
            writeln!(f, "    {idx}. {rule}")?;
        }

        let size = self
            .acl_mask
            .capacity()
            .saturating_mul(std::mem::size_of::<AclRule>());
        writeln!(
            f,
            "  Mask Rules: ({}, total {})",
            human_size(size),
            self.acl_mask.len()
        )?;
        for (idx, (rule, _)) in self.acl_mask.iter().enumerate() {
            let idx = idx.saturating_add(1);
            writeln!(f, "    {idx}. {rule}")?;
        }

        let mut force_rules: Vec<_> = self.force_map.iter().collect();
        force_rules.sort_by_key(|&(k, _)| k); // Sort by path keys for consistent ordering.
        writeln!(
            f,
            "  Force Rules: (total {}, default action: {})",
            force_rules.len(),
            self.force_act,
        )?;
        for (idx, (k, v)) in force_rules.iter().enumerate() {
            let idx = idx.saturating_add(1);
            let (force, bytes) = v;
            let hash = bytes.to_lower_hex_string();
            let path = k.to_string_lossy();
            writeln!(
                f,
                "    {idx}. Action: {force}, Checksum: {hash}, Path: {path}"
            )?;
        }

        Ok(())
    }
}

impl fmt::Debug for Sandbox {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("Sandbox")
            .field("flags", &self.flags)
            .field("state", &self.state)
            .field("lock", &self.lock)
            .field("cpid", &self.cpid)
            .field("fpid", &self.fpid)
            .field("root", &self.root)
            .field("proc", &self.proc)
            .field("default_read", &self.read_act)
            .field("default_write", &self.write_act)
            .field("default_stat", &self.stat_act)
            .field("default_exec", &self.exec_act)
            .field("default_ioctl", &self.ioctl_act)
            .field("default_net_bind", &self.bind_act)
            .field("default_net_connect", &self.connect_act)
            .field("default_mem", &self.mem_act)
            .field("default_pid", &self.pid_act)
            .field("default_tpe", &self.tpe_act)
            .field("default_force", &self.force_act)
            .field("default_segvguard", &self.segvguard_act)
            .field("propagation", &self.propagation)
            .field("hostname", &self.hostname)
            .field("domainname", &self.domainname)
            .field("mem_max", &self.mem_max)
            .field("mem_vm_max", &self.mem_vm_max)
            .field("pid_max", &self.pid_max)
            .field("umask", &self.umask)
            .field("transit_uids", &self.transit_uids)
            .field("transit_gids", &self.transit_gids)
            .field("segvguard_expiry", &self.segvguard_expiry.as_secs())
            .field("segvguard_suspension", &self.segvguard_suspension.as_secs())
            .field("segvguard_maxcrashes", &self.segvguard_maxcrashes)
            //.field("segvguard_map_expiry", &self.segvguard_map_expiry) // skipped
            //.field("segvguard_map_suspension", &self.segvguard_map_suspension) // skipped
            .field("force_map", &self.force_map)
            .field("bind_mounts", &self.bind_mounts)
            .field("cidr_rules", &self.cidr_rules)
            .field("glob_rules", &self.glob_rules())
            .finish()
    }
}

impl Serialize for Sandbox {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        let mut map = serializer.serialize_map(None)?;

        map.serialize_entry("flags", &self.flags)?;
        map.serialize_entry("state", &self.state)?;
        map.serialize_entry("lock", &self.lock)?;
        map.serialize_entry("cpid", &self.cpid)?;
        map.serialize_entry("default_read", &self.read_act)?;
        map.serialize_entry("default_write", &self.write_act)?;
        map.serialize_entry("default_stat", &self.stat_act)?;
        map.serialize_entry("default_exec", &self.exec_act)?;
        map.serialize_entry("default_ioctl", &self.ioctl_act)?;
        map.serialize_entry("default_net_bind", &self.bind_act)?;
        map.serialize_entry("default_net_connect", &self.connect_act)?;
        map.serialize_entry("default_mem", &self.mem_act)?;
        map.serialize_entry("default_pid", &self.pid_act)?;
        map.serialize_entry("default_tpe", &self.tpe_act)?;
        map.serialize_entry("default_force", &self.force_act)?;
        map.serialize_entry("default_segvguard", &self.segvguard_act)?;
        map.serialize_entry("default_block", &self.block_act)?;
        map.serialize_entry("mem_max", &self.mem_max)?;
        map.serialize_entry("mem_vm_max", &self.mem_vm_max)?;
        map.serialize_entry("pid_max", &self.pid_max)?;
        map.serialize_entry("segvguard_expiry", &self.segvguard_expiry.as_secs())?;
        map.serialize_entry("segvguard_suspension", &self.segvguard_suspension.as_secs())?;
        map.serialize_entry("segvguard_maxcrashes", &self.segvguard_maxcrashes)?;
        map.serialize_entry(
            "transit_uids",
            &self
                .transit_uids
                .iter()
                .map(|(src, dst)| (src.as_raw(), dst.as_raw()))
                .collect::<Vec<(nix::libc::uid_t, nix::libc::uid_t)>>(),
        )?;
        map.serialize_entry(
            "transit_gids",
            &self
                .transit_gids
                .iter()
                .map(|(src, dst)| (src.as_raw(), dst.as_raw()))
                .collect::<Vec<(nix::libc::gid_t, nix::libc::gid_t)>>(),
        )?;
        map.serialize_entry("cidr_rules", &self.cidr_rules)?;
        map.serialize_entry("glob_rules", &self.glob_rules())?;
        map.serialize_entry(
            "append_rules",
            &self
                .acl_append
                .iter()
                .map(|(p, _)| p.as_str())
                .collect::<Vec<&str>>(),
        )?;
        map.serialize_entry(
            "mask_rules",
            &self
                .acl_mask
                .iter()
                .map(|(p, _)| p.as_str())
                .collect::<Vec<&str>>(),
        )?;

        // Serialize the `force_map` as "force_rules"
        let mut force_rules: Vec<_> = self.force_map.iter().collect();
        force_rules.sort_by_key(|&(k, _)| k); // Sort by path keys for consistent ordering
                                              // FIXME: json! calls unwrap().
        #[allow(clippy::disallowed_methods)]
        let force_rules: Vec<_> = force_rules
            .iter()
            .map(|(k, v)| {
                let (force, bytes) = v;
                serde_json::json!({
                    "pat": k.to_string_lossy(),
                    "sha": bytes.to_lower_hex_string(),
                    "act": force
                })
            })
            .collect();
        map.serialize_entry("force_rules", &force_rules)?;

        map.end()
    }
}

#[cfg(feature = "oci")]
impl TryFrom<&Spec> for Sandbox {
    type Error = crate::err::SydError;

    /// Create a sandbox using saved config /.oci.syd-3.
    /// If the file does not exist, parse the oci profile.
    fn try_from(_spec: &Spec) -> Result<Self, Self::Error> {
        // Initialize sandbox to default state.
        let mut sandbox = Self::default();

        // SAFETY: Let the container engine declare capabilities.
        sandbox.flags.insert(Flag::FL_ALLOW_UNSAFE_CAPS);

        // Parse the user specified configuration file.
        // Parse the hardcoded OCI profile if no user config was specified.
        let path = Path::new("/.oci.syd-3");
        if path_exists(path).is_ok() {
            sandbox.parse_config_file(path)?;
            info!("ctx": "oci", "op": "load_config");
        } else {
            sandbox.parse_profile("oci")?;
            info!("ctx": "oci", "op": "load_profile", "profile": "oci");
        }

        Ok(sandbox)
    }
}

impl Sandbox {
    /// Parses a configuration from a given file-like object and applies its configuration to the sandbox.
    ///
    /// This function reads from the given file-like object line by line. It skips lines that are either
    /// empty or start with a '#' (treated as comments). For each valid line, it applies its
    /// configuration to the provided sandbox.
    ///
    /// # Arguments
    ///
    /// * `file` - A file-like object to read the configuration from. This can be any type that
    ///            implements the `Read` and `BufRead` traits.
    /// * `path` - Path name of the file, must be an absolute path and have the file extension ".syd-3".
    /// * `imap` - A FxHashSet of file information to keep track of included files to prevent loops.
    ///
    /// # Returns
    ///
    /// * A Result indicating the success or failure of the operation.
    ///
    /// # Errors
    ///
    /// This function will return an error if:
    /// * There's an error reading a line from the file.
    /// * There's an issue in parsing and applying a configuration line to the sandbox.
    #[allow(clippy::cognitive_complexity)]
    pub fn parse_config<F: Read + BufRead, P: AsRef<Path>>(
        &mut self,
        mut file: F,
        path: P,
        imap: &mut FxHashSet<FileInformation>,
    ) -> SydResult<()> {
        if path.as_ref().is_relative() {
            return Err(Errno::EBADF.into());
        }
        let name = path.as_ref().to_string_lossy().to_string();
        let load = name == "/dev/syd/load";
        let fext = format!(".syd-{API_VERSION}");
        if !load && !name.ends_with(&fext) {
            return Err(Errno::EOPNOTSUPP.into());
        }
        let mut line = vec![0; LINE_MAX];
        let mut temp = Vec::new();
        let mut line_count = 1usize;

        loop {
            let bytes_read = file.read(&mut line[..])?;
            if bytes_read == 0 {
                break; // End of file reached.
            }

            if !line.iter().take(bytes_read).any(|&b| b == b'\n') {
                // If no newline is found in the current chunk and we're
                // reading from a file like /dev/zero, return an error
                // indicating the line count at which this was detected.
                return Err(Errno::ENAMETOOLONG.into());
            }
            temp.extend_from_slice(&line[..bytes_read]);

            while let Some(pos) = temp.iter().position(|&b| b == b'\n') {
                let line = &temp[..pos]; // excludes the \n character.
                let line = std::str::from_utf8(line)?;

                if line.trim_start().starts_with('#') {
                    /* Comment: do nothing */
                } else if line.trim().is_empty() {
                    /* Blank line: do nothing */
                } else if self.locked() {
                    // SAFETY: To be consistent with the way we handle
                    // consequent -m CLI arguments, we check for sandbox
                    // lock before each sandbox.config() call.
                    return Err(Errno::EBUSY.into());
                } else if let Some(inc) = line.strip_prefix("include_profile ") {
                    // Handle include_profile directive.

                    // Shell expand the include profile name.
                    let inc = shellexpand::full(inc)?;

                    // Finally, parse the profile.
                    self.parse_profile(&inc)?;
                } else if let Some(inc) = line.strip_prefix("include ") {
                    // Handle include directive.

                    // SAFETY: We do not parse include directives when loading from file descriptors.
                    if load {
                        return Err(Errno::EBUSY.into());
                    }

                    // Shell expand the include path.
                    let inc = shellexpand::full(inc)?.as_ref().to_string();

                    // Handle relative files according to the directory of the current file.
                    #[allow(clippy::disallowed_types)]
                    let mut inc = PathBuf::from(inc);
                    if inc.is_relative() {
                        #[allow(clippy::disallowed_methods)]
                        let dir = path.as_ref().parent().unwrap_or_else(|| Path::new("/"));
                        inc = dir.join(inc);
                    }

                    // Query file metadata.
                    let info = FileInformation::from_path(&inc)?;

                    // Check for include loops and secure file permissions.
                    let permissions = Mode::from_bits_truncate(info.mode.into());
                    if !imap.insert(info) {
                        return Err(Errno::ELOOP.into());
                    }
                    if permissions.contains(Mode::S_IWGRP | Mode::S_IWOTH) {
                        return Err(Errno::EACCES.into());
                    }

                    // Check for file extension.
                    // Currently we have three supported extensions:
                    // 1. .syd-3
                    // 2. .ipset, .netset
                    // ipset and netset files are list of IP addresses
                    // where lines starting with the '#' character are
                    // ignored.
                    let inc_ext = inc.extension().ok_or(Errno::EOPNOTSUPP)?;
                    let syd_ext = OsString::from(format!("syd-{API_VERSION}"));
                    let ips_ext = Path::new("ipset");
                    let net_ext = Path::new("netset");
                    if inc_ext == syd_ext {
                        // Parse as Syd configuration file.
                        let file = File::open(&inc)?;
                        self.parse_config(BufReader::new(file), inc, imap)?;
                    } else if inc_ext == ips_ext || inc_ext == net_ext {
                        // Parse as IPSet.
                        let file = File::open(&inc)?;
                        self.parse_netset(BufReader::new(file))?;
                    } else {
                        return Err(Errno::EOPNOTSUPP.into());
                    }
                } else {
                    let line = shellexpand::full(line)?;
                    self.config(&line)?;
                }
                // Remove the processed line from temp storage.
                temp.drain(..=pos);
                line_count = line_count.saturating_add(1); // Increment line count after processing each line.
            }
        }

        Ok(())
    }

    /// Parses a configuration file and applies its configuration to the sandbox.
    ///
    /// This function reads the given configuration file line by line. It skips lines that are either
    /// empty or start with a '#' (treated as comments). For each valid line, it applies its
    /// configuration to the provided sandbox.
    ///
    /// # Arguments
    ///
    /// * `path` - A reference to the path of the configuration file. This can be any type that
    ///            implements the `AsRef<Path>` trait.
    ///
    /// # Returns
    ///
    /// * A Result indicating the success or failure of the operation.
    ///
    /// # Errors
    ///
    /// This function will return an error if:
    /// * There's an issue in opening the configuration file.
    /// * There's an error reading a line from the file.
    /// * There's an issue in parsing and applying a configuration line to the sandbox.
    ///
    /// # Examples
    ///
    /// ```no_run
    /// use syd::sandbox::Sandbox;
    ///
    /// let path = "/path/to/config/file";
    /// let mut sandbox = Sandbox::new();
    /// sandbox
    ///     .parse_config_file(&path)
    ///     .expect("Failed to parse configuration file");
    /// ```
    pub fn parse_config_file<P: AsRef<Path>>(&mut self, path: P) -> SydResult<()> {
        let path = path.as_ref().canonicalize()?;
        let file = BufReader::new(File::open(&path)?);
        let mut imap = FxHashSet::default();
        self.parse_config(file, path, &mut imap)
    }

    /// Parses the given profile and applies its configuration to the sandbox.
    ///
    /// This function supports multiple predefined profiles such as "paludis", "noipv4", "noipv6", and "user".
    /// Each profile corresponds to a set of configuration lines which are applied to the sandbox.
    /// The "user" profile includes both static configurations and dynamic ones that depend on the
    /// environment and the existence of a user-specific configuration file.
    ///
    /// # Arguments
    ///
    /// * `name` - A string slice that holds the name of the profile to be parsed.
    /// * `sandbox` - A mutable reference to the sandbox where the profile configurations will be applied.
    ///
    /// # Returns
    ///
    /// * A Result indicating the success or failure of the operation.
    ///
    /// # Errors
    ///
    /// This function will return an error if:
    /// * The profile name is invalid.
    /// * There's an issue in parsing the configuration lines.
    /// * There's an issue in reading or parsing the user-specific configuration file for the "user" profile.
    #[allow(clippy::cognitive_complexity)]
    pub fn parse_profile(&mut self, name: &str) -> SydResult<()> {
        // Inner function to handle repetitive logic of applying configurations
        fn apply_config(sandbox: &mut Sandbox, profile: &[&str]) -> SydResult<()> {
            for line in profile {
                sandbox.config(line)?;
            }
            Ok(())
        }

        match name {
            "container" => apply_config(self, PROFILE_CONTAINER),
            "immutable" => apply_config(self, PROFILE_IMMUTABLE),
            "landlock" => apply_config(self, PROFILE_LANDLOCK),
            "linux" => apply_config(self, PROFILE_LINUX),
            "kvm" => apply_config(self, PROFILE_KVM),
            "kvm_native" => apply_config(self, PROFILE_KVM_NATIVE),
            "tty" => apply_config(self, PROFILE_TTY),
            "paludis" => apply_config(self, PROFILE_PALUDIS),
            "pandora" => apply_config(self, PROFILE_PANDORA),
            "noipv4" => apply_config(self, PROFILE_NOIPV4),
            "noipv6" => apply_config(self, PROFILE_NOIPV6),
            "privileged" => apply_config(self, PROFILE_PRIVILEGED),
            "core" => apply_config(self, PROFILE_CORE),
            "debug" => apply_config(self, PROFILE_DEBUG),
            "noexe" => apply_config(self, PROFILE_NOEXE),
            "nomem" => apply_config(self, PROFILE_NOMEM),
            "nopie" => apply_config(self, PROFILE_NOPIE),
            "silent" => apply_config(self, PROFILE_SILENT),
            "off" => apply_config(self, PROFILE_OFF),
            "lib" => apply_config(self, PROFILE_LIB),
            "oci" => apply_config(self, PROFILE_OCI),
            "trace" => apply_config(self, PROFILE_TRACE),
            "user" => {
                // Step 1: Apply static user configuration defined at compile-time.
                apply_config(self, PROFILE_USER)?;

                // Step 2: Apply dynamic, user-specific configuration.
                let uid = Uid::effective();
                let name = crate::get_user_name(uid);
                let home = crate::get_user_home(&name);

                // Save the user from some annoying warnings.
                if env::var("GIT_CEILING_DIRECTORIES").is_err() {
                    env::set_var("GIT_CEILING_DIRECTORIES", &home);
                }

                // /home
                // We allow read(/home/user) but not write(/home/user),
                // read|write(/home/user/**) is ok, i.e. the user can
                // not delete their home directory under the sandbox
                // which is a nice and funny protection.
                self.config(&format!("allow/lock/write+{home}"))?;
                self.config(&format!("allow/read,stat+{home}/***"))?;
                self.config(&format!("allow/exec,write+{home}/**"))?;
                self.config(&format!("allow/net/bind+{home}/**"))?;
                self.config(&format!("allow/net/connect+{home}/**"))?;
                // /run/user/uid
                self.config(&format!("allow/lock/write+/run/user/{uid}"))?;
                self.config(&format!("allow/read,stat+/run/user/{uid}/***"))?;
                self.config(&format!("allow/write+/run/user/{uid}/**"))?;
                self.config(&format!("allow/net/connect+/run/user/{uid}/**"))?;

                // Step 3: Parse the system & user configuration file if it exists.
                #[allow(clippy::disallowed_types)]
                let rc = vec![
                    PathBuf::from(PATH_ETC).join(format!("user.syd-{API_VERSION}")),
                    Path::new(&home).join(format!(".user.syd-{API_VERSION}")),
                ];
                for p in rc {
                    if self.locked() {
                        info!("ctx": "config", "op": "parse_profile",
                            "errno": Errno::EAGAIN as i32, "error": "sandbox is locked",
                            "path": mask_path(&p));
                    } else if path_exists(&p).is_ok() {
                        self.parse_config_file(&p)?;
                    }
                }
                Ok(())
            }
            name => {
                // Parse one character at a time.
                let mut ok = false;
                for c in name.chars() {
                    self.parse_profile(match c {
                        '4' => "noipv6",
                        '6' => "noipv4",
                        'C' => "core",
                        'D' => "debug",
                        'M' => "nomem",
                        'P' => "nopie",
                        'X' => "noexe",
                        'c' => "container",
                        'i' => "immutable",
                        'l' => "landlock",
                        'p' => "privileged",
                        's' => "silent",
                        'u' => "user",
                        _ => return Err(Errno::EINVAL.into()),
                    })?;
                    ok = true;
                }

                if ok {
                    Ok(())
                } else {
                    Err(Errno::EINVAL.into())
                }
            }
        }
    }

    /// Parses an ip set file with extensions: .ipset & .netset.
    pub fn parse_netset<F: Read + BufRead>(&mut self, mut file: F) -> SydResult<()> {
        let mut line = vec![0; LINE_MAX];
        let mut temp = Vec::new();
        let mut line_count = 1usize;

        // SAFETY: Check for sandbox lock.
        if self.locked() {
            return Err(Errno::EBUSY.into());
        }

        loop {
            let bytes_read = file.read(&mut line[..])?;
            if bytes_read == 0 {
                break; // End of file reached.
            }

            if !line.iter().take(bytes_read).any(|&b| b == b'\n') {
                // If no newline is found in the current chunk and we're
                // reading from a file like /dev/zero, return an error
                // indicating the line count at which this was detected.
                return Err(Errno::ENAMETOOLONG.into());
            }
            temp.extend_from_slice(&line[..bytes_read]);

            while let Some(pos) = temp.iter().position(|&b| b == b'\n') {
                let line = &temp[..pos]; // excludes the \n character.
                let line = std::str::from_utf8(line)?;
                let line = line.trim();
                if line.is_empty() || line.starts_with('#') {
                    /* Blank line or comment: do nothing. */
                } else {
                    match parse_ipnet(line) {
                        Ok(IpNet::V4(addr)) => {
                            self.block_net.0.add(addr);
                        }
                        Ok(IpNet::V6(addr)) => {
                            self.block_net.1.add(addr);
                        }
                        Err(err) => panic!("Invalid IP network `{line}': {err}"),
                    };
                }
                // Remove the processed line from temp storage.
                temp.drain(..=pos);
                line_count = line_count.saturating_add(1); // Increment line count after processing each line.
            }
        }

        Ok(())
    }

    /// Configures the sandbox using a specified command.
    ///
    /// This method provides a central point for configuring the sandbox. It interprets and
    /// processes a variety of commands to adjust the sandbox's state, manage its tracing,
    /// handle regex-based configurations, and more.
    ///
    /// # Arguments
    ///
    /// * `command` - A string slice that represents the command to be executed.
    ///
    /// # Returns
    ///
    /// * A `Result` that indicates the success or failure of the operation. In the event of a
    ///   failure, it returns an appropriate error from the `Errno` enum.
    ///
    /// # Commands
    ///
    /// - If the command is empty or matches the API version, it simply returns `Ok(())`.
    /// - If the command starts with "lock", it attempts to set the sandbox's lock state.
    /// - If the command matches one of the supported commands, it applies the command to the sandbox.
    ///   See the ["Configuration" section in the README.md file](https://crates.io/crates/syd#configuration)
    ///   for a list of supported commands.
    /// - If none of the above conditions are met, it returns an error indicating invalid input.
    ///
    /// # Examples
    ///
    /// ```
    /// use syd::sandbox::Sandbox;
    ///
    /// let mut sandbox = Sandbox::new();
    /// sandbox
    ///     .config("lock:on")
    ///     .expect("Failed to lock the sandbox");
    /// ```
    #[allow(clippy::cognitive_complexity)]
    pub fn config(&mut self, command: &str) -> Result<(), Errno> {
        match self.config_unchecked(command) {
            Ok(()) => {
                info!("ctx": "config", "op": "parse_config",
                    "cfg": command);
                Ok(())
            }
            Err(errno) => {
                info!("ctx": "config", "op": "parse_config",
                    "cfg": command, "errno": errno as i32);
                Err(errno)
            }
        }
    }

    #[allow(clippy::cognitive_complexity)]
    fn config_unchecked(&mut self, command: &str) -> Result<(), Errno> {
        if command.is_empty() || command == API_VERSION {
            Ok(())
        } else if matches!(command, "l" | "lock") {
            // Shorthands for lock:on.
            self.lock(LockState::Set)
        } else if command == "reset" {
            self.reset()
        } else if command == "stat" {
            eprint!("{self}");
            Ok(())
        } else if let Some(name) = command.strip_prefix("include_profile ") {
            // Handle include_profile directive here as well for convenience.
            // This way, we can include profile from within other profiles.
            self.parse_profile(name).or(Err(Errno::ENOENT))
        } else if let Some(state) = command.strip_prefix("lock:") {
            self.lock(LockState::from_str(state)?)
        } else if let Some(value) = command.strip_prefix("time:") {
            self.time = Some(value.parse::<i64>().or(Err(Errno::EINVAL))?);
            Ok(())
        } else if let Some(command) = command.strip_prefix("cache/") {
            self.handle_cache_config(command)
        } else if let Some(command) = command.strip_prefix("cmd/") {
            self.handle_sandbox_command(command)
        } else if let Some(command) = command.strip_prefix("sandbox/") {
            self.handle_sandbox_config(command)
        } else if let Some(command) = command.strip_prefix("default/") {
            self.handle_default_config(command)
        } else if let Some(command) = command.strip_prefix("ioctl/") {
            self.handle_ioctl_config(command)
        } else if let Some(command) = command.strip_prefix("mem/") {
            self.handle_mem_config(command)
        } else if let Some(command) = command.strip_prefix("pid/") {
            self.handle_pid_config(command)
        } else if let Some(command) = command.strip_prefix("proxy/") {
            self.handle_proxy_config(command)
        } else if let Some(command) = command.strip_prefix("tpe/") {
            self.handle_tpe_config(command)
        } else if let Some(command) = command.strip_prefix("trace/") {
            self.handle_trace_config(command)
        } else if let Some(command) = command.strip_prefix("unshare/") {
            self.handle_unshare_config(command)
        } else if let Some(command) = command.strip_prefix("name/") {
            self.handle_name_config(command)
        } else if let Some(command) = command.strip_prefix("append") {
            self.handle_append_rules(command)
        } else if let Some(command) = command.strip_prefix("block") {
            self.handle_block_rules(command)
        } else if let Some(command) = command.strip_prefix("mask") {
            self.handle_mask_rules(command)
        } else if let Some(command) = command.strip_prefix("root") {
            self.handle_root_config(command)
        } else if let Some(captures) = RE_BIND.captures(command) {
            self.handle_bind_config(&captures)
        } else if let Some(command) = command.strip_prefix("segvguard/") {
            self.handle_segvguard_config(command)
        } else if let Some(captures) = RE_FORCE.captures(command) {
            self.handle_force_rule_config(&captures)
        } else if let Some(captures) = RE_SETID_0.captures(command) {
            self.handle_setid_rule_config(&captures)
        } else if let Some(captures) = RE_SETID_1.captures(command) {
            self.handle_setid_rule_config(&captures)
        } else if let Some(captures) = RE_NETALIAS.captures(command) {
            let alias = captures["alias"].to_ascii_lowercase();
            let command = captures["command"].to_ascii_lowercase();
            self.handle_netalias_config(&command, &alias)
        } else if let Some(captures) = RE_RULE_NETLINK.captures(command) {
            self.handle_netlink_config(&captures)
        } else if let Some(captures) = RE_RULE.captures(command) {
            self.handle_rule_config(&captures)
        } else {
            Err(Errno::EINVAL)
        }
    }

    pub(crate) fn add_bind(&mut self, fd: &OwnedFd, path: &SmallPathBuf) -> Result<(), Errno> {
        // Convert path to unix address.
        let addr = UnixAddr::new(path)?;

        // Get socket inode.
        let inode =
            retry_on_eintr(|| fstatx(fd.as_raw_fd(), STATX_INO)).map(|statx| statx.stx_ino)?;

        // Record bind address.
        self.bind_map.insert(inode, addr);

        // Cleanup bind map from unused inodes as necessary.
        if self.bind_map.len() > 128 {
            let inodes = proc_unix_get_inodes()?;
            self.bind_map.retain(|inode, _| inodes.contains(inode));
        }

        Ok(())
    }

    pub(crate) fn get_bind(&self, inode: u64) -> Option<&UnixAddr> {
        self.bind_map.get(&inode)
    }

    fn handle_cache_config(&mut self, command: &str) -> Result<(), Errno> {
        if let Some(value) = command.strip_prefix("path/icap:") {
            if self.is_running() {
                return Err(Errno::EBUSY);
            }
            self.cache_path_icap = value.parse::<usize>().or(Err(Errno::EINVAL))?;
        } else if let Some(value) = command.strip_prefix("path/wcap:") {
            if self.is_running() {
                return Err(Errno::EBUSY);
            }
            self.cache_path_wcap = value.parse::<u64>().or(Err(Errno::EINVAL))?;
        } else if let Some(value) = command.strip_prefix("addr/icap:") {
            if self.is_running() {
                return Err(Errno::EBUSY);
            }
            self.cache_addr_icap = value.parse::<usize>().or(Err(Errno::EINVAL))?;
        } else if let Some(value) = command.strip_prefix("addr/wcap:") {
            if self.is_running() {
                return Err(Errno::EBUSY);
            }
            self.cache_addr_wcap = value.parse::<u64>().or(Err(Errno::EINVAL))?;
        } else {
            return Err(Errno::EINVAL);
        }

        Ok(())
    }

    fn handle_netalias_config(&mut self, command: &str, alias: &str) -> Result<(), Errno> {
        if let Some(addr_vec) = MAP_NETALIAS.get(&alias) {
            for addr in addr_vec {
                let c = command.replacen(alias, addr, 1);
                self.config(&c)?;
            }
            Ok(())
        } else {
            // This should never happen,
            // but let's handle it safely anyway.
            Err(Errno::EAFNOSUPPORT)
        }
    }

    fn handle_name_config(&mut self, command: &str) -> Result<(), Errno> {
        if let Some(value) = command.strip_prefix("host:") {
            self.set_hostname(value)?;
        } else if let Some(value) = command.strip_prefix("domain:") {
            self.set_domainname(value)?;
        } else {
            return Err(Errno::EINVAL);
        }
        Ok(())
    }

    fn handle_append_rules(&mut self, command: &str) -> Result<(), Errno> {
        // Check command length is at least 2 parameters.
        if command.len() < 2 {
            return Err(Errno::EINVAL);
        }
        // Check the first character
        match command.chars().nth(0) {
            Some('+') => self.rule_add_append(&command[1..]),
            Some('-') => self.rule_del_append(&command[1..]),
            Some('^') => self.rule_rem_append(&command[1..]),
            _ => Err(Errno::EINVAL),
        }
    }

    fn handle_block_rules(&mut self, command: &str) -> Result<(), Errno> {
        // Check the first character.
        match command.chars().nth(0) {
            Some('+') => self.rule_add_block(&command[1..]),
            Some('-') => self.rule_del_block(&command[1..]),
            Some('^') => self.rule_rem_block(&command[1..]),
            Some('!') => self.rule_agg_block(&command[1..]),
            _ => Err(Errno::EINVAL),
        }
    }

    fn handle_mask_rules(&mut self, command: &str) -> Result<(), Errno> {
        // Check command length is at least 2 parameters.
        if command.len() < 2 {
            return Err(Errno::EINVAL);
        }
        // Check the first character
        match command.chars().nth(0) {
            Some('+') => self.rule_add_mask(&command[1..]),
            Some('-') => self.rule_del_mask(&command[1..]),
            Some('^') => self.rule_rem_mask(&command[1..]),
            _ => Err(Errno::EINVAL),
        }
    }

    fn handle_root_config(&mut self, command: &str) -> Result<(), Errno> {
        if let Some(root) = command.strip_prefix(':') {
            #[allow(clippy::disallowed_types)]
            let root = PathBuf::from(root);
            if root.is_relative()
                || root
                    .components()
                    .any(|p| p == std::path::Component::ParentDir)
            {
                return Err(Errno::EINVAL);
            }
            if self.is_running() {
                return Err(Errno::EBUSY);
            }
            self.root = Some(root.clone());
            self.proc = Some(root.join("proc"));
        } else if let Some(value) = command.strip_prefix("/map:") {
            self.set_flag(Flag::FL_MAP_ROOT, value)?;
        } else if let Some(value) = command.strip_prefix("/fake:") {
            self.set_flag(Flag::FL_FAKE_ROOT, value)?;
        } else {
            return Err(Errno::EINVAL);
        }
        Ok(())
    }

    #[allow(clippy::cognitive_complexity)]
    fn handle_sandbox_config(&mut self, command: &str) -> Result<(), Errno> {
        #[allow(clippy::arithmetic_side_effects)]
        let (caps, state) = match command.chars().last() {
            Some('?') => (Capability::from_str(&command[..command.len() - 1])?, None),
            _ => {
                let mut splits = command.splitn(2, ':');
                (
                    Capability::from_str(splits.next().unwrap_or(""))?,
                    Some(strbool(splits.next().ok_or(Errno::EINVAL)?)?),
                )
            }
        };

        if let Some(state) = state {
            // Setting Capability with :{on,off}.
            if self.is_running() && caps.is_startup() {
                return Err(Errno::EBUSY);
            } else if state {
                self.state.insert(caps);
            } else {
                self.state.remove(caps);
            }
        } else if !self.state.contains(caps) {
            // Querying for Capability with ?.
            return Err(Errno::ENOENT);
        }

        Ok(()) // set|query successful.
    }

    #[allow(clippy::cognitive_complexity)]
    fn handle_sandbox_command(&mut self, command: &str) -> Result<(), Errno> {
        if let Some(command) = command.strip_prefix("exec!") {
            // Splitting the command using the Unit Separator character
            let parts: Vec<&str> = command.split('\x1F').collect();

            // Paranoid checks: Ensure the command and its arguments are not empty
            if parts.is_empty() || parts[0].is_empty() {
                error!("ctx": "config", "op": "check_sandbox_command",
                    "cfg": "cmd/exec", "errno": Errno::EINVAL as i32);
                return Err(Errno::EINVAL);
            }

            let program = parts[0];
            let args = &parts[1..];

            // SAFETY: We're spawning a child outside the sandbox here.
            // We should take some precautions so that the process to be
            // executed has a sane environment. That's why we change the
            // current directory to /, close the standard file
            // descriptors, and execute the process in a new process
            // group.
            let mut command = Command::new(program);
            command
                .args(args)
                //.current_dir("/")
                //.stderr(Stdio::null())
                //.stdout(Stdio::null())
                .stdin(Stdio::null());

            // SAFETY: We must detach from Syd!
            unsafe { command.pre_exec(|| Ok(setsid().map(drop)?)) };

            match command.spawn() {
                Ok(_) => Ok(()),
                Err(error) => {
                    let errstr = error.to_string();
                    let errno = err2no(error);
                    error!("ctx": "config", "op": "execute_sandbox_command", "cfg": "cmd/exec",
                        "errno": errno as i32, "error": errstr,
                        "cmd": program, "args": format!("{args:?}"));
                    Err(errno)
                }
            }
        } else {
            Err(Errno::ENOENT)
        }
    }

    fn handle_default_config(&mut self, command: &str) -> Result<(), Errno> {
        // Split the command into two parts: items and action.
        let mut parts = command.splitn(2, ':');

        let items = parts.next().ok_or(Errno::EINVAL)?;
        let action = Action::from_str(parts.next().ok_or(Errno::EINVAL)?)?;

        for item in items.split(',') {
            match item.trim() {
                "read" => self.read_act = action,
                "write" => self.write_act = action,
                "stat" => self.stat_act = action,
                "exec" => self.exec_act = action,
                "ioctl" => self.ioctl_act = action,
                "force" => self.force_act = action,
                "segvguard" => self.segvguard_act = action,
                "net/bind" => self.bind_act = action,
                "net/connect" => self.connect_act = action,
                "net" => {
                    self.bind_act = action;
                    self.connect_act = action;
                }
                "block" => {
                    if action == Action::Allow {
                        return Err(Errno::EINVAL);
                    }
                    self.block_act = action;
                }
                "mem" => {
                    if action == Action::Allow {
                        return Err(Errno::EINVAL);
                    }
                    self.mem_act = action;
                }
                "pid" => {
                    if action == Action::Allow {
                        return Err(Errno::EINVAL);
                    }
                    self.pid_act = action;
                }
                "tpe" => {
                    if action == Action::Allow {
                        return Err(Errno::EINVAL);
                    }
                    self.tpe_act = action;
                }
                _ => return Err(Errno::EINVAL),
            }
        }

        Ok(())
    }

    fn handle_ioctl_config(&mut self, command: &str) -> Result<(), Errno> {
        if let Some(value) = command.strip_prefix("deny+") {
            let request = str2u64(value)?;
            self.add_ioctl_deny(request);
        } else if let Some(value) = command.strip_prefix("deny-") {
            let request = str2u64(value)?;
            self.del_ioctl(request);
        } else if let Some(value) = command.strip_prefix("allow+") {
            let request = str2u64(value)?;
            self.add_ioctl_allow(request);
        } else if let Some(value) = command.strip_prefix("allow-") {
            let request = str2u64(value)?;
            self.del_ioctl(request);
        } else {
            return Err(Errno::EINVAL);
        }
        Ok(())
    }

    fn handle_mem_config(&mut self, command: &str) -> Result<(), Errno> {
        if let Some(value) = command.strip_prefix("max:") {
            match parse_size::Config::new().with_binary().parse_size(value) {
                Ok(value) => {
                    self.mem_max = value;
                }
                Err(_) => {
                    return Err(Errno::EINVAL);
                }
            }
        } else if let Some(value) = command.strip_prefix("vm_max:") {
            match parse_size::Config::new().with_binary().parse_size(value) {
                Ok(value) => {
                    self.mem_vm_max = value;
                }
                Err(_) => {
                    return Err(Errno::EINVAL);
                }
            }
        } else {
            return Err(Errno::EINVAL);
        }
        Ok(())
    }

    fn handle_pid_config(&mut self, command: &str) -> Result<(), Errno> {
        if let Some(value) = command.strip_prefix("max:") {
            self.pid_max = value.parse::<usize>().or(Err(Errno::EINVAL))?;
        } else {
            return Err(Errno::EINVAL);
        }
        Ok(())
    }

    fn handle_proxy_config(&mut self, command: &str) -> Result<(), Errno> {
        if let Some(value) = command.strip_prefix("port:") {
            self.proxy_port = value.parse::<u16>().or(Err(Errno::EINVAL))?;
        } else if let Some(value) = command.strip_prefix("ext/port:") {
            self.proxy_ext_port = value.parse::<u16>().or(Err(Errno::EINVAL))?;
        } else if let Some(value) = command.strip_prefix("addr:") {
            self.proxy_addr = value.parse::<IpAddr>().or(Err(Errno::EINVAL))?;
        } else if let Some(value) = command.strip_prefix("ext/addr:") {
            self.proxy_ext_addr = value.parse::<IpAddr>().or(Err(Errno::EINVAL))?;
        } else {
            return Err(Errno::EINVAL);
        }
        Ok(())
    }

    fn handle_tpe_config(&mut self, command: &str) -> Result<(), Errno> {
        if let Some(value) = command.strip_prefix("gid:") {
            self.tpe_gid = if value == "none" {
                None
            } else {
                Some(Gid::from_raw(
                    value.parse::<nix::libc::gid_t>().or(Err(Errno::EINVAL))?,
                ))
            };
        } else if let Some(value) = command.strip_prefix("negate:") {
            self.set_flag(Flag::FL_TPE_NEGATE, value)?;
        } else if let Some(value) = command.strip_prefix("root_owned:") {
            self.set_flag(Flag::FL_TPE_ROOT_OWNED, value)?;
        } else if let Some(value) = command.strip_prefix("user_owned:") {
            self.set_flag(Flag::FL_TPE_USER_OWNED, value)?;
        } else {
            return Err(Errno::EINVAL);
        }
        Ok(())
    }

    #[allow(clippy::cognitive_complexity)]
    fn handle_trace_config(&mut self, command: &str) -> Result<(), Errno> {
        if let Some(value) = command.strip_prefix("exit_wait_all:") {
            self.set_flag(Flag::FL_EXIT_WAIT_ALL, value)?;
        } else if let Some(value) = command.strip_prefix("allow_unsafe_bind:") {
            self.set_flag(Flag::FL_ALLOW_UNSAFE_BIND, value)?
        } else if let Some(value) = command.strip_prefix("allow_unsafe_chown:") {
            self.set_flag(Flag::FL_ALLOW_UNSAFE_CHOWN, value)?
        } else if let Some(value) = command.strip_prefix("allow_unsafe_cpu:") {
            self.set_flag(Flag::FL_ALLOW_UNSAFE_CPU, value)?
        } else if let Some(value) = command.strip_prefix("allow_unsafe_dumpable:") {
            self.set_flag(Flag::FL_ALLOW_UNSAFE_DUMPABLE, value)?
        } else if let Some(value) = command.strip_prefix("allow_unsafe_exec:") {
            self.set_flag(Flag::FL_ALLOW_UNSAFE_EXEC, value)?
        } else if let Some(value) = command.strip_prefix("allow_unsafe_keyring:") {
            self.set_flag(Flag::FL_ALLOW_UNSAFE_KEYRING, value)?
        } else if let Some(value) = command.strip_prefix("allow_unsafe_memory:") {
            self.set_flag(Flag::FL_ALLOW_UNSAFE_MEMORY, value)?
        } else if let Some(value) = command.strip_prefix("allow_unsafe_pkey:") {
            self.set_flag(Flag::FL_ALLOW_UNSAFE_PKEY, value)?
        } else if let Some(value) = command.strip_prefix("allow_unsafe_caps:") {
            self.set_flag(Flag::FL_ALLOW_UNSAFE_CAPS, value)?
        } else if let Some(value) = command.strip_prefix("allow_unsafe_env:") {
            self.set_flag(Flag::FL_ALLOW_UNSAFE_ENV, value)?
        } else if let Some(value) = command.strip_prefix("allow_safe_bind:") {
            self.set_flag(Flag::FL_ALLOW_SAFE_BIND, value)?
        } else if let Some(value) = command.strip_prefix("allow_safe_kcapi:") {
            self.set_flag(Flag::FL_ALLOW_SAFE_KCAPI, value)?
        } else if let Some(value) = command.strip_prefix("allow_safe_setuid:") {
            self.set_flag(Flag::FL_ALLOW_SAFE_SETUID, value)?
        } else if let Some(value) = command.strip_prefix("allow_safe_setgid:") {
            self.set_flag(Flag::FL_ALLOW_SAFE_SETGID, value)?
        } else if let Some(value) = command.strip_prefix("allow_unsupp_socket:") {
            self.set_flag(Flag::FL_ALLOW_UNSUPP_SOCKET, value)?
        } else if let Some(value) = command.strip_prefix("allow_unsafe_socket:") {
            self.set_flag(Flag::FL_ALLOW_UNSAFE_SOCKET, value)?
        } else if let Some(value) = command.strip_prefix("allow_unsafe_syslog:") {
            self.set_flag(Flag::FL_ALLOW_UNSAFE_SYSLOG, value)?
        } else if let Some(value) = command.strip_prefix("allow_unsafe_msgsnd:") {
            self.set_flag(Flag::FL_ALLOW_UNSAFE_MSGSND, value)?
        } else if let Some(value) = command.strip_prefix("allow_unsafe_prctl:") {
            self.set_flag(Flag::FL_ALLOW_UNSAFE_PRCTL, value)?
        } else if let Some(value) = command.strip_prefix("allow_unsafe_prlimit:") {
            self.set_flag(Flag::FL_ALLOW_UNSAFE_PRLIMIT, value)?
        } else if let Some(value) = command.strip_prefix("allow_unsafe_debug:") {
            self.set_flag(Flag::FL_ALLOW_UNSAFE_DEBUG, value)?
        } else if let Some(value) = command.strip_prefix("allow_unsafe_nopie:") {
            self.set_flag(Flag::FL_ALLOW_UNSAFE_NOPIE, value)?
        } else if let Some(value) = command.strip_prefix("allow_unsafe_namespace:") {
            self.set_nsflags(value)?;
        } else if let Some(value) = command.strip_prefix("allow_unsafe_stack:") {
            self.set_flag(Flag::FL_ALLOW_UNSAFE_STACK, value)?
        } else if let Some(value) = command.strip_prefix("allow_unsafe_time:") {
            self.set_flag(Flag::FL_ALLOW_UNSAFE_TIME, value)?
        } else if let Some(value) = command.strip_prefix("allow_unsafe_open:") {
            self.set_flag(Flag::FL_ALLOW_UNSAFE_OPEN, value)?
        } else if let Some(value) = command.strip_prefix("allow_unsafe_filename:") {
            self.set_flag(Flag::FL_ALLOW_UNSAFE_FILENAME, value)?
        } else if let Some(value) = command.strip_prefix("allow_unsafe_uring:") {
            self.set_flag(Flag::FL_ALLOW_UNSAFE_IOURING, value)?
        } else if let Some(value) = command.strip_prefix("allow_unsafe_memfd:") {
            self.set_flag(Flag::FL_ALLOW_UNSAFE_MEMFD, value)?
        } else if let Some(value) = command.strip_prefix("force_cloexec:") {
            self.set_flag(Flag::FL_FORCE_CLOEXEC, value)?
        } else if let Some(value) = command.strip_prefix("deny_dotdot:") {
            self.set_flag(Flag::FL_DENY_DOTDOT, value)?
        } else if let Some(value) = command.strip_prefix("deny_script:") {
            self.set_flag(Flag::FL_DENY_SCRIPT, value)?
        } else if let Some(value) = command.strip_prefix("deny_tsc:") {
            self.set_flag(Flag::FL_DENY_TSC, value)?
        } else if let Some(value) = command.strip_prefix("lock_personality:") {
            self.set_flag(Flag::FL_LOCK_PERSONALITY, value)?
        } else if let Some(value) = command.strip_prefix("deny_elf32:") {
            self.set_flag(Flag::FL_DENY_ELF32, value)?
        } else if let Some(value) = command.strip_prefix("deny_elf_dynamic:") {
            self.set_flag(Flag::FL_DENY_ELF_DYNAMIC, value)?
        } else if let Some(value) = command.strip_prefix("deny_elf_static:") {
            self.set_flag(Flag::FL_DENY_ELF_STATIC, value)?
        } else if let Some(value) = command.strip_prefix("force_umask:") {
            // Note, 0 is a valid umask so we'd rather disable with -1 or strbools.
            let umask = match value {
                "-1" | "off" | "f" | "fa" | "fal" | "fals" | "false" | "✗" => None,
                _ => Some(
                    Mode::from_bits(
                        nix::libc::mode_t::from_str_radix(value, 8).or(Err(Errno::EINVAL))?,
                    )
                    .ok_or(Errno::EINVAL)?,
                ),
            };
            if self.is_running() {
                return Err(Errno::EBUSY);
            }
            self.umask = umask;
        } else if let Some(value) = command.strip_prefix("memory_access:") {
            let value = match value {
                "0" => false,
                "1" => true,
                _ => return Err(Errno::EINVAL),
            };
            if self.is_running() {
                return Err(Errno::EBUSY);
            }
            if value {
                env::set_var(ENV_NO_CROSS_MEMORY_ATTACH, "1");
            } else {
                env::remove_var(ENV_NO_CROSS_MEMORY_ATTACH);
            }
        } else {
            return Err(Errno::EINVAL);
        }
        Ok(())
    }

    fn handle_unshare_config(&mut self, command: &str) -> Result<(), Errno> {
        #[allow(clippy::arithmetic_side_effects)]
        let (flags, state) = match command.chars().last() {
            Some('?') => (
                Flag::ns_from_str(&command[..command.len() - 1], false)?,
                None,
            ),
            _ => {
                let mut splits = command.splitn(2, ':');
                (
                    Flag::ns_from_str(splits.next().unwrap_or(""), false)?,
                    Some(strbool(splits.next().ok_or(Errno::EINVAL)?)?),
                )
            }
        };

        if let Some(state) = state {
            // Setting Capability with :{on,off}.
            if self.is_running() {
                return Err(Errno::EBUSY);
            } else if state {
                self.flags.insert(flags);
            } else {
                self.flags.remove(flags);
            }
        } else if !self.flags.contains(flags) {
            // Querying for Capability with ?.
            return Err(Errno::ENOENT);
        }

        Ok(()) // set|query successful.
    }

    fn handle_bind_config(&mut self, captures: &Captures) -> Result<(), Errno> {
        let op = &captures["mod"];
        let mount = BindMount::try_from(captures)?;

        if self.is_running() {
            return Err(Errno::EBUSY);
        }

        match op {
            "+" => self.add_bind_mount(mount),
            "-" => self.del_bind_mount(mount),
            "^" => self.rem_bind_mount(mount),
            _ => return Err(Errno::EINVAL),
        };

        Ok(())
    }

    fn handle_segvguard_config(&mut self, command: &str) -> Result<(), Errno> {
        if let Some(value) = command.strip_prefix("expiry:") {
            self.segvguard_expiry = value
                .parse::<u64>()
                .map(Duration::from_secs)
                .or(Err(Errno::EINVAL))?;
        } else if let Some(value) = command.strip_prefix("suspension:") {
            self.segvguard_suspension = value
                .parse::<u64>()
                .map(Duration::from_secs)
                .or(Err(Errno::EINVAL))?;
        } else if let Some(value) = command.strip_prefix("maxcrashes:") {
            self.segvguard_maxcrashes = value.parse::<u8>().or(Err(Errno::EINVAL))?;
        } else {
            return Err(Errno::EINVAL);
        }

        Ok(())
    }

    fn handle_force_rule_config(&mut self, captures: &Captures) -> Result<(), Errno> {
        let op = &captures["mod"];

        // Handle remove-all operator.
        if op == "^" {
            if ["src", "key", "act"]
                .iter()
                .any(|&name| captures.name(name).is_some())
            {
                return Err(Errno::EINVAL);
            }
            self.force_map.clear();
            return Ok(());
        }

        #[allow(clippy::disallowed_types)]
        let src = if let Some(src) = captures.name("src") {
            PathBuf::from(src.as_str())
        } else {
            return Err(Errno::EINVAL);
        };
        match op {
            "-" => {
                self.force_map.remove(&src);
                return Ok(());
            }
            "+" => {}
            _ => unreachable!("fix force regex"),
        }

        // Addition requires key and action.
        let key = if let Some(key) = captures.name("key") {
            Vec::from_hex(key.as_str()).or(Err(Errno::EINVAL))?
        } else {
            return Err(Errno::EINVAL);
        };
        // Protect user from adding invalid checksums.
        if !matches!(key.len(), 16 | 20 | 32 | 48 | 64) {
            return Err(Errno::EINVAL);
        }

        let act = if let Some(act) = captures.name("act") {
            Action::from_str(act.as_str())?
        } else {
            return Err(Errno::EINVAL);
        };

        self.force_map.insert(src, (act, key));
        Ok(())
    }

    fn handle_setid_rule_config(&mut self, captures: &Captures) -> Result<(), Errno> {
        let id = captures["id"].chars().nth(0);
        let op = captures["mod"].chars().nth(0);

        match id {
            Some('u') => {
                match (op, captures.name("src")) {
                    (Some('+'), Some(src)) => {
                        let source_uid = parse_user(src.as_str())?;
                        let target_uid = parse_user(&captures["dst"])?;
                        self.add_uid_transit(source_uid, target_uid)?;
                    }
                    (Some('-'), Some(src)) => {
                        let source_uid = parse_user(src.as_str())?;
                        let target_uid = parse_user(&captures["dst"])?;
                        self.del_uid_transit(Some(source_uid), Some(target_uid));
                    }
                    (Some('^'), Some(src)) => {
                        let source_uid = parse_user(src.as_str())?;
                        self.del_uid_transit(Some(source_uid), None);
                    }
                    (Some('^'), None) => {
                        self.del_uid_transit(None, None);
                    }
                    _ => return Err(Errno::EINVAL),
                };
            }
            Some('g') => {
                match (op, captures.name("src")) {
                    (Some('+'), Some(src)) => {
                        let source_gid = parse_group(src.as_str())?;
                        let target_gid = parse_group(&captures["dst"])?;
                        self.add_gid_transit(source_gid, target_gid)?;
                    }
                    (Some('-'), Some(src)) => {
                        let source_gid = parse_group(src.as_str())?;
                        let target_gid = parse_group(&captures["dst"])?;
                        self.del_gid_transit(Some(source_gid), Some(target_gid));
                    }
                    (Some('^'), Some(src)) => {
                        let source_gid = parse_group(src.as_str())?;
                        self.del_gid_transit(Some(source_gid), None);
                    }
                    (Some('^'), None) => {
                        self.del_gid_transit(None, None);
                    }
                    _ => return Err(Errno::EINVAL),
                };
            }
            _ => return Err(Errno::EINVAL),
        };

        Ok(())
    }

    fn handle_netlink_config(&mut self, captures: &Captures) -> Result<(), Errno> {
        if self.is_running() {
            // Netlink family restrictions are applied at kernel level at startup.
            return Err(Errno::EBUSY);
        }

        if captures.name("clr").is_some() {
            self.netlink_families = NetlinkFamily::empty();
        } else if captures.name("add").is_some() {
            self.netlink_families
                .insert(NetlinkFamily::from_str(&captures["fml"])?);
        } else if captures.name("del").is_some() {
            self.netlink_families
                .remove(NetlinkFamily::from_str(&captures["fml"])?);
        } else {
            unreachable!();
        };

        Ok(())
    }

    fn handle_rule_config(&mut self, captures: &Captures) -> Result<(), Errno> {
        let act = Action::from(captures);
        let cap = Capability::from(captures);
        let op = &captures["mod"];
        let (pat, ip) = if let Some(addr) = captures.name("addr") {
            (
                addr.as_str(),
                cap.intersects(Capability::CAP_BIND | Capability::CAP_CONNECT),
            )
        } else if let Some(path) = captures.name("path") {
            (path.as_str(), false)
        } else {
            unreachable!("Invalid rule regex!");
        };

        // Handle Landlock rules which are path beneath rules, not glob rules.
        if cap.intersects(Capability::CAP_LOCK) {
            if act != Action::Allow {
                return Err(Errno::EINVAL);
            } else if self.is_running() {
                // Landlock rules are applied at startup.
                return Err(Errno::EBUSY);
            }
            return match op {
                "+" => self.rule_add_lock(cap, pat.as_ref()),
                "-" => self.rule_del_lock(cap, pat.as_ref()),
                "^" => self.rule_rem_lock(cap, pat.as_ref()),
                _ => Err(Errno::EINVAL),
            };
        }

        // SAFETY: Reject rules that must only be set at startup.
        if self.is_running() && cap.is_startup() {
            return Err(Errno::EBUSY);
        }

        match op {
            "+" => {
                // add rule
                if ip {
                    self.rule_add_cidr(act, cap, pat.as_ref())
                } else {
                    self.rule_add_glob(act, cap, pat.as_ref())
                }
            }
            "-" => {
                // remove rule
                if ip {
                    self.rule_del_cidr(act, cap, pat.as_ref())
                } else {
                    self.rule_del_glob(act, cap, pat.as_ref())
                }
            }
            "^" => {
                // remove all matching rules
                if ip {
                    self.rule_rem_cidr(act, cap, pat.as_ref())
                } else {
                    self.rule_rem_glob(act, cap, pat.as_ref())
                }
            }
            _ => Err(Errno::EINVAL),
        }
    }

    /// Remove CIDR with port range, removes all matching instances.
    pub fn rule_rem_cidr(&mut self, act: Action, cap: Capability, pat: &str) -> Result<(), Errno> {
        let pat = pat.parse::<AddressPattern>()?;
        let rem = CidrRule { act, cap, pat };
        self.cidr_rules.retain(|rule| *rule != rem);
        Ok(())
    }

    /// Remove CIDR with port range, removes the first instance from the end for predictability.
    pub fn rule_del_cidr(&mut self, act: Action, cap: Capability, pat: &str) -> Result<(), Errno> {
        let pat = pat.parse::<AddressPattern>()?;
        let del = CidrRule { act, cap, pat };
        if let Some(idx) = self.cidr_rules.iter().position(|rule| *rule == del) {
            self.cidr_rules.remove(idx);
        }
        Ok(())
    }

    /// Add CIDR with port range
    /// The rule is either a Unix shell style pattern, or
    /// a network address, one of the following formats:
    ///
    /// 1. GLOB-PATTERN
    /// 2. IP/NETMASK!$PORT
    ///
    /// - GLOB-PATTERN must start with a slash, `/`.
    /// - /NETMASK may be omitted.
    /// - PORT is a single integer or two in format port1-port2
    pub fn rule_add_cidr(&mut self, act: Action, cap: Capability, pat: &str) -> Result<(), Errno> {
        let pat = pat.parse::<AddressPattern>()?;
        self.cidr_rules.push_front(CidrRule { act, cap, pat });
        Ok(())
    }

    /// Remove Landlock rule, removes all matching patterns.
    pub fn rule_rem_lock(&mut self, cap: Capability, pat: &str) -> Result<(), Errno> {
        #[allow(clippy::disallowed_types)]
        match cap {
            Capability::CAP_LOCK_RO => {
                if let Some(ref mut rules) = self.lock_rules_ro {
                    let pat: PathBuf = pat.into();
                    rules.retain(|p| *p != pat);
                }
                Ok(())
            }
            Capability::CAP_LOCK_RW => {
                if let Some(ref mut rules) = self.lock_rules_rw {
                    let pat: PathBuf = pat.into();
                    rules.retain(|p| *p != pat);
                }
                Ok(())
            }
            _ => Err(Errno::EINVAL),
        }
    }

    /// Remove Landlock rule, removes the first instance from the end for predicatibility.
    pub fn rule_del_lock(&mut self, cap: Capability, pat: &str) -> Result<(), Errno> {
        #[allow(clippy::disallowed_types)]
        match cap {
            Capability::CAP_LOCK_RO => {
                if let Some(ref mut rules) = self.lock_rules_ro {
                    let pat: PathBuf = pat.into();
                    if let Some((index, _)) =
                        rules.iter().enumerate().rev().find(|(_, p)| **p == pat)
                    {
                        rules.remove(index);
                    }
                }
                Ok(())
            }
            Capability::CAP_LOCK_RW => {
                if let Some(ref mut rules) = self.lock_rules_rw {
                    let pat: PathBuf = pat.into();
                    if let Some((index, _)) =
                        rules.iter().enumerate().rev().find(|(_, p)| **p == pat)
                    {
                        rules.remove(index);
                    }
                }
                Ok(())
            }
            _ => Err(Errno::EINVAL),
        }
    }

    /// Add Landlock rule.
    pub fn rule_add_lock(&mut self, cap: Capability, pat: &str) -> Result<(), Errno> {
        if pat.chars().nth(0) != Some('/') {
            return Err(Errno::EINVAL);
        }

        // Landlock rules are not glob patterns but path beneath rules.
        match cap {
            Capability::CAP_LOCK_RO => {
                if let Some(ref mut rules) = self.lock_rules_ro {
                    rules.push(pat.into());
                } else {
                    let rules = vec![pat.into()];
                    self.lock_rules_ro = Some(rules);
                }
                Ok(())
            }
            Capability::CAP_LOCK_RW => {
                if let Some(ref mut rules) = self.lock_rules_rw {
                    rules.push(pat.into());
                } else {
                    let rules = vec![pat.into()];
                    self.lock_rules_rw = Some(rules);
                }
                Ok(())
            }
            _ => Err(Errno::EINVAL),
        }
    }

    /// Add Unix shell style pattern.
    pub fn rule_add_glob(&mut self, act: Action, caps: Capability, pat: &str) -> Result<(), Errno> {
        if pat.chars().nth(0) != Some('/') {
            // We match on canonicalized paths,
            // relative patterns are a common case of error,
            // let's just prevent them until someone comes
            // up with a valid usecase.
            return Err(Errno::EINVAL);
        }

        // Clean consecutive slashes.
        // Again, we match on canonicalized paths,
        // patterns with consecutive slashes are a
        // common case of error, let's just safely
        // sanitize them to turn them into useful
        // patterns.
        let pat = clean_slash(pat);

        let (pat, meth) = if let Some(pat) = get_prefix(&pat) {
            (pat, MatchMethod::Prefix)
        } else if is_literal(pat.as_bytes()) {
            (pat.as_str(), MatchMethod::Literal)
        } else if let Some(pat) = pat.strip_suffix("/***") {
            // Pattern followed by triple star.
            // We split this into multiple patterns.
            self.rule_add_glob(act, caps, &format!("{pat}/**"))?;
            self.rule_add_glob(act, caps, pat)?;
            return Ok(());
        } else {
            (pat.as_str(), MatchMethod::Glob)
        };

        for &cap in &Capability::GLOB {
            if !caps.contains(cap) {
                continue;
            }

            if act == Action::Filter {
                let arr = self.get_arr_mut(cap);
                arr.push_front((pat.to_string(), meth));
            } else {
                let acl = self.get_acl_mut(cap);
                acl.push_front((pat.to_string(), meth, act));
            }
        }

        Ok(())
    }

    /// Remove Unix shell style pattern, removes all matching instances.
    pub fn rule_rem_glob(&mut self, act: Action, caps: Capability, pat: &str) -> Result<(), Errno> {
        // Clean consecutive slashes.
        // See rule_add_glob() for the reason.
        let pat = clean_slash(pat);

        let (pat, meth) = if let Some(pat) = get_prefix(&pat) {
            (pat, MatchMethod::Prefix)
        } else if is_literal(pat.as_bytes()) {
            (pat.as_str(), MatchMethod::Literal)
        } else if let Some(pat) = pat.strip_suffix("/***") {
            // Pattern followed by triple star.
            // We split this into multiple patterns.
            self.rule_rem_glob(act, caps, &format!("{pat}/**"))?;
            self.rule_rem_glob(act, caps, pat)?;
            return Ok(());
        } else {
            (pat.as_str(), MatchMethod::Glob)
        };

        for &cap in &Capability::GLOB {
            if !caps.contains(cap) {
                continue;
            }

            if act == Action::Filter {
                let arr = self.get_arr_mut(cap);
                arr.retain(|(p, m)| meth != *m || !litmatch(pat.as_bytes(), p.as_bytes()));
            } else {
                let acl = self.get_acl_mut(cap);
                acl.retain(|(p, m, a)| {
                    meth != *m || act != *a || !litmatch(pat.as_bytes(), p.as_bytes())
                });
            }
        }

        Ok(())
    }

    /// Remove Unix shell style pattern, removes the first instance from the end for predictability.
    pub fn rule_del_glob(&mut self, act: Action, caps: Capability, pat: &str) -> Result<(), Errno> {
        // Clean consecutive slashes.
        // See rule_add_glob() for the reason.
        let pat = clean_slash(pat);

        let (pat, meth) = if let Some(pat) = get_prefix(&pat) {
            (pat, MatchMethod::Prefix)
        } else if is_literal(pat.as_bytes()) {
            (pat.as_str(), MatchMethod::Literal)
        } else if let Some(pat) = pat.strip_suffix("/***") {
            // Pattern followed by triple star.
            // We split this into multiple patterns.
            self.rule_del_glob(act, caps, &format!("{pat}/**"))?;
            self.rule_del_glob(act, caps, pat)?;
            return Ok(());
        } else {
            (pat.as_str(), MatchMethod::Glob)
        };

        for &cap in &Capability::GLOB {
            if !caps.contains(cap) {
                continue;
            }

            if act == Action::Filter {
                let arr = self.get_arr_mut(cap);
                if let Some(index) = arr
                    .iter()
                    .position(|(p, m)| meth == *m && litmatch(pat.as_bytes(), p.as_bytes()))
                {
                    arr.remove(index);
                }
            } else {
                let acl = self.get_acl_mut(cap);
                if let Some(index) = acl.iter().position(|(p, m, a)| {
                    meth == *m && act == *a && litmatch(pat.as_bytes(), p.as_bytes())
                }) {
                    acl.remove(index);
                }
            }
        }

        Ok(())
    }

    /// Remove Unix shell style pattern from append-only acl, removes all matching instances.
    pub fn rule_rem_append(&mut self, pat: &str) -> Result<(), Errno> {
        // Clean consecutive slashes.
        // See rule_add_glob() for the reason.
        let pat = clean_slash(pat);

        let (pat, meth) = if let Some(pat) = get_prefix(&pat) {
            (pat, MatchMethod::Prefix)
        } else if is_literal(pat.as_bytes()) {
            (pat.as_str(), MatchMethod::Literal)
        } else if let Some(pat) = pat.strip_suffix("/***") {
            // Pattern followed by triple star.
            // We split this into multiple patterns.
            self.rule_rem_append(&format!("{pat}/**"))?;
            self.rule_rem_append(pat)?;
            return Ok(());
        } else {
            (pat.as_str(), MatchMethod::Glob)
        };

        self.acl_append
            .retain(|(p, m)| meth != *m || !litmatch(pat.as_bytes(), p.as_bytes()));

        Ok(())
    }

    /// Remove Unix shell style pattern from append-only acl, removes the first instance from the end for predictability.
    pub fn rule_del_append(&mut self, pat: &str) -> Result<(), Errno> {
        // Clean consecutive slashes.
        // See rule_add_glob() for the reason.
        let pat = clean_slash(pat);

        let (pat, meth) = if let Some(pat) = get_prefix(&pat) {
            (pat, MatchMethod::Prefix)
        } else if is_literal(pat.as_bytes()) {
            (pat.as_str(), MatchMethod::Literal)
        } else if let Some(pat) = pat.strip_suffix("/***") {
            // Pattern followed by triple star.
            // We split this into multiple patterns.
            self.rule_del_append(&format!("{pat}/**"))?;
            self.rule_del_append(pat)?;
            return Ok(());
        } else {
            (pat.as_str(), MatchMethod::Glob)
        };

        if let Some(index) = self
            .acl_append
            .iter()
            .position(|(p, m)| meth == *m && litmatch(pat.as_bytes(), p.as_bytes()))
        {
            self.acl_append.remove(index);
        }

        Ok(())
    }

    /// Add Unix shell style pattern to append-only acl.
    pub fn rule_add_append(&mut self, pat: &str) -> Result<(), Errno> {
        // Ensure absolute path.
        if pat.chars().nth(0) != Some('/') {
            // We match on canonicalized paths,
            // relative patterns are a common case of error,
            // let's just prevent them until someone comes
            // up with a valid usecase.
            return Err(Errno::EINVAL);
        }

        // Clean consecutive slashes.
        // See rule_add_glob() for the reason.
        let pat = clean_slash(pat);

        self.add_append(&pat);

        Ok(())
    }

    /// Simplifies the blocklists.
    pub fn rule_agg_block(&mut self, pat: &str) -> Result<(), Errno> {
        if !pat.is_empty() {
            return Err(Errno::EINVAL);
        }

        self.block_net.0.simplify();
        self.block_net.1.simplify();

        Ok(())
    }

    /// Clears the blocklists.
    pub fn rule_rem_block(&mut self, pat: &str) -> Result<(), Errno> {
        if !pat.is_empty() {
            return Err(Errno::EINVAL);
        }

        self.block_net.0 = IpRange::new();
        self.block_net.1 = IpRange::new();

        Ok(())
    }

    /// Remove an IP network from the blocklist.
    pub fn rule_del_block(&mut self, pat: &str) -> Result<(), Errno> {
        match parse_ipnet(pat) {
            Ok(IpNet::V4(addr)) => {
                self.block_net.0.remove(addr);
            }
            Ok(IpNet::V6(addr)) => {
                self.block_net.1.remove(addr);
            }
            Err(_) => return Err(Errno::EINVAL),
        }
        Ok(())
    }

    /// Add an IP network to the blocklist.
    pub fn rule_add_block(&mut self, pat: &str) -> Result<(), Errno> {
        match parse_ipnet(pat) {
            Ok(IpNet::V4(addr)) => {
                self.block_net.0.add(addr);
            }
            Ok(IpNet::V6(addr)) => {
                self.block_net.1.add(addr);
            }
            Err(_) => return Err(Errno::EINVAL),
        }
        Ok(())
    }

    /// Remove Unix shell style pattern from mask acl, removes all matching instances.
    pub fn rule_rem_mask(&mut self, pat: &str) -> Result<(), Errno> {
        // Clean consecutive slashes.
        // See rule_add_glob() for the reason.
        let pat = clean_slash(pat);

        let (pat, meth) = if let Some(pat) = get_prefix(&pat) {
            (pat, MatchMethod::Prefix)
        } else if is_literal(pat.as_bytes()) {
            (pat.as_str(), MatchMethod::Literal)
        } else if let Some(pat) = pat.strip_suffix("/***") {
            // Pattern followed by triple star.
            // We split this into multiple patterns.
            self.rule_rem_mask(&format!("{pat}/**"))?;
            self.rule_rem_mask(pat)?;
            return Ok(());
        } else {
            (pat.as_str(), MatchMethod::Glob)
        };

        self.acl_mask
            .retain(|(p, m)| meth != *m || !litmatch(pat.as_bytes(), p.as_bytes()));

        Ok(())
    }

    /// Remove Unix shell style pattern from mask acl, removes the first instance from the end for predictability.
    pub fn rule_del_mask(&mut self, pat: &str) -> Result<(), Errno> {
        // Clean consecutive slashes.
        // See rule_add_glob() for the reason.
        let pat = clean_slash(pat);

        let (pat, meth) = if let Some(pat) = get_prefix(&pat) {
            (pat, MatchMethod::Prefix)
        } else if is_literal(pat.as_bytes()) {
            (pat.as_str(), MatchMethod::Literal)
        } else if let Some(pat) = pat.strip_suffix("/***") {
            // Pattern followed by triple star.
            // We split this into multiple patterns.
            self.rule_del_mask(&format!("{pat}/**"))?;
            self.rule_del_mask(pat)?;
            return Ok(());
        } else {
            (pat.as_str(), MatchMethod::Glob)
        };

        if let Some(index) = self
            .acl_mask
            .iter()
            .position(|(p, m)| meth == *m && litmatch(pat.as_bytes(), p.as_bytes()))
        {
            self.acl_mask.remove(index);
        }

        Ok(())
    }

    /// Add Unix shell style pattern to mask acl.
    pub fn rule_add_mask(&mut self, pat: &str) -> Result<(), Errno> {
        // Ensure absolute path.
        if pat.chars().nth(0) != Some('/') {
            // We match on canonicalized paths,
            // relative patterns are a common case of error,
            // let's just prevent them until someone comes
            // up with a valid usecase.
            return Err(Errno::EINVAL);
        }

        // Clean consecutive slashes.
        // See rule_add_glob() for the reason.
        let pat = clean_slash(pat);

        self.add_mask(&pat);

        Ok(())
    }

    /// Extract the Landlock read-only and read-write path lists.
    /// Returns None if Landlock sandboxing is disabled.
    #[allow(clippy::disallowed_types)]
    pub fn collect_landlock(&mut self) -> Option<LandlockPathPair> {
        if !self.landlocked() {
            return None;
        }

        let path_ro: Vec<PathBuf> = if let Some(rules) = self.lock_rules_ro.take() {
            let set: IndexSet<PathBuf> = IndexSet::from_iter(rules);
            set.iter().cloned().collect()
        } else {
            vec![]
        };

        let path_rw: Vec<PathBuf> = if let Some(rules) = self.lock_rules_rw.take() {
            let set: IndexSet<PathBuf> = IndexSet::from_iter(rules);
            set.iter().cloned().collect()
        } else {
            vec![]
        };

        Some((path_ro, path_rw))
    }

    /// Check if the given path is hidden (ie denylisted for stat sandboxing)
    pub fn is_hidden(&self, path: &Path) -> bool {
        if self.enabled(Capability::CAP_STAT) {
            let (action, _) = self.check_path(Capability::CAP_STAT, path);
            action.is_denying()
        } else {
            false
        }
    }

    /// Check IPv{4,6} address for access.
    #[allow(clippy::cognitive_complexity)]
    pub(crate) fn check_ip(&self, cap: Capability, addr: IpAddr, port: u16) -> (Action, bool) {
        // Check for IP blocklist first.
        if cap == Capability::CAP_CONNECT {
            let ok = match addr {
                IpAddr::V4(addr) => self.block_net.0.contains(&addr),
                IpAddr::V6(addr) => self.block_net.1.contains(&addr),
            };

            if ok {
                let act = self.block_act;
                if matches!(act, Action::Allow | Action::Filter) {
                    // Filter is only checked for !(Allow|Filter).
                    return (act, true);
                } else {
                    return (act, self.filter_ip(Capability::CAP_CONNECT, &addr, port));
                }
            }
        }

        // Check for CIDR rules next.
        for rule in &self.cidr_rules {
            if cap != rule.cap {
                continue;
            }
            if rule.act == Action::Filter {
                continue;
            }
            let port_match = match rule.pat.port {
                None => true,
                Some(ports) if ports[0] == ports[1] => port == ports[0],
                Some(ports) => port >= ports[0] && port <= ports[1],
            };
            if port_match && rule.pat.addr.contains(&addr) {
                if matches!(rule.act, Action::Allow | Action::Filter) {
                    // Filter is only checked for !(Allow|Filter).
                    return (rule.act, true);
                } else {
                    return (rule.act, self.filter_ip(cap, &addr, port));
                }
            }
        }

        // If no specific rule is found, return based on capability
        // being enabled or not.
        if self.enabled(cap) {
            let action = self.default_action(cap);
            if matches!(action, Action::Allow | Action::Filter) {
                (action, true)
            } else {
                (self.default_action(cap), self.filter_ip(cap, &addr, port))
            }
        } else {
            (Action::Allow, true)
        }
    }

    /// Check UNIX socket for access.
    pub(crate) fn check_unix(&self, cap: Capability, path: &Path) -> (Action, bool) {
        // First, see if there's a matching allow or deny rule for the path.
        if let Some(action) = self.match_action(cap, path) {
            return match action {
                Action::Allow | Action::Filter => (action, true),
                Action::Warn => return (Action::Warn, false),
                action => (action, self.filter_path(cap, path)),
            };
        }

        // If no specific rule is found, return based on capability being enabled or not.
        match self.default_action(cap) {
            Action::Allow => (Action::Allow, true),
            Action::Warn => (Action::Warn, false),
            Action::Filter => (Action::Filter, true),
            action => (action, self.filter_path(cap, path)),
        }
    }

    /// Check path for TPE.
    pub(crate) fn check_tpe(&self, path: &Path) -> Action {
        if !self.apply_tpe() {
            return Action::Allow;
        }

        // Get the parent directory.
        let (parent, _) = path_split(path);

        // SAFETY:
        // 1. Do not resolve symbolic links.
        // 2. Fail if the parent is not a directory.
        // Both of these are necessary to avoid TOCTOU.
        let fd = match safe_open_path(&parent, OFlag::O_DIRECTORY) {
            Ok(fd) => fd,
            Err(_) => return self.tpe_act,
        };

        let root_owned = self.tpe_root_owned();
        let user_owned = self.tpe_user_owned();
        let mut sflags = STATX_MODE;
        if root_owned || user_owned {
            // File owner check required, request UID.
            sflags |= STATX_UID;
        }
        let statx = match fstatx(fd.as_raw_fd(), sflags) {
            Ok(statx) => statx,
            Err(_) => return self.tpe_act,
        };

        // Check if the parent directory is root/user owned.
        // Check if the parent directory is writable only by the owner.
        let is0 = statx.stx_uid == 0;
        if (u32::from(statx.stx_mode) & (nix::libc::S_IWGRP | nix::libc::S_IWOTH) != 0)
            || (user_owned && !is0 && statx.stx_uid != Uid::current().as_raw())
            || (root_owned && !is0)
        {
            self.tpe_act
        } else {
            Action::Allow
        }
    }

    /// Check if TPE should be applied.
    fn apply_tpe(&self) -> bool {
        // Check if TPE should be applied.
        if let Some(tpe_gid) = self.tpe_gid {
            let egid = Gid::effective();
            let apply = if egid == tpe_gid {
                !self.tpe_negate()
            } else {
                match getgroups() {
                    Ok(gids) => {
                        if self.tpe_negate() {
                            !gids.contains(&tpe_gid)
                        } else {
                            gids.contains(&tpe_gid)
                        }
                    }
                    Err(_) => return true,
                }
            };

            if !apply {
                return false;
            }
        } // TPE is applied if tpe_gid=None.

        true
    }

    /// Check path for access.
    pub(crate) fn check_path(&self, cap: Capability, path: &Path) -> (Action, bool) {
        // SAFETY: Deny access to paths with control characters when
        // writing. They have little to no valid usecases and an
        // attacker could use paths with control characters in them to
        // make an attack against user's terminal.
        if cap.can_write() && !self.allow_unsafe_filename() && path_has_control_chars(path) {
            return self.check_path_nomatch(cap, path);
        }

        // Drop trailing slash which can cause inconsistencies with expectations.
        let path_bytes = path.as_os_str().as_bytes();
        #[allow(clippy::arithmetic_side_effects)]
        let path = if path_bytes.ends_with(b"/") && path_bytes.len() > 1 {
            // SAFETY: Since we're operating on valid path bytes,
            // getting a slice is safe. This excludes the root path "/"
            // to avoid turning it into an empty path.
            Path::new(OsStr::from_bytes(&path_bytes[..path_bytes.len() - 1]))
        } else {
            path
        };

        // First, see if there's a matching allow or deny rule for the path.
        if let Some(action) = self.match_action(cap, path) {
            return match action {
                Action::Allow | Action::Filter => {
                    // Filter is only checked for !(Allow|Warn|Filter).
                    (action, true)
                }
                Action::Warn => (Action::Warn, false),
                Action::Deny if cap == Capability::CAP_STAT => {
                    // Filter is not checked if denying for stat (==hiding).
                    (Action::Deny, true)
                }
                _ => {
                    // If the action is !(Allow|Warn|Filter), then we
                    // must check if it's filtered.
                    (action, self.filter_path(cap, path))
                }
            };
        }

        // If no specific rule is found, return based on capability being enabled or not.
        self.check_path_nomatch(cap, path)
    }

    // If no specific rule is found, return based on capability being enabled or not.
    fn check_path_nomatch(&self, cap: Capability, path: &Path) -> (Action, bool) {
        match self.default_action(cap) {
            Action::Allow => (Action::Allow, true),
            Action::Warn => (Action::Warn, false),
            Action::Filter => (Action::Filter, true),
            Action::Deny if cap == Capability::CAP_STAT => {
                // Filter is not checked if denying for stat (==hiding).
                (Action::Deny, true)
            }
            action => {
                // If the action is !(Allow|Warn|Filter), then we must
                // check if it's filtered.
                (action, self.filter_path(cap, path))
            }
        }
    }

    /// Find a matching action (Allow or Deny) for the given path.
    pub fn match_action(&self, cap: Capability, path: &Path) -> Option<Action> {
        for (pattern, method, action) in self.get_acl(cap) {
            if globmatch(pattern.as_bytes(), path.as_os_str().as_bytes(), *method) {
                return Some(*action);
            }
        }
        None
    }

    /// Check if the given path is append-only.
    pub fn is_append(&self, path: &Path) -> bool {
        for (pattern, method) in &self.acl_append {
            if globmatch(pattern.as_bytes(), path.as_os_str().as_bytes(), *method) {
                return true;
            }
        }
        false
    }

    /// Check if the given path is masked.
    pub fn is_masked(&self, path: &Path) -> bool {
        for (pattern, method) in &self.acl_mask {
            if globmatch(pattern.as_bytes(), path.as_os_str().as_bytes(), *method) {
                return true;
            }
        }
        false
    }

    /// Check if the ip address with the given port is filtered.
    fn filter_ip(&self, cap: Capability, addr: &IpAddr, port: u16) -> bool {
        self.cidr_rules
            .iter()
            .filter(|filter| filter.act == Action::Filter && filter.cap == cap)
            .any(|filter| {
                let port_match = match filter.pat.port {
                    None => true,
                    Some(ports) if ports[0] == ports[1] => port == ports[0],
                    Some(ports) => port >= ports[0] && port <= ports[1],
                };
                port_match && filter.pat.addr.contains(addr)
            })
    }

    /// Check if the path is filtered.
    pub fn filter_path(&self, cap: Capability, path: &Path) -> bool {
        for (pattern, method) in self.get_arr(cap) {
            if globmatch(pattern.as_bytes(), path.as_os_str().as_bytes(), *method) {
                return true;
            }
        }
        false
    }

    // Accumulate glob rules into a GlobRule vector.
    fn glob_rules(&self) -> Vec<GlobRule> {
        let mut rules = vec![];

        for cap in Capability::GLOB.iter().rev() {
            for (glob, _) in self.get_arr(*cap) {
                rules.push(GlobRule {
                    cap: *cap,
                    act: Action::Filter,
                    pat: glob.clone(),
                });
            }
            for (glob, _, act) in self.get_acl(*cap) {
                rules.push(GlobRule {
                    cap: *cap,
                    act: *act,
                    pat: glob.clone(),
                });
            }
        }

        rules
    }

    #[inline]
    fn get_acl(&self, cap: Capability) -> &Acl {
        match cap {
            Capability::CAP_READ => &self.acl_r,
            Capability::CAP_STAT => &self.acl_s,
            Capability::CAP_WRITE => &self.acl_w,
            Capability::CAP_EXEC => &self.acl_x,
            Capability::CAP_IOCTL => &self.acl_i,
            Capability::CAP_BIND => &self.acl_nb,
            Capability::CAP_CONNECT => &self.acl_nc,
            _ => unreachable!(),
        }
    }

    #[inline]
    fn get_acl_mut(&mut self, cap: Capability) -> &mut Acl {
        match cap {
            Capability::CAP_READ => &mut self.acl_r,
            Capability::CAP_STAT => &mut self.acl_s,
            Capability::CAP_WRITE => &mut self.acl_w,
            Capability::CAP_EXEC => &mut self.acl_x,
            Capability::CAP_IOCTL => &mut self.acl_i,
            Capability::CAP_BIND => &mut self.acl_nb,
            Capability::CAP_CONNECT => &mut self.acl_nc,
            _ => unreachable!(),
        }
    }

    #[inline]
    fn get_arr(&self, cap: Capability) -> &Arr {
        match cap {
            Capability::CAP_READ => &self.arr_r,
            Capability::CAP_STAT => &self.arr_s,
            Capability::CAP_WRITE => &self.arr_w,
            Capability::CAP_EXEC => &self.arr_x,
            Capability::CAP_IOCTL => &self.arr_i,
            Capability::CAP_BIND => &self.arr_nb,
            Capability::CAP_CONNECT => &self.arr_nc,
            _ => unreachable!(),
        }
    }

    #[inline]
    fn get_arr_mut(&mut self, cap: Capability) -> &mut Arr {
        match cap {
            Capability::CAP_READ => &mut self.arr_r,
            Capability::CAP_STAT => &mut self.arr_s,
            Capability::CAP_WRITE => &mut self.arr_w,
            Capability::CAP_EXEC => &mut self.arr_x,
            Capability::CAP_IOCTL => &mut self.arr_i,
            Capability::CAP_BIND => &mut self.arr_nb,
            Capability::CAP_CONNECT => &mut self.arr_nc,
            _ => unreachable!(),
        }
    }

    /// Returns the default action for the given capability.
    #[inline]
    pub fn default_action(&self, cap: Capability) -> Action {
        match cap {
            Capability::CAP_READ => self.read_act,
            Capability::CAP_WRITE => self.write_act,
            Capability::CAP_STAT => self.stat_act,
            Capability::CAP_EXEC => self.exec_act,
            Capability::CAP_IOCTL => self.ioctl_act,
            Capability::CAP_BIND => self.bind_act,
            Capability::CAP_CONNECT => self.connect_act,
            Capability::CAP_MEM => self.mem_act,
            Capability::CAP_PID => self.pid_act,
            Capability::CAP_TPE => self.tpe_act,
            Capability::CAP_FORCE => self.force_act,
            _ => {
                // SAFETY: This can never happen.
                unsafe { std::hint::unreachable_unchecked() }
            }
        }
    }

    /// Return IPv4 blocklist.
    pub fn block4(&self) -> &IpRange<Ipv4Net> {
        &self.block_net.0
    }

    /// Return IPv6 blocklist.
    pub fn block6(&self) -> &IpRange<Ipv6Net> {
        &self.block_net.1
    }

    /// Return true if Proxy is configured.
    pub fn has_proxy(&self) -> bool {
        self.enabled(Capability::CAP_PROXY)
    }

    /// Return a list of denylisted ioctl requests.
    pub(crate) fn get_ioctl_deny(&self) -> Vec<u64> {
        let mut vec = Vec::with_capacity(self.ioctl_set.len());
        for (req, deny) in &self.ioctl_set {
            if *deny {
                vec.push(*req);
            }
        }
        vec
    }

    /// Check if request belongs to the ioctl allowlist/denylist.
    pub(crate) fn has_ioctl(&self, request: &u64) -> Option<bool> {
        self.ioctl_set.get(request).copied()
    }

    /// Add an ioctl request to the allowlist.
    fn add_ioctl_allow(&mut self, request: u64) {
        self.ioctl_set.insert(request, false);
        if let Some(request) = extend_ioctl(request) {
            // musl compat, see documentation of extend_ioctl().
            self.ioctl_set.insert(request, false);
        }
    }

    /// Add an ioctl request to the denylist.
    fn add_ioctl_deny(&mut self, request: u64) {
        self.ioctl_set.insert(request, true);
        if let Some(request) = extend_ioctl(request) {
            // musl compat, see documentation of extend_ioctl().
            self.ioctl_set.insert(request, true);
        }
    }

    /// Remove an ioctl request to the allowlist/denylist.
    fn del_ioctl(&mut self, request: u64) {
        self.ioctl_set.remove(&request);
        if let Some(request) = extend_ioctl(request) {
            // musl compat, see documentation of extend_ioctl().
            self.ioctl_set.remove(&request);
        }
    }

    fn add_append(&mut self, pat: &str) {
        let (pat, meth) = if let Some(pat) = get_prefix(pat) {
            (pat, MatchMethod::Prefix)
        } else if is_literal(pat.as_bytes()) {
            (pat, MatchMethod::Literal)
        } else if let Some(pat) = pat.strip_suffix("/***") {
            // Pattern followed by triple star.
            // We split this into multiple patterns.
            self.add_append(&format!("{pat}/**"));
            self.add_append(pat);
            return;
        } else {
            (pat, MatchMethod::Glob)
        };
        self.acl_append.push_front((pat.to_string(), meth));
    }

    fn add_mask(&mut self, pat: &str) {
        let (pat, meth) = if let Some(pat) = get_prefix(pat) {
            (pat, MatchMethod::Prefix)
        } else if is_literal(pat.as_bytes()) {
            (pat, MatchMethod::Literal)
        } else if let Some(pat) = pat.strip_suffix("/***") {
            // Pattern followed by triple star.
            // We split this into multiple patterns.
            self.add_mask(&format!("{pat}/**"));
            self.add_mask(pat);
            return;
        } else {
            (pat, MatchMethod::Glob)
        };
        self.acl_mask.push_front((pat.to_string(), meth));
    }

    /// Get the process ID of the syd execve child.
    pub fn get_child_pid(&self) -> Pid {
        Pid::from_raw(self.cpid)
    }

    /// Set the process ID of the syd execve child.
    pub(crate) fn set_child(&mut self, pid: Pid, pid_fd: RawFd) {
        // SAFETY: Set the sandbox lock if the state is unspecified.
        // This is safer than the previous default LockState::Exec.
        // We set this post-exec to ensure the initial configuration
        // passes through (ie config file and CLI options).
        if self.lock.is_none() {
            // !self.is_running -> lock returns no errors.
            let _ = self.lock(LockState::Set);
        }

        self.cpid = pid.as_raw();
        self.fpid = pid_fd;
    }

    /// Returns true if syd execve child is still alive.
    fn child_is_alive(&self) -> bool {
        self.fpid == nix::libc::AT_FDCWD
            // SAFETY: fpid is a valid PID file descriptor.
            || unsafe { nix::libc::syscall(nix::libc::SYS_pidfd_send_signal, self.fpid, 0, 0, 0) }
                == 0
    }

    /// Return true of the sandbox is running.
    fn is_running(&self) -> bool {
        !self.fpid.is_negative()
    }

    /// Get map root flag.
    pub fn map_root(&self) -> bool {
        self.flags.contains(Flag::FL_MAP_ROOT)
    }

    /// Get fake root flag.
    pub fn fake_root(&self) -> bool {
        self.flags.contains(Flag::FL_FAKE_ROOT)
    }

    /// Return the enabled capabilities out of the given set of capabilities.
    pub fn getcaps(&self, caps: Capability) -> Capability {
        self.state & caps
    }

    /// Return true if the sandboxing is enabled for the given capability.
    pub fn enabled(&self, cap: Capability) -> bool {
        self.enabled_all(cap)
    }

    /// Return true if the sandboxing is enabled for the given capability.
    pub fn enabled_all(&self, caps: Capability) -> bool {
        self.state.contains(caps)
    }

    /// Return true if any of the sandboxing capabilities is enabled.
    pub fn enabled_any(&self, caps: Capability) -> bool {
        self.state.intersects(caps)
    }

    /// Lock sandbox.
    pub fn lock(&mut self, state: LockState) -> Result<(), Errno> {
        if self.lock == Some(LockState::Set) {
            if state == LockState::Set {
                // Locking again when already locked is no-op.
                Ok(())
            } else {
                // No going back once locked.
                Err(Errno::EBUSY)
            }
        } else if state == LockState::Set {
            // Locked for the first and last time.
            self.lock = Some(LockState::Set);
            LOCKED.store(true, Ordering::Relaxed);
            Ok(())
        } else {
            self.lock = Some(state);
            Ok(())
        }
    }

    /// Returns true if the sandbox is locked.
    pub fn locked(&self) -> bool {
        self.lock == Some(LockState::Set)
    }

    /// Returns true if the sandbox is locked without having to lock the
    /// sandbox first. This depends on a global atomic variable and
    /// will not work if you have more than once `Sandbox` instance.
    /// Use `locked` function instead in this case.
    pub fn locked_once() -> bool {
        LOCKED.load(Ordering::Relaxed)
    }

    /// Returns true if the sandbox is locked for the given process ID.
    pub fn locked_for_pid(&self, pid: nix::libc::pid_t) -> bool {
        match self.lock {
            None => false, // same state as cpid==0.
            Some(LockState::Off) => false,
            Some(LockState::Exec) if self.cpid == 0 => false,
            Some(LockState::Exec) if self.cpid == pid => !self.child_is_alive(),
            _ => true,
        }
    }

    /// Returns true if Landlock sandboxing is enabled.
    pub fn landlocked(&self) -> bool {
        self.state.contains(Capability::CAP_LOCK)
    }

    /// Get the namespace settings of the Sandbox.
    pub fn namespaces(&self) -> nix::libc::c_int {
        let mut namespaces = 0;

        if self.flags.contains(Flag::FL_UNSHARE_MOUNT) {
            namespaces |= nix::libc::CLONE_NEWNS;
        }
        if self.flags.contains(Flag::FL_UNSHARE_UTS) {
            namespaces |= nix::libc::CLONE_NEWUTS;
        }
        if self.flags.contains(Flag::FL_UNSHARE_IPC) {
            namespaces |= nix::libc::CLONE_NEWIPC;
        }
        if self.flags.contains(Flag::FL_UNSHARE_USER) {
            namespaces |= nix::libc::CLONE_NEWUSER;
        }
        if self.flags.contains(Flag::FL_UNSHARE_PID) {
            namespaces |= nix::libc::CLONE_NEWPID;
        }
        if self.flags.contains(Flag::FL_UNSHARE_NET) {
            namespaces |= nix::libc::CLONE_NEWNET;
        }
        if self.flags.contains(Flag::FL_UNSHARE_CGROUP) {
            namespaces |= nix::libc::CLONE_NEWCGROUP;
        }
        if self.flags.contains(Flag::FL_UNSHARE_TIME) {
            namespaces |= CLONE_NEWTIME;
        }

        namespaces
    }

    /// Get the allowed namespaces of the Sandbox.
    pub(crate) fn allowed_namespaces(&self) -> nix::libc::c_int {
        let mut namespaces = 0;

        if self.flags.contains(Flag::FL_ALLOW_UNSAFE_UNSHARE_MOUNT) {
            namespaces |= nix::libc::CLONE_NEWNS;
        }
        if self.flags.contains(Flag::FL_ALLOW_UNSAFE_UNSHARE_UTS) {
            namespaces |= nix::libc::CLONE_NEWUTS;
        }
        if self.flags.contains(Flag::FL_ALLOW_UNSAFE_UNSHARE_IPC) {
            namespaces |= nix::libc::CLONE_NEWIPC;
        }
        if self.flags.contains(Flag::FL_ALLOW_UNSAFE_UNSHARE_USER) {
            namespaces |= nix::libc::CLONE_NEWUSER;
        }
        if self.flags.contains(Flag::FL_ALLOW_UNSAFE_UNSHARE_PID) {
            namespaces |= nix::libc::CLONE_NEWPID;
        }
        if self.flags.contains(Flag::FL_ALLOW_UNSAFE_UNSHARE_NET) {
            namespaces |= nix::libc::CLONE_NEWNET;
        }
        if self.flags.contains(Flag::FL_ALLOW_UNSAFE_UNSHARE_CGROUP) {
            namespaces |= nix::libc::CLONE_NEWCGROUP;
        }
        if self.flags.contains(Flag::FL_ALLOW_UNSAFE_UNSHARE_TIME) {
            namespaces |= CLONE_NEWTIME;
        }

        namespaces
    }

    /// Get the denied namespaces of the Sandbox.
    pub(crate) fn denied_namespaces(&self) -> nix::libc::c_int {
        let allowed = self.allowed_namespaces();
        NAMESPACE_FLAGS_ALL & !allowed
    }

    /// Set domainname, error if sandboxing is running.
    pub fn set_domainname(&mut self, value: &str) -> Result<(), Errno> {
        if self.is_running() {
            Err(Errno::EBUSY)
        } else {
            self.domainname = value.to_string();
            Ok(())
        }
    }

    /// Set hostname, error if sandboxing is running.
    pub fn set_hostname(&mut self, value: &str) -> Result<(), Errno> {
        if self.is_running() {
            Err(Errno::EBUSY)
        } else {
            self.hostname = value.to_string();
            Ok(())
        }
    }

    /// Get the value of the unshare-mount flag.
    pub fn unshare_mount(&self) -> bool {
        self.flags.contains(Flag::FL_UNSHARE_MOUNT)
    }

    /// Set the value of the unshare-mount flag.
    pub fn set_unshare_mount(&mut self, state: bool) {
        if state {
            self.flags.insert(Flag::FL_UNSHARE_MOUNT);
        } else {
            self.flags.remove(Flag::FL_UNSHARE_MOUNT);
        }
    }

    /// Get the value of the unshare-uts flag.
    pub fn unshare_uts(&self) -> bool {
        self.flags.contains(Flag::FL_UNSHARE_UTS)
    }

    /// Set the value of the unshare-uts flag.
    pub fn set_unshare_uts(&mut self, state: bool) {
        if state {
            self.flags.insert(Flag::FL_UNSHARE_UTS);
        } else {
            self.flags.remove(Flag::FL_UNSHARE_UTS);
        }
    }

    /// Get the value of the unshare-ipc flag.
    pub fn unshare_ipc(&self) -> bool {
        self.flags.contains(Flag::FL_UNSHARE_IPC)
    }

    /// Set the value of the unshare-ipc flag.
    pub fn set_unshare_ipc(&mut self, state: bool) {
        if state {
            self.flags.insert(Flag::FL_UNSHARE_IPC);
        } else {
            self.flags.remove(Flag::FL_UNSHARE_IPC);
        }
    }

    /// Get the value of the unshare-user flag.
    pub fn unshare_user(&self) -> bool {
        self.flags.contains(Flag::FL_UNSHARE_USER)
    }

    /// Set the value of the unshare-user flag.
    pub fn set_unshare_user(&mut self, state: bool) {
        if state {
            self.flags.insert(Flag::FL_UNSHARE_USER);
        } else {
            self.flags.remove(Flag::FL_UNSHARE_USER);
        }
    }

    /// Get the value of the unshare-pid flag.
    pub fn unshare_pid(&self) -> bool {
        self.flags.contains(Flag::FL_UNSHARE_PID)
    }

    /// Set the value of the unshare-pid flag.
    pub fn set_unshare_pid(&mut self, state: bool) {
        if state {
            self.flags.insert(Flag::FL_UNSHARE_PID);
        } else {
            self.flags.remove(Flag::FL_UNSHARE_PID);
        }
    }

    /// Get the value of the unshare-net flag.
    pub fn unshare_net(&self) -> bool {
        self.flags.contains(Flag::FL_UNSHARE_NET)
    }

    /// Set the value of the unshare-net flag.
    pub fn set_unshare_net(&mut self, state: bool) {
        if state {
            self.flags.insert(Flag::FL_UNSHARE_NET);
        } else {
            self.flags.remove(Flag::FL_UNSHARE_NET);
        }
    }

    /// Get the value of the unshare-cgroup flag.
    pub fn unshare_cgroup(&self) -> bool {
        self.flags.contains(Flag::FL_UNSHARE_CGROUP)
    }

    /// Set the value of the unshare-cgroup flag.
    pub fn set_unshare_cgroup(&mut self, state: bool) {
        if state {
            self.flags.insert(Flag::FL_UNSHARE_CGROUP);
        } else {
            self.flags.remove(Flag::FL_UNSHARE_CGROUP);
        }
    }

    /// Get the value of the unshare-time flag.
    pub fn unshare_time(&self) -> bool {
        self.flags.contains(Flag::FL_UNSHARE_TIME)
    }

    /// Set the value of the unshare-time flag.
    pub fn set_unshare_time(&mut self, state: bool) {
        if state {
            self.flags.insert(Flag::FL_UNSHARE_TIME);
        } else {
            self.flags.remove(Flag::FL_UNSHARE_TIME);
        }
    }

    /// Returns true if exit wait flag is set.
    pub fn exit_wait_all(&self) -> bool {
        self.flags.contains(Flag::FL_EXIT_WAIT_ALL)
    }

    /// Returns the TPE Gid.
    pub fn tpe_gid(&self) -> Option<Gid> {
        self.tpe_gid
    }

    /// Returns true if tpe negate flag is set.
    pub fn tpe_negate(&self) -> bool {
        self.flags.contains(Flag::FL_TPE_NEGATE)
    }

    /// Returns true if tpe root owned flag is set.
    pub fn tpe_root_owned(&self) -> bool {
        self.flags.contains(Flag::FL_TPE_ROOT_OWNED)
    }

    /// Returns true if tpe user owned flag is set.
    pub fn tpe_user_owned(&self) -> bool {
        self.flags.contains(Flag::FL_TPE_USER_OWNED)
    }

    /// Returns true if force cloexec flag is set.
    pub fn force_cloexec(&self) -> bool {
        self.flags.contains(Flag::FL_FORCE_CLOEXEC)
    }

    /// Returns true if deny dotdot flag is set.
    pub fn deny_dotdot(&self) -> bool {
        self.flags.contains(Flag::FL_DENY_DOTDOT)
    }

    /// Returns true if deny elf32 flag is set.
    pub fn deny_elf32(&self) -> bool {
        self.flags.contains(Flag::FL_DENY_ELF32)
    }

    /// Returns true if deny elf-dynamic flag is set.
    pub fn deny_elf_dynamic(&self) -> bool {
        self.flags.contains(Flag::FL_DENY_ELF_DYNAMIC)
    }

    /// Returns true if deny elf-static flag is set.
    pub fn deny_elf_static(&self) -> bool {
        self.flags.contains(Flag::FL_DENY_ELF_STATIC)
    }

    /// Returns true if deny script flag is set.
    pub fn deny_script(&self) -> bool {
        self.flags.contains(Flag::FL_DENY_SCRIPT)
    }

    /// Returns true if CAP_NET_BIND_SERVICE capability is retained.
    pub fn allow_unsafe_bind(&self) -> bool {
        self.flags.contains(Flag::FL_ALLOW_UNSAFE_BIND)
    }

    /// Returns true if CAP_CHOWN capability is retained.
    pub fn allow_unsafe_chown(&self) -> bool {
        self.flags.contains(Flag::FL_ALLOW_UNSAFE_CHOWN)
    }

    /// Allow system calls for CPU emulation functionality.
    pub fn allow_unsafe_cpu(&self) -> bool {
        self.flags.contains(Flag::FL_ALLOW_UNSAFE_CPU)
    }

    /// Returns true if core dumps are allowed for the Syd process.
    pub fn allow_unsafe_dumpable(&self) -> bool {
        self.flags.contains(Flag::FL_ALLOW_UNSAFE_DUMPABLE)
    }

    /// Returns true if exec-TOCTOU mitigator is disabled.
    pub fn allow_unsafe_exec(&self) -> bool {
        // trace/allow_unsafe_debug implies trace/allow_unsafe_{exec,memory,perf,ptrace}
        self.flags
            .intersects(Flag::FL_ALLOW_UNSAFE_DEBUG | Flag::FL_ALLOW_UNSAFE_EXEC)
    }

    /// Returns true if access to the Kernel keyring is allowed.
    pub fn allow_unsafe_keyring(&self) -> bool {
        self.flags.contains(Flag::FL_ALLOW_UNSAFE_KEYRING)
    }

    /// Returns true if unsafe memory flag is set.
    pub fn allow_unsafe_memory(&self) -> bool {
        // trace/allow_unsafe_debug implies trace/allow_unsafe_{exec,memory,perf,ptrace}
        self.flags
            .intersects(Flag::FL_ALLOW_UNSAFE_DEBUG | Flag::FL_ALLOW_UNSAFE_MEMORY)
    }

    /// Returns true if system calls used for memory protection keys are allowed.
    pub fn allow_unsafe_pkey(&self) -> bool {
        self.flags.contains(Flag::FL_ALLOW_UNSAFE_PKEY)
    }

    /// Returns true if unsafe capabilities flag is set.
    pub fn allow_unsafe_caps(&self) -> bool {
        self.flags.contains(Flag::FL_ALLOW_UNSAFE_CAPS)
    }

    /// Returns true if unsafe environment flag is set.
    pub fn allow_unsafe_env(&self) -> bool {
        self.flags.contains(Flag::FL_ALLOW_UNSAFE_ENV)
    }

    /// Returns true if successful bind addresses should be allowed for subsequent connect calls.
    pub fn allow_safe_bind(&self) -> bool {
        self.flags.contains(Flag::FL_ALLOW_SAFE_BIND)
    }

    /// Returns true if access to the Linux kernel crypto API is allowed.
    pub fn allow_safe_kcapi(&self) -> bool {
        self.flags.contains(Flag::FL_ALLOW_SAFE_KCAPI)
    }

    /// Returns true if CAP_SETUID capability is retained.
    pub fn allow_safe_setuid(&self) -> bool {
        self.flags.contains(Flag::FL_ALLOW_SAFE_SETUID)
    }

    /// Returns true if CAP_SETGID capability is retained.
    pub fn allow_safe_setgid(&self) -> bool {
        self.flags.contains(Flag::FL_ALLOW_SAFE_SETGID)
    }

    /// Returns true if execution of non-PIE binaries is allowed.
    pub fn allow_unsafe_nopie(&self) -> bool {
        self.flags.intersects(
            Flag::FL_ALLOW_UNSAFE_DEBUG | Flag::FL_ALLOW_UNSAFE_EXEC | Flag::FL_ALLOW_UNSAFE_NOPIE,
        )
    }

    /// Returns true if execution of ELF binaries with executable stack is allowed.
    pub fn allow_unsafe_stack(&self) -> bool {
        self.flags.intersects(
            Flag::FL_ALLOW_UNSAFE_DEBUG | Flag::FL_ALLOW_UNSAFE_EXEC | Flag::FL_ALLOW_UNSAFE_STACK,
        )
    }

    /// Returns true if unsupported socket families should be allowed.
    pub fn allow_unsupp_socket(&self) -> bool {
        self.flags.contains(Flag::FL_ALLOW_UNSUPP_SOCKET)
    }

    /// Returns true if raw sockets should be allowed.
    pub fn allow_unsafe_socket(&self) -> bool {
        self.flags.contains(Flag::FL_ALLOW_UNSAFE_SOCKET)
    }

    /// Returns true if unsafe syslog should be allowed.
    pub fn allow_unsafe_syslog(&self) -> bool {
        self.flags.contains(Flag::FL_ALLOW_UNSAFE_SYSLOG)
    }

    /// Returns true if unsafe msgsnd calls are allowed.
    pub fn allow_unsafe_msgsnd(&self) -> bool {
        self.flags.contains(Flag::FL_ALLOW_UNSAFE_MSGSND)
    }

    /// Returns true if unsafe prctl calls are allowed.
    pub fn allow_unsafe_prctl(&self) -> bool {
        self.flags.contains(Flag::FL_ALLOW_UNSAFE_PRCTL)
    }

    /// Returns true if unsafe prlimit calls are allowed.
    pub fn allow_unsafe_prlimit(&self) -> bool {
        self.flags.contains(Flag::FL_ALLOW_UNSAFE_PRLIMIT)
    }

    /// Returns true if unsafe debug (perf, ptrace etc) are allowed.
    pub fn allow_unsafe_debug(&self) -> bool {
        self.flags.contains(Flag::FL_ALLOW_UNSAFE_DEBUG)
    }

    /// Returns true if unsafe perf calls are allowed.
    pub fn allow_unsafe_perf(&self) -> bool {
        // Note, we keep the unsafe_p{erf,trace} intact
        // outside this module such that in the future
        // they'll be easy to split again if need be.
        self.allow_unsafe_debug()
    }

    /// Returns true if unsafe ptrace calls are allowed.
    pub fn allow_unsafe_ptrace(&self) -> bool {
        // See the note to allow_unsafe_perf.
        self.flags
            .intersects(Flag::FL_ALLOW_UNSAFE_DEBUG | Flag::FL_ALLOW_UNSAFE_EXEC)
    }

    /// Returns true if unsafe adjtime calls are allowed.
    /// This also results in keeping the CAP_SYS_TIME capability.
    pub fn allow_unsafe_time(&self) -> bool {
        self.flags.contains(Flag::FL_ALLOW_UNSAFE_TIME)
    }

    /// Returns true if CONTINUE should be applied on O_PATH file
    /// descriptors rather than turning them into O_RDONLY.
    pub fn allow_unsafe_open(&self) -> bool {
        self.flags.contains(Flag::FL_ALLOW_UNSAFE_OPEN)
    }

    /// Returns true if filenames with control characters are allowed.
    pub fn allow_unsafe_filename(&self) -> bool {
        self.flags.contains(Flag::FL_ALLOW_UNSAFE_FILENAME)
    }

    /// Returns true if unsafe io_uring calls are allowed.
    pub fn allow_unsafe_iouring(&self) -> bool {
        self.flags.contains(Flag::FL_ALLOW_UNSAFE_IOURING)
    }

    /// Returns true if secret memfds and executable memfds are allowed.
    pub fn allow_unsafe_memfd(&self) -> bool {
        self.flags.contains(Flag::FL_ALLOW_UNSAFE_MEMFD)
    }

    /// Returns true if personality(2) changes are locked.
    pub fn lock_personality(&self) -> bool {
        self.flags.contains(Flag::FL_LOCK_PERSONALITY)
    }

    /// Returns true if reading the timestamp counter is denied (x86 only).
    pub fn deny_tsc(&self) -> bool {
        self.flags.contains(Flag::FL_DENY_TSC)
    }

    /// Get SegvGuard entry expiry timeout.
    pub fn get_segvguard_expiry(&self) -> Duration {
        self.segvguard_expiry
    }

    /// Set SegvGuard entry expiry timeout.
    pub fn set_segvguard_expiry(&mut self, timeout: Duration) {
        self.segvguard_expiry = timeout;
    }

    /// SegvGuard entry suspension timeout.
    pub fn get_segvguard_suspension(&self) -> Duration {
        self.segvguard_suspension
    }

    /// SegvGuard entry suspension timeout.
    pub fn set_segvguard_suspension(&mut self, timeout: Duration) {
        self.segvguard_suspension = timeout;
    }

    /// Get SegvGuard max number of crashes before expiry.
    pub fn get_segvguard_maxcrashes(&self) -> u8 {
        self.segvguard_maxcrashes
    }

    /// Set SegvGuard max number of crashes before expiry.
    pub fn set_segvguard_maxcrashes(&mut self, maxcrashes: u8) {
        self.segvguard_maxcrashes = maxcrashes;
    }

    /// Record a crash in the SegvGuard map.
    /// Returns the current number of crashes for the given path,
    /// and two booleans, one specifies whether the executable was
    /// suspended from execution, the second specifies whether the
    /// executable has just been suspended from execution.
    #[allow(clippy::disallowed_types)]
    pub fn add_segvguard_crash(&mut self, path: PathBuf) -> (bool, bool, u8) {
        if let Some(value) = self.segvguard_map_expiry.get_mut(&path) {
            *value = value.saturating_add(1);
            let (was_suspended, is_suspended) = if *value >= self.segvguard_maxcrashes {
                (
                    true,
                    self.segvguard_map_suspension
                        .insert(path, (), self.segvguard_suspension)
                        .is_none(),
                )
            } else {
                (false, false)
            };
            (was_suspended, is_suspended, *value)
        } else {
            self.segvguard_map_expiry
                .insert(path.clone(), 1, self.segvguard_expiry);
            let (was_suspended, is_suspended) = if self.segvguard_maxcrashes <= 1 {
                (
                    true,
                    self.segvguard_map_suspension
                        .insert(path, (), self.segvguard_suspension)
                        .is_none(),
                )
            } else {
                (false, false)
            };
            (was_suspended, is_suspended, 1)
        }
    }

    /// Check SegvGuard for access.
    pub fn check_segvguard(&self, path: &Path) -> Option<Action> {
        // Setting SegvGuard default action to Allow disables SegvGuard.
        // Setting expiry timeout to 0 disables SegvGuard.
        if self.segvguard_act == Action::Allow
            || self.segvguard_expiry.is_zero()
            || !self.segvguard_map_suspension.contains_key(path)
        {
            None
        } else {
            Some(self.segvguard_act)
        }
    }

    /// Return true if there're any SegvGuard suspended paths.
    pub fn has_segvguard(&self) -> bool {
        !self.segvguard_map_suspension.is_empty()
    }

    /// Add a UID transit.
    /// If the sandbox did not previously contain this transition, Ok(true) is returned.
    /// If the sandbox did contain this transition, Ok(false) is returned, sandbox is not modified.
    pub fn add_uid_transit(&mut self, source_uid: Uid, target_uid: Uid) -> Result<bool, Errno> {
        if target_uid == ROOT_UID || source_uid.as_raw() >= target_uid.as_raw() {
            return Err(Errno::EACCES);
        }

        let transit = (source_uid, target_uid);
        if self.transit_uids.contains(&transit) {
            return Ok(false);
        }

        if self
            .transit_uids
            .iter()
            .any(|&(s_uid, _)| s_uid == source_uid)
        {
            // Transition exists with same source UID but different target UID.
            // The user should remove the old transition to add this one.
            return Err(Errno::EEXIST);
        }

        self.transit_uids.push(transit);
        Ok(true)
    }

    /// Delete a UID transit.
    /// If both source and target is None, clears all transit UIDs.
    /// If source is not None and target is None, remove all transit UIDs with the source.
    /// If source is None and target is not None, remove all transit UIDs with the target.
    /// If both is not None, delete the matching UID.
    pub fn del_uid_transit(&mut self, source_uid: Option<Uid>, target_uid: Option<Uid>) {
        match (source_uid, target_uid) {
            (None, None) => self.transit_uids.clear(),
            (Some(source), None) => self.transit_uids.retain(|&(s_uid, _)| s_uid != source),
            (None, Some(target)) => self.transit_uids.retain(|&(_, t_uid)| t_uid != target),
            (Some(source), Some(target)) => self
                .transit_uids
                .retain(|&(s_uid, t_uid)| s_uid != source || t_uid != target),
        }
    }

    /// Check a UID transit.
    /// Returns true for allowed, false for not allowed.
    pub fn chk_uid_transit(&self, source_uid: Uid, target_uid: Uid) -> bool {
        if target_uid == ROOT_UID || source_uid.as_raw() >= target_uid.as_raw() {
            return false;
        }

        for (s_uid, t_uid) in &self.transit_uids {
            if source_uid == *s_uid && target_uid == *t_uid {
                return true;
            }
        }

        false
    }

    /// Add a GID transit.
    /// If the sandbox did not previously contain this transition, Ok(true) is returned.
    /// If the sandbox did contain this transition, Ok(false) is returned, sandbox is not modified.
    pub fn add_gid_transit(&mut self, source_gid: Gid, target_gid: Gid) -> Result<bool, Errno> {
        if target_gid == ROOT_GID || source_gid.as_raw() >= target_gid.as_raw() {
            return Err(Errno::EACCES);
        }

        let transit = (source_gid, target_gid);
        if self.transit_gids.contains(&transit) {
            return Ok(false);
        }

        if self
            .transit_gids
            .iter()
            .any(|&(s_gid, _)| s_gid == source_gid)
        {
            // Transition exists with same source GID but different target GID.
            // The user should remove the old transition to add this one.
            return Err(Errno::EEXIST);
        }

        self.transit_gids.push(transit);
        Ok(true)
    }

    /// Delete a GID transit.
    /// If both source and target is None, clears all transit GIDs.
    /// If source is not None and target is None, remove all transit GIDs with the source.
    /// If source is None and target is not None, remove all transit GIDs with the target.
    /// If both is not None, delete the matching GID.
    pub fn del_gid_transit(&mut self, source_gid: Option<Gid>, target_gid: Option<Gid>) {
        match (source_gid, target_gid) {
            (None, None) => self.transit_gids.clear(),
            (Some(source), None) => self.transit_gids.retain(|&(s_gid, _)| s_gid != source),
            (None, Some(target)) => self.transit_gids.retain(|&(_, t_gid)| t_gid != target),
            (Some(source), Some(target)) => self
                .transit_gids
                .retain(|&(s_gid, t_gid)| s_gid != source || t_gid != target),
        }
    }

    /// Check a GID transit.
    /// Returns true for allowed, false for not allowed.
    pub fn chk_gid_transit(&self, source_gid: Gid, target_gid: Gid) -> bool {
        if target_gid == ROOT_GID || source_gid.as_raw() >= target_gid.as_raw() {
            return false;
        }

        for (s_gid, t_gid) in &self.transit_gids {
            if source_gid == *s_gid && target_gid == *t_gid {
                return true;
            }
        }

        false
    }

    /// Add a bind mount action to the list of mount actions.
    pub fn add_bind_mount(&mut self, mount: BindMount) {
        if let Some(ref mut mounts) = self.bind_mounts {
            mounts.push(mount);
        } else {
            self.bind_mounts = Some(vec![mount]);
        }
    }

    /// Remove the first matching item from the end of the list of mount actions.
    pub fn del_bind_mount(&mut self, mount: BindMount) {
        if let Some(ref mut mounts) = self.bind_mounts {
            if let Some(pos) = mounts.iter().rposition(|m| m == &mount) {
                mounts.remove(pos);
            }
        }
    }

    /// Remove all matchign items from the list of mount actions.
    pub fn rem_bind_mount(&mut self, mount: BindMount) {
        if let Some(ref mut mounts) = self.bind_mounts {
            mounts.retain(|m| m != &mount);
        }
    }

    /// Extract the bind mount list.
    pub fn collect_bind_mounts(&mut self) -> Option<Vec<BindMount>> {
        std::mem::take(&mut self.bind_mounts)
    }

    /// Return true if there're any bind mounts defined.
    pub fn has_bind_mounts(&self) -> bool {
        !self
            .bind_mounts
            .as_ref()
            .map_or(true, |bind_mounts| bind_mounts.is_empty())
    }

    /// Check the path against the Integrity Force map.
    pub fn check_force(&self, path: &Path) -> Result<Action, IntegrityError> {
        if let Some((action, key)) = self.force_map.get(path) {
            let func = match HashAlgorithm::try_from(key.len()) {
                Ok(func) => func,
                _ => unreachable!("Hash with undefined length in Integrity Force map!"),
            };
            // SAFETY: Use safe open to avoid TOCTOU!
            let file = match safe_open(path, OFlag::O_RDONLY) {
                Ok(fd) => BufReader::new(File::from(fd)),
                Err(errno) => return Err(IntegrityError::Sys(errno)),
            };
            let hash = crate::hash::hash(file, func)?;
            if hash != *key {
                return Err(IntegrityError::Hash {
                    action: *action,
                    expected: key.to_lower_hex_string(),
                    found: hash.to_lower_hex_string(),
                });
            } else {
                return Ok(Action::Allow);
            }
        }
        Ok(self.force_act)
    }

    /// Check the path against the Integrity Force map using the given File.
    pub fn check_force2<R: BufRead>(
        &self,
        path: &Path,
        mut reader: R,
    ) -> Result<Action, IntegrityError> {
        if let Some((action, key)) = self.force_map.get(path) {
            let func = match HashAlgorithm::try_from(key.len()) {
                Ok(func) => func,
                _ => unreachable!("Hash with undefined length in Integrity Force map!"),
            };
            let hash = crate::hash::hash(&mut reader, func)?;
            if hash != *key {
                return Err(IntegrityError::Hash {
                    action: *action,
                    expected: key.to_lower_hex_string(),
                    found: hash.to_lower_hex_string(),
                });
            } else {
                return Ok(Action::Allow);
            }
        }
        Ok(self.force_act)
    }

    /// Panic if the sandbox state allows it.
    pub fn panic(&self) -> Result<(), Errno> {
        #[allow(clippy::disallowed_methods)]
        std::process::exit(127)
    }

    /// Reset the sandbox to its default state, keeping the child pid information intact.
    pub fn reset(&mut self) -> Result<(), Errno> {
        // SAFETY: We must preserve the state of the Sandbox lock!
        // SAFETY: We must preserve child pid{,fd} or lock:exec can be
        // bypassed!
        *self = Self {
            cpid: self.cpid,
            fpid: self.fpid,
            lock: self.lock,
            ..Self::default()
        };

        // ATM, this function can never fail but we leave the Result
        // return as a possible extension for the future.
        Ok(())
    }

    /// Set namespace flags.
    fn set_nsflags(&mut self, value: &str) -> Result<(), Errno> {
        // Parse namespace flags.
        let nsflags = Flag::ns_from_str(value, true)?;

        // Reset flags for predictability.
        self.flags.remove(
            Flag::FL_ALLOW_UNSAFE_UNSHARE_MOUNT
                | Flag::FL_ALLOW_UNSAFE_UNSHARE_UTS
                | Flag::FL_ALLOW_UNSAFE_UNSHARE_IPC
                | Flag::FL_ALLOW_UNSAFE_UNSHARE_USER
                | Flag::FL_ALLOW_UNSAFE_UNSHARE_PID
                | Flag::FL_ALLOW_UNSAFE_UNSHARE_NET
                | Flag::FL_ALLOW_UNSAFE_UNSHARE_CGROUP
                | Flag::FL_ALLOW_UNSAFE_UNSHARE_TIME,
        );

        self.flags.insert(nsflags);

        Ok(())
    }

    /// Set or remove sandbox flag.
    fn set_flag(&mut self, flag: Flag, state: &str) -> Result<(), Errno> {
        // SAFETY: Reject flags that must only be set at startup.
        if self.is_running() && flag.is_startup() {
            return Err(Errno::EBUSY);
        }

        if strbool(state)? {
            self.flags.insert(flag);
        } else {
            self.flags.remove(flag);
        }

        Ok(())
    }

    /// Returns a new sandbox in default state.
    pub fn new() -> Self {
        Sandbox::default()
    }
}

/// Converts a string representation of a number into a `u64` value.
///
/// The string can be in hexadecimal (prefixed with "0x"), octal
/// (prefixed with "0o"), or decimal format. If the conversion fails, it
/// returns an `Errno::EINVAL` error.
///
/// # Arguments
///
/// * `value` - A string slice that holds the number to be converted.
///
/// # Returns
///
/// * `Result<u64, Errno>` - On success, returns the converted `u64`
///   value. On failure, returns an `Errno::EINVAL` error.
fn str2u64(value: &str) -> Result<u64, Errno> {
    let value = value.to_ascii_lowercase();
    if let Some(value) = value.strip_prefix("0x") {
        u64::from_str_radix(value, 16)
    } else if let Some(value) = value.strip_prefix("0o") {
        u64::from_str_radix(value, 8)
    } else {
        value.parse::<u64>()
    }
    .or(Err(Errno::EINVAL))
}

/// Replaces consecutive slashes (`/`) in a string with a single slash.
///
/// # Arguments
///
/// * `input` - A string slice that represents the string to be processed.
///
/// # Returns
///
/// Returns a new `String` where all consecutive slashes have been
/// replaced with a single slash.
fn clean_slash(input: &str) -> String {
    // Use `chars().peekable()` to create an iterator that can look
    // ahead without consuming the item.
    let mut chars = input.chars().peekable();
    let mut result = String::new();

    // Iterate through each character in the string.
    while let Some(c) = chars.next() {
        // Check if the current character is a slash:
        // If the next character is also a slash,
        // continue to the next iteration without
        // adding the current slash.
        if c == '/' && chars.peek() == Some(&'/') {
            continue;
        }

        // Add the current character to the result string.
        result.push(c);
    }

    result
}

// Note to self: To renumber the tests, do
// :let i=1 | g/sandbox_config_rules_\zs\d\+/s//\=i/ | let i+=1
// in VIM.
#[cfg(test)]
mod tests {
    use nix::unistd::Group;

    use super::*;
    use crate::err::SydResult as TestResult;

    fn get_nogroup() -> Result<(Gid, String), Errno> {
        // nogroup may be GID 65533 or 65534 depending on system.
        // nogroup may not even exist such as on Fedora (in which case nobody exists).
        // E.g. on Alpine it's 65533 meanwhile on Ubuntu it's 65534.
        let name = "nogroup".to_string();
        if let Ok(Some(group)) = Group::from_name(&name) {
            return Ok((group.gid, name));
        }

        let name = "nobody".to_string();
        if let Ok(Some(group)) = Group::from_name(&name) {
            return Ok((group.gid, name));
        }

        Err(Errno::ENOENT)
    }

    #[test]
    fn test_clean_slash() -> TestResult<()> {
        assert_eq!(clean_slash("/"), "/");
        assert_eq!(clean_slash("//"), "/");
        assert_eq!(clean_slash("///"), "/");
        assert_eq!(clean_slash("//home/alip///"), "/home/alip/");
        assert_eq!(
            clean_slash("//home/alip///.config///"),
            "/home/alip/.config/"
        );
        assert_eq!(
            clean_slash("//home/alip///.config///htop////"),
            "/home/alip/.config/htop/"
        );
        assert_eq!(
            clean_slash("//home/alip///.config///htop////htoprc"),
            "/home/alip/.config/htop/htoprc"
        );
        Ok(())
    }

    #[test]
    fn sandbox_config_api() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        sandbox.config("")?;
        sandbox.config("3")?;
        assert!(sandbox.config("2").is_err(), "{sandbox}");
        assert!(sandbox.config("1").is_err(), "{sandbox}");
        assert!(sandbox.config("0").is_err(), "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_sandbox_read() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert!(sandbox.state.contains(Capability::CAP_READ));
        assert!(sandbox.config("sandbox/read?").is_ok());
        sandbox.config("sandbox/read:off")?;
        assert!(!sandbox.state.contains(Capability::CAP_READ));
        assert!(sandbox.config("sandbox/read?").is_err());
        sandbox.config("sandbox/read:on")?;
        assert!(sandbox.state.contains(Capability::CAP_READ));
        assert!(sandbox.config("sandbox/read?").is_ok());

        Ok(())
    }

    #[test]
    fn sandbox_config_sandbox_stat() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert!(sandbox.state.contains(Capability::CAP_STAT));
        assert!(sandbox.config("sandbox/stat?").is_ok());
        sandbox.config("sandbox/stat:off")?;
        assert!(!sandbox.state.contains(Capability::CAP_STAT));
        assert!(sandbox.config("sandbox/stat?").is_err());
        sandbox.config("sandbox/stat:on")?;
        assert!(sandbox.state.contains(Capability::CAP_STAT));
        assert!(sandbox.config("sandbox/stat?").is_ok());

        Ok(())
    }

    #[test]
    fn sandbox_config_sandbox_write() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert!(sandbox.state.contains(Capability::CAP_WRITE));
        assert!(sandbox.config("sandbox/write?").is_ok());
        sandbox.config("sandbox/write:off")?;
        assert!(!sandbox.state.contains(Capability::CAP_WRITE));
        assert!(sandbox.config("sandbox/write?").is_err());
        sandbox.config("sandbox/write:on")?;
        assert!(sandbox.state.contains(Capability::CAP_WRITE));
        assert!(sandbox.config("sandbox/write?").is_ok());
        Ok(())
    }

    #[test]
    fn sandbox_config_sandbox_exec() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert!(sandbox.state.contains(Capability::CAP_EXEC));
        assert!(sandbox.config("sandbox/exec?").is_ok());
        sandbox.config("sandbox/exec:off")?;
        assert!(!sandbox.state.contains(Capability::CAP_EXEC));
        assert!(sandbox.config("sandbox/exec?").is_err());
        sandbox.config("sandbox/exec:on")?;
        assert!(sandbox.state.contains(Capability::CAP_EXEC));
        assert!(sandbox.config("sandbox/exec?").is_ok());
        Ok(())
    }

    #[test]
    fn sandbox_config_sandbox_ioctl() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert!(!sandbox.state.contains(Capability::CAP_IOCTL));
        assert!(sandbox.config("sandbox/ioctl?").is_err());
        sandbox.config("sandbox/ioctl:on")?;
        assert!(sandbox.state.contains(Capability::CAP_IOCTL));
        assert!(sandbox.config("sandbox/ioctl?").is_ok());
        sandbox.config("sandbox/ioctl:off")?;
        assert!(!sandbox.state.contains(Capability::CAP_IOCTL));
        assert!(sandbox.config("sandbox/ioctl?").is_err());
        Ok(())
    }

    #[test]
    fn sandbox_config_sandbox_network() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert!(sandbox.state.contains(Capability::CAP_BIND));
        assert!(sandbox.state.contains(Capability::CAP_CONNECT));
        assert!(sandbox.config("sandbox/net?").is_ok());
        sandbox.config("sandbox/net:off")?;
        assert!(!sandbox.state.contains(Capability::CAP_BIND));
        assert!(!sandbox.state.contains(Capability::CAP_CONNECT));
        assert!(sandbox.config("sandbox/net?").is_err());
        sandbox.config("sandbox/net:on")?;
        assert!(sandbox.state.contains(Capability::CAP_BIND));
        assert!(sandbox.state.contains(Capability::CAP_CONNECT));
        assert!(sandbox.config("sandbox/net?").is_ok());

        sandbox.config("sandbox/net:off")?;
        sandbox.config("sandbox/net/bind:on")?;
        assert!(sandbox.state.contains(Capability::CAP_BIND));
        assert!(!sandbox.state.contains(Capability::CAP_CONNECT));
        assert!(sandbox.config("sandbox/net?").is_err());
        assert!(sandbox.config("sandbox/net/bind?").is_ok());
        assert!(sandbox.config("sandbox/net/connect?").is_err());
        sandbox.config("sandbox/net/bind:off")?;
        assert!(sandbox.config("sandbox/net?").is_err());
        assert!(sandbox.config("sandbox/net/bind?").is_err());
        assert!(sandbox.config("sandbox/net/connect?").is_err());

        sandbox.config("sandbox/net:off")?;
        sandbox.config("sandbox/net/connect:on")?;
        assert!(sandbox.state.contains(Capability::CAP_CONNECT));
        assert!(!sandbox.state.contains(Capability::CAP_BIND));
        assert!(sandbox.config("sandbox/net?").is_err());
        assert!(sandbox.config("sandbox/net/bind?").is_err());
        assert!(sandbox.config("sandbox/net/connect?").is_ok());
        sandbox.config("sandbox/net/connect:off")?;
        assert!(sandbox.config("sandbox/net?").is_err());
        assert!(sandbox.config("sandbox/net/bind?").is_err());
        assert!(sandbox.config("sandbox/net/connect?").is_err());

        Ok(())
    }

    #[test]
    fn sandbox_config_sandbox_many() -> TestResult<()> {
        let mut sandbox = Sandbox::default();

        sandbox.state = Capability::empty();
        sandbox.config("sandbox/read,stat:on")?;
        sandbox.config("sandbox/read,write,lock:off")?;
        sandbox.config("sandbox/lock,pid,mem,force,proxy,ioctl:on")?;
        sandbox.config("sandbox/force,mem,tpe,proxy:off")?;
        sandbox.config("sandbox/net,exec:on")?;
        sandbox.config("sandbox/net/bind,net/bind:off")?;
        assert!(sandbox.state.contains(Capability::CAP_CONNECT));
        assert!(sandbox.state.contains(Capability::CAP_EXEC));
        assert!(sandbox.state.contains(Capability::CAP_IOCTL));
        assert!(sandbox.state.contains(Capability::CAP_LOCK));
        assert!(sandbox.state.contains(Capability::CAP_PID));
        assert!(sandbox.state.contains(Capability::CAP_STAT));
        assert!(!sandbox.state.contains(Capability::CAP_BIND));
        assert!(!sandbox.state.contains(Capability::CAP_FORCE));
        assert!(!sandbox.state.contains(Capability::CAP_TPE));
        assert!(!sandbox.state.contains(Capability::CAP_PROXY));
        assert!(!sandbox.state.contains(Capability::CAP_MEM));
        assert!(!sandbox.state.contains(Capability::CAP_READ));
        assert!(!sandbox.state.contains(Capability::CAP_WRITE));

        Ok(())
    }

    #[test]
    fn sandbox_config_sandbox_many_lax() -> TestResult<()> {
        let mut sandbox = Sandbox::default();

        sandbox.state = Capability::empty();
        sandbox.config("sandbox/\treAd ,\t,\t\t,\t\t ,\t \t,  STaT :on")?;
        sandbox.config("sandbox/  ReaD\t\t, write   , lock\t\t:OFF")?;
        sandbox.config("sandbox/   Lock  , pID, MeM,  ForcE,MeM,LOCK,IoCtL:on")?;
        sandbox.config("sandbox/ Force ,  ,\t,  MeM  , PROXY, TPe\t,  :off")?;
        sandbox.config("sandbox/   Net ,   , ,  ,   ,    ,    \t,eXEc    :on")?;
        sandbox.config("sandbox/\t Net/BInd , net/bInd :off")?;
        assert!(sandbox.state.contains(Capability::CAP_CONNECT));
        assert!(sandbox.state.contains(Capability::CAP_EXEC));
        assert!(sandbox.state.contains(Capability::CAP_IOCTL));
        assert!(sandbox.state.contains(Capability::CAP_LOCK));
        assert!(sandbox.state.contains(Capability::CAP_PID));
        assert!(sandbox.state.contains(Capability::CAP_STAT));
        assert!(!sandbox.state.contains(Capability::CAP_BIND));
        assert!(!sandbox.state.contains(Capability::CAP_FORCE));
        assert!(!sandbox.state.contains(Capability::CAP_TPE));
        assert!(!sandbox.state.contains(Capability::CAP_PROXY));
        assert!(!sandbox.state.contains(Capability::CAP_MEM));
        assert!(!sandbox.state.contains(Capability::CAP_READ));
        assert!(!sandbox.state.contains(Capability::CAP_WRITE));

        Ok(())
    }

    #[test]
    fn sandbox_config_unshare_flags_mount() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert!(!sandbox.flags.contains(Flag::FL_UNSHARE_MOUNT));
        assert!(sandbox.config("unshare/mount?").is_err());
        sandbox.config("unshare/mount:on")?;
        assert!(sandbox.flags.contains(Flag::FL_UNSHARE_MOUNT));
        assert!(sandbox.config("unshare/mount?").is_ok());
        sandbox.config("unshare/mount:off")?;
        assert!(!sandbox.flags.contains(Flag::FL_UNSHARE_MOUNT));
        assert!(sandbox.config("unshare/mount?").is_err());

        Ok(())
    }

    #[test]
    fn sandbox_config_unshare_flags_uts() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert!(!sandbox.flags.contains(Flag::FL_UNSHARE_UTS));
        assert!(sandbox.config("unshare/uts?").is_err());
        sandbox.config("unshare/uts:on")?;
        assert!(sandbox.flags.contains(Flag::FL_UNSHARE_UTS));
        assert!(sandbox.config("unshare/uts?").is_ok());
        sandbox.config("unshare/uts:off")?;
        assert!(!sandbox.flags.contains(Flag::FL_UNSHARE_UTS));
        assert!(sandbox.config("unshare/uts?").is_err());

        Ok(())
    }

    #[test]
    fn sandbox_config_unshare_flags_ipc() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert!(!sandbox.flags.contains(Flag::FL_UNSHARE_IPC));
        assert!(sandbox.config("unshare/ipc?").is_err());
        sandbox.config("unshare/ipc:on")?;
        assert!(sandbox.flags.contains(Flag::FL_UNSHARE_IPC));
        assert!(sandbox.config("unshare/ipc?").is_ok());
        sandbox.config("unshare/ipc:off")?;
        assert!(!sandbox.flags.contains(Flag::FL_UNSHARE_IPC));
        assert!(sandbox.config("unshare/ipc?").is_err());

        Ok(())
    }

    #[test]
    fn sandbox_config_unshare_flags_user() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert!(!sandbox.flags.contains(Flag::FL_UNSHARE_USER));
        assert!(sandbox.config("unshare/user?").is_err());
        sandbox.config("unshare/user:on")?;
        assert!(sandbox.flags.contains(Flag::FL_UNSHARE_USER));
        assert!(sandbox.config("unshare/user?").is_ok());
        sandbox.config("unshare/user:off")?;
        assert!(!sandbox.flags.contains(Flag::FL_UNSHARE_USER));
        assert!(sandbox.config("unshare/user?").is_err());

        Ok(())
    }

    #[test]
    fn sandbox_config_unshare_flags_pid() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert!(!sandbox.flags.contains(Flag::FL_UNSHARE_PID));
        assert!(sandbox.config("unshare/pid?").is_err());
        sandbox.config("unshare/pid:on")?;
        assert!(sandbox.flags.contains(Flag::FL_UNSHARE_PID));
        assert!(sandbox.config("unshare/pid?").is_ok());
        sandbox.config("unshare/pid:off")?;
        assert!(!sandbox.flags.contains(Flag::FL_UNSHARE_PID));
        assert!(sandbox.config("unshare/pid?").is_err());

        Ok(())
    }

    #[test]
    fn sandbox_config_unshare_flags_net() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert!(!sandbox.flags.contains(Flag::FL_UNSHARE_NET));
        assert!(sandbox.config("unshare/net?").is_err());
        sandbox.config("unshare/net:on")?;
        assert!(sandbox.flags.contains(Flag::FL_UNSHARE_NET));
        assert!(sandbox.config("unshare/net?").is_ok());
        sandbox.config("unshare/net:off")?;
        assert!(!sandbox.flags.contains(Flag::FL_UNSHARE_NET));
        assert!(sandbox.config("unshare/net?").is_err());

        Ok(())
    }

    #[test]
    fn sandbox_config_unshare_flags_cgroup() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert!(!sandbox.flags.contains(Flag::FL_UNSHARE_CGROUP));
        assert!(sandbox.config("unshare/cgroup?").is_err());
        sandbox.config("unshare/cgroup:on")?;
        assert!(sandbox.flags.contains(Flag::FL_UNSHARE_CGROUP));
        assert!(sandbox.config("unshare/cgroup?").is_ok());
        sandbox.config("unshare/cgroup:off")?;
        assert!(!sandbox.flags.contains(Flag::FL_UNSHARE_CGROUP));
        assert!(sandbox.config("unshare/cgroup?").is_err());

        Ok(())
    }

    #[test]
    fn sandbox_config_unshare_flags_many() -> TestResult<()> {
        let mut sandbox = Sandbox::default();

        sandbox.flags = Flag::empty();
        sandbox.config("unshare/mount,uts:on")?;
        sandbox.config("unshare/mount,uts,ipc:off")?;
        sandbox.config("unshare/mount,uts,ipc,user:on")?;
        sandbox.config("unshare/user,pid:off")?;
        sandbox.config("unshare/net,cgroup:on")?;
        sandbox.config("unshare/cgroup:off")?;
        assert!(sandbox.flags.contains(Flag::FL_UNSHARE_MOUNT));
        assert!(sandbox.flags.contains(Flag::FL_UNSHARE_UTS));
        assert!(sandbox.flags.contains(Flag::FL_UNSHARE_IPC));
        assert!(!sandbox.flags.contains(Flag::FL_UNSHARE_USER));
        assert!(!sandbox.flags.contains(Flag::FL_UNSHARE_PID));
        assert!(sandbox.flags.contains(Flag::FL_UNSHARE_NET));
        assert!(!sandbox.flags.contains(Flag::FL_UNSHARE_CGROUP));

        Ok(())
    }

    #[test]
    fn sandbox_config_unshare_flags_many_lax() -> TestResult<()> {
        let mut sandbox = Sandbox::default();

        sandbox.flags = Flag::empty();
        sandbox.config("unshare/\tmOunt ,\tuTS,\t\t,\t\t ,\t \t,   :on")?;
        sandbox.config("unshare/  moUnT\t\t, UTS   ,  \t\tIPc    ,,,,,,:off")?;
        sandbox.config("unshare/  MoUnT\t , ,  ,,,,,,\tUtS  ,\t, IPC  \t,  USer:on")?;
        sandbox.config("unshare/     user,  , , , , , , pId:off")?;
        sandbox.config("unshare/\t\t,,,,net,,,,,,cgroup:on")?;
        sandbox.config("unshare/,,,,,CGROUP,\t:off")?;
        assert!(sandbox.flags.contains(Flag::FL_UNSHARE_MOUNT));
        assert!(sandbox.flags.contains(Flag::FL_UNSHARE_UTS));
        assert!(sandbox.flags.contains(Flag::FL_UNSHARE_IPC));
        assert!(!sandbox.flags.contains(Flag::FL_UNSHARE_USER));
        assert!(!sandbox.flags.contains(Flag::FL_UNSHARE_PID));
        assert!(sandbox.flags.contains(Flag::FL_UNSHARE_NET));
        assert!(!sandbox.flags.contains(Flag::FL_UNSHARE_CGROUP));

        Ok(())
    }

    #[test]
    fn sandbox_config_lock() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.lock, None);
        sandbox.config("lock:off")?;
        assert_eq!(sandbox.lock, Some(LockState::Off));
        sandbox.config("lock:exec")?;
        assert_eq!(sandbox.lock, Some(LockState::Exec));
        sandbox.config("lock:on")?;
        assert_eq!(sandbox.lock, Some(LockState::Set));
        Ok(())
    }

    #[test]
    fn sandbox_config_trace() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert!(!sandbox.flags.contains(Flag::FL_ALLOW_SAFE_BIND));
        sandbox.config("trace/allow_safe_bind:true")?;
        assert!(sandbox.flags.contains(Flag::FL_ALLOW_SAFE_BIND));
        sandbox.config("trace/allow_safe_bind:false")?;
        assert!(!sandbox.flags.contains(Flag::FL_ALLOW_SAFE_BIND));
        sandbox.config("trace/allow_safe_bind:t")?;
        assert!(sandbox.flags.contains(Flag::FL_ALLOW_SAFE_BIND));
        sandbox.config("trace/allow_safe_bind:f")?;
        assert!(!sandbox.flags.contains(Flag::FL_ALLOW_SAFE_BIND));
        sandbox.config("trace/allow_safe_bind:1")?;
        assert!(sandbox.flags.contains(Flag::FL_ALLOW_SAFE_BIND));
        sandbox.config("trace/allow_safe_bind:0")?;
        assert!(!sandbox.flags.contains(Flag::FL_ALLOW_SAFE_BIND));

        assert_eq!(
            sandbox.config("trace/allow_safe_bind_invalid:t"),
            Err(Errno::EINVAL)
        );
        assert_eq!(
            sandbox.config("trace/allow_safe_bind!x"),
            Err(Errno::EINVAL)
        );
        assert_eq!(
            sandbox.config("trace/allow_safe_bind:x"),
            Err(Errno::EINVAL)
        );
        assert_eq!(
            sandbox.config("trace/allow_safe_bind:☮"),
            Err(Errno::EINVAL)
        );

        assert!(!sandbox.flags.contains(Flag::FL_ALLOW_UNSUPP_SOCKET));
        sandbox.config("trace/allow_unsupp_socket:true")?;
        assert!(sandbox.flags.contains(Flag::FL_ALLOW_UNSUPP_SOCKET));
        sandbox.config("trace/allow_unsupp_socket:false")?;
        assert!(!sandbox.flags.contains(Flag::FL_ALLOW_UNSUPP_SOCKET));
        sandbox.config("trace/allow_unsupp_socket:t")?;
        assert!(sandbox.flags.contains(Flag::FL_ALLOW_UNSUPP_SOCKET));
        sandbox.config("trace/allow_unsupp_socket:f")?;
        assert!(!sandbox.flags.contains(Flag::FL_ALLOW_UNSUPP_SOCKET));
        sandbox.config("trace/allow_unsupp_socket:1")?;
        assert!(sandbox.flags.contains(Flag::FL_ALLOW_UNSUPP_SOCKET));
        sandbox.config("trace/allow_unsupp_socket:0")?;
        assert!(!sandbox.flags.contains(Flag::FL_ALLOW_UNSUPP_SOCKET));

        assert_eq!(
            sandbox.config("trace/allow_unsupp_socket_invalid:t"),
            Err(Errno::EINVAL)
        );
        assert_eq!(
            sandbox.config("trace/allow_unsupp_socket!x"),
            Err(Errno::EINVAL)
        );
        assert_eq!(
            sandbox.config("trace/allow_unsupp_socket:x"),
            Err(Errno::EINVAL)
        );
        assert_eq!(
            sandbox.config("trace/allow_unsupp_socket:☮"),
            Err(Errno::EINVAL)
        );

        assert_eq!(sandbox.config("trace/memory_access:0"), Ok(()));
        assert_eq!(sandbox.config("trace/memory_access:1"), Ok(()));
        assert_eq!(
            sandbox.config("trace/memory_access_invalid:t"),
            Err(Errno::EINVAL)
        );
        assert_eq!(sandbox.config("trace/memory_access!x"), Err(Errno::EINVAL));
        assert_eq!(sandbox.config("trace/memory_access:x"), Err(Errno::EINVAL));
        assert_eq!(sandbox.config("trace/memory_access:t"), Err(Errno::EINVAL));
        assert_eq!(sandbox.config("trace/memory_access:☮"), Err(Errno::EINVAL));
        assert_eq!(sandbox.config("trace/memory_access:f"), Err(Errno::EINVAL));

        Ok(())
    }

    #[test]
    fn sandbox_config_safesetid_1() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.transit_uids.len(), 0, "{sandbox}");
        assert_eq!(sandbox.transit_gids.len(), 0, "{sandbox}");

        // Invalid syntax
        assert_eq!(sandbox.config("setuid:0:65534"), Err(Errno::EINVAL));
        assert_eq!(sandbox.config("setuid:0:0"), Err(Errno::EINVAL));
        assert_eq!(sandbox.config("setgid:0:65534"), Err(Errno::EINVAL));
        assert_eq!(sandbox.config("setgid:0:0"), Err(Errno::EINVAL));

        Ok(())
    }

    #[test]
    fn sandbox_config_safesetid_2() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.transit_uids.len(), 0, "{sandbox}");
        assert_eq!(sandbox.transit_gids.len(), 0, "{sandbox}");

        // ROOT not allowed in target.
        assert_eq!(sandbox.config("setuid+0:0"), Err(Errno::EACCES));
        assert_eq!(sandbox.config("setgid+0:0"), Err(Errno::EACCES));
        assert_eq!(sandbox.config("setuid+1:0"), Err(Errno::EACCES));
        assert_eq!(sandbox.config("setgid+1:0"), Err(Errno::EACCES));
        assert_eq!(sandbox.config("setuid+65534:0"), Err(Errno::EACCES));
        assert_eq!(sandbox.config("setgid+65534:0"), Err(Errno::EACCES));

        Ok(())
    }

    #[test]
    fn sandbox_config_safesetid_3() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.transit_uids.len(), 0, "{sandbox}");
        assert_eq!(sandbox.transit_gids.len(), 0, "{sandbox}");

        // ID escalation is not allowed.
        assert_eq!(sandbox.config("setuid+65534:42"), Err(Errno::EACCES));
        assert_eq!(sandbox.config("setgid+65534:42"), Err(Errno::EACCES));

        Ok(())
    }

    #[test]
    fn sandbox_config_safesetid_4() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.transit_uids.len(), 0, "{sandbox}");
        assert_eq!(sandbox.transit_gids.len(), 0, "{sandbox}");

        // Same ID is meaningless and is disallowed.
        assert_eq!(sandbox.config("setuid+1:1"), Err(Errno::EACCES));
        assert_eq!(sandbox.config("setgid+1:1"), Err(Errno::EACCES));
        assert_eq!(sandbox.config("setuid+65534:65534"), Err(Errno::EACCES));
        assert_eq!(sandbox.config("setgid+65534:65534"), Err(Errno::EACCES));

        Ok(())
    }

    #[test]
    fn sandbox_config_safesetid_5() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.transit_uids.len(), 0, "{sandbox}");
        assert_eq!(sandbox.transit_gids.len(), 0, "{sandbox}");

        assert_eq!(sandbox.config("setuid+0:65534"), Ok(()));
        assert_eq!(sandbox.transit_uids.len(), 1, "{sandbox}");
        assert_eq!(sandbox.transit_uids[0].0, Uid::from_raw(0), "{sandbox}");
        assert_eq!(sandbox.transit_uids[0].1, Uid::from_raw(65534), "{sandbox}");
        assert_eq!(sandbox.config("setuid+0:65534"), Ok(()));
        assert_eq!(sandbox.transit_uids.len(), 1, "{sandbox}");
        assert_eq!(sandbox.config("setuid+0:65534"), Ok(()));
        assert_eq!(sandbox.transit_uids.len(), 1, "{sandbox}");
        assert_eq!(sandbox.config("setuid-0:65534"), Ok(()));
        assert_eq!(sandbox.transit_uids.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_safesetid_6() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.transit_uids.len(), 0, "{sandbox}");
        assert_eq!(sandbox.transit_gids.len(), 0, "{sandbox}");

        assert_eq!(sandbox.config("setgid+0:65534"), Ok(()));
        assert_eq!(sandbox.transit_gids.len(), 1, "{sandbox}");
        assert_eq!(sandbox.transit_gids[0].0, Gid::from_raw(0), "{sandbox}");
        assert_eq!(sandbox.transit_gids[0].1, Gid::from_raw(65534), "{sandbox}");
        assert_eq!(sandbox.config("setgid+0:65534"), Ok(()));
        assert_eq!(sandbox.transit_gids.len(), 1, "{sandbox}");
        assert_eq!(sandbox.config("setgid+0:65534"), Ok(()));
        assert_eq!(sandbox.transit_gids.len(), 1, "{sandbox}");
        assert_eq!(sandbox.config("setgid-0:65534"), Ok(()));
        assert_eq!(sandbox.transit_gids.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_safesetid_7() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.transit_uids.len(), 0, "{sandbox}");
        assert_eq!(sandbox.transit_gids.len(), 0, "{sandbox}");

        // Adding a transition with same source but diff target fails.
        assert_eq!(sandbox.config("setuid+0:65534"), Ok(()));
        assert_eq!(sandbox.transit_uids.len(), 1, "{sandbox}");
        assert_eq!(sandbox.transit_uids[0].0, Uid::from_raw(0), "{sandbox}");
        assert_eq!(sandbox.transit_uids[0].1, Uid::from_raw(65534), "{sandbox}");
        assert_eq!(sandbox.config("setuid+0:65534"), Ok(()));
        assert_eq!(sandbox.transit_uids.len(), 1, "{sandbox}");
        assert_eq!(sandbox.config("setuid+0:1"), Err(Errno::EEXIST));
        // Removing the transition and then readding with diff target is OK.
        assert_eq!(sandbox.config("setuid-0:65534"), Ok(()));
        assert_eq!(sandbox.transit_uids.len(), 0, "{sandbox}");
        assert_eq!(sandbox.config("setuid+0:1"), Ok(()));
        assert_eq!(sandbox.transit_uids.len(), 1, "{sandbox}");
        assert_eq!(sandbox.transit_uids[0].0, Uid::from_raw(0), "{sandbox}");
        assert_eq!(sandbox.transit_uids[0].1, Uid::from_raw(1), "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_safesetid_8() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.transit_uids.len(), 0, "{sandbox}");
        assert_eq!(sandbox.transit_gids.len(), 0, "{sandbox}");

        // Adding a transition with same source but diff target fails.
        assert_eq!(sandbox.config("setgid+0:65534"), Ok(()));
        assert_eq!(sandbox.transit_gids.len(), 1, "{sandbox}");
        assert_eq!(sandbox.transit_gids[0].0, Gid::from_raw(0), "{sandbox}");
        assert_eq!(sandbox.transit_gids[0].1, Gid::from_raw(65534), "{sandbox}");
        assert_eq!(sandbox.config("setgid+0:65534"), Ok(()));
        assert_eq!(sandbox.transit_gids.len(), 1, "{sandbox}");
        assert_eq!(sandbox.config("setgid+0:1"), Err(Errno::EEXIST));
        // Removing the transition and then readding with diff target is OK.
        assert_eq!(sandbox.config("setgid-0:65534"), Ok(()));
        assert_eq!(sandbox.transit_gids.len(), 0, "{sandbox}");
        assert_eq!(sandbox.config("setgid+0:1"), Ok(()));
        assert_eq!(sandbox.transit_gids.len(), 1, "{sandbox}");
        assert_eq!(sandbox.transit_gids[0].0, Gid::from_raw(0), "{sandbox}");
        assert_eq!(sandbox.transit_gids[0].1, Gid::from_raw(1), "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_safesetid_9() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.transit_uids.len(), 0, "{sandbox}");
        assert_eq!(sandbox.transit_gids.len(), 0, "{sandbox}");

        assert_eq!(sandbox.config("setuid+0:1"), Ok(()));
        assert_eq!(sandbox.config("setuid+1:2"), Ok(()));
        assert_eq!(sandbox.config("setuid+2:3"), Ok(()));
        assert_eq!(sandbox.transit_uids.len(), 3, "{sandbox}");
        assert_eq!(sandbox.transit_uids[0].0, Uid::from_raw(0), "{sandbox}");
        assert_eq!(sandbox.transit_uids[0].1, Uid::from_raw(1), "{sandbox}");
        assert_eq!(sandbox.transit_uids[1].0, Uid::from_raw(1), "{sandbox}");
        assert_eq!(sandbox.transit_uids[1].1, Uid::from_raw(2), "{sandbox}");
        assert_eq!(sandbox.transit_uids[2].0, Uid::from_raw(2), "{sandbox}");
        assert_eq!(sandbox.transit_uids[2].1, Uid::from_raw(3), "{sandbox}");
        assert_eq!(sandbox.config("setuid^"), Ok(()));
        assert_eq!(sandbox.transit_uids.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_safesetid_10() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.transit_uids.len(), 0, "{sandbox}");
        assert_eq!(sandbox.transit_gids.len(), 0, "{sandbox}");

        assert_eq!(sandbox.config("setgid+0:1"), Ok(()));
        assert_eq!(sandbox.config("setgid+1:2"), Ok(()));
        assert_eq!(sandbox.config("setgid+2:3"), Ok(()));
        assert_eq!(sandbox.transit_gids.len(), 3, "{sandbox}");
        assert_eq!(sandbox.transit_gids[0].0, Gid::from_raw(0), "{sandbox}");
        assert_eq!(sandbox.transit_gids[0].1, Gid::from_raw(1), "{sandbox}");
        assert_eq!(sandbox.transit_gids[1].0, Gid::from_raw(1), "{sandbox}");
        assert_eq!(sandbox.transit_gids[1].1, Gid::from_raw(2), "{sandbox}");
        assert_eq!(sandbox.transit_gids[2].0, Gid::from_raw(2), "{sandbox}");
        assert_eq!(sandbox.transit_gids[2].1, Gid::from_raw(3), "{sandbox}");
        assert_eq!(sandbox.config("setgid^"), Ok(()));
        assert_eq!(sandbox.transit_gids.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_safesetid_11() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.transit_uids.len(), 0, "{sandbox}");
        assert_eq!(sandbox.transit_gids.len(), 0, "{sandbox}");

        assert_eq!(sandbox.config("setuid+0:1"), Ok(()));
        assert_eq!(sandbox.config("setuid+1:2"), Ok(()));
        assert_eq!(sandbox.config("setuid+2:3"), Ok(()));
        assert_eq!(sandbox.transit_uids.len(), 3, "{sandbox}");
        assert_eq!(sandbox.transit_uids[0].0, Uid::from_raw(0), "{sandbox}");
        assert_eq!(sandbox.transit_uids[0].1, Uid::from_raw(1), "{sandbox}");
        assert_eq!(sandbox.transit_uids[1].0, Uid::from_raw(1), "{sandbox}");
        assert_eq!(sandbox.transit_uids[1].1, Uid::from_raw(2), "{sandbox}");
        assert_eq!(sandbox.transit_uids[2].0, Uid::from_raw(2), "{sandbox}");
        assert_eq!(sandbox.transit_uids[2].1, Uid::from_raw(3), "{sandbox}");
        assert_eq!(sandbox.config("setuid^0:1"), Err(Errno::EINVAL));
        assert_eq!(sandbox.config("setuid^0"), Ok(()));
        assert_eq!(sandbox.transit_uids.len(), 2, "{sandbox}");
        assert_eq!(sandbox.transit_uids[0].0, Uid::from_raw(1), "{sandbox}");
        assert_eq!(sandbox.transit_uids[0].1, Uid::from_raw(2), "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_safesetid_12() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.transit_uids.len(), 0, "{sandbox}");
        assert_eq!(sandbox.transit_gids.len(), 0, "{sandbox}");

        assert_eq!(sandbox.config("setgid+0:1"), Ok(()));
        assert_eq!(sandbox.config("setgid+1:2"), Ok(()));
        assert_eq!(sandbox.config("setgid+2:3"), Ok(()));
        assert_eq!(sandbox.transit_gids.len(), 3, "{sandbox}");
        assert_eq!(sandbox.transit_gids[0].0, Gid::from_raw(0), "{sandbox}");
        assert_eq!(sandbox.transit_gids[0].1, Gid::from_raw(1), "{sandbox}");
        assert_eq!(sandbox.transit_gids[1].0, Gid::from_raw(1), "{sandbox}");
        assert_eq!(sandbox.transit_gids[1].1, Gid::from_raw(2), "{sandbox}");
        assert_eq!(sandbox.transit_gids[2].0, Gid::from_raw(2), "{sandbox}");
        assert_eq!(sandbox.transit_gids[2].1, Gid::from_raw(3), "{sandbox}");
        assert_eq!(sandbox.config("setgid^0:1"), Err(Errno::EINVAL));
        assert_eq!(sandbox.config("setgid^0"), Ok(()));
        assert_eq!(sandbox.transit_gids.len(), 2, "{sandbox}");
        assert_eq!(sandbox.transit_gids[0].0, Gid::from_raw(1), "{sandbox}");
        assert_eq!(sandbox.transit_gids[0].1, Gid::from_raw(2), "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_safesetuser_1() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.transit_uids.len(), 0, "{sandbox}");
        assert_eq!(sandbox.transit_gids.len(), 0, "{sandbox}");

        // Invalid syntax
        assert_eq!(sandbox.config("setuid:root:nobody"), Err(Errno::EINVAL));
        assert_eq!(sandbox.config("setuid:root:root"), Err(Errno::EINVAL));
        assert_eq!(sandbox.config("setgid:root:nobody"), Err(Errno::EINVAL));
        assert_eq!(sandbox.config("setgid:root:root"), Err(Errno::EINVAL));

        Ok(())
    }

    #[test]
    fn sandbox_config_safesetuser_2() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.transit_uids.len(), 0, "{sandbox}");
        assert_eq!(sandbox.transit_gids.len(), 0, "{sandbox}");

        // ROOT not allowed in target.
        assert_eq!(sandbox.config("setuid+root:root"), Err(Errno::EACCES));
        assert_eq!(sandbox.config("setgid+root:root"), Err(Errno::EACCES));
        assert_eq!(sandbox.config("setuid+nobody:root"), Err(Errno::EACCES));
        if let Ok((_, nogroup)) = get_nogroup() {
            assert_eq!(
                sandbox.config(&format!("setgid+{nogroup}:root")),
                Err(Errno::EACCES)
            );
        }

        Ok(())
    }

    #[test]
    fn sandbox_config_safesetuser_3() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.transit_uids.len(), 0, "{sandbox}");
        assert_eq!(sandbox.transit_gids.len(), 0, "{sandbox}");

        // Same ID is meaningless and is disallowed.
        assert_eq!(sandbox.config("setuid+nobody:nobody"), Err(Errno::EACCES));
        if let Ok((_, nogroup)) = get_nogroup() {
            assert_eq!(
                sandbox.config(&format!("setgid+{nogroup}:{nogroup}")),
                Err(Errno::EACCES)
            );
        }

        Ok(())
    }

    #[test]
    fn sandbox_config_safesetuser_4() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.transit_uids.len(), 0, "{sandbox}");
        assert_eq!(sandbox.transit_gids.len(), 0, "{sandbox}");

        assert_eq!(sandbox.config("setuid+root:nobody"), Ok(()));
        assert_eq!(sandbox.transit_uids.len(), 1, "{sandbox}");
        assert_eq!(sandbox.transit_uids[0].0, Uid::from_raw(0), "{sandbox}");
        assert_eq!(sandbox.transit_uids[0].1, Uid::from_raw(65534), "{sandbox}");
        assert_eq!(sandbox.config("setuid+root:nobody"), Ok(()));
        assert_eq!(sandbox.transit_uids.len(), 1, "{sandbox}");
        assert_eq!(sandbox.config("setuid+root:nobody"), Ok(()));
        assert_eq!(sandbox.transit_uids.len(), 1, "{sandbox}");
        assert_eq!(sandbox.config("setuid-root:nobody"), Ok(()));
        assert_eq!(sandbox.transit_uids.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_safesetuser_5() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.transit_uids.len(), 0, "{sandbox}");
        assert_eq!(sandbox.transit_gids.len(), 0, "{sandbox}");

        let (nogroup_gid, nogroup) = match get_nogroup() {
            Ok((nogroup_gid, nogroup)) => (nogroup_gid, nogroup),
            Err(_) => return Ok(()), // should not happen, skip.
        };

        assert_eq!(sandbox.config(&format!("setgid+root:{nogroup}")), Ok(()));
        assert_eq!(sandbox.transit_gids.len(), 1, "{sandbox}");
        assert_eq!(sandbox.transit_gids[0].0, Gid::from_raw(0), "{sandbox}");
        assert_eq!(sandbox.transit_gids[0].1, nogroup_gid, "{sandbox}");
        assert_eq!(sandbox.config(&format!("setgid+root:{nogroup}")), Ok(()));
        assert_eq!(sandbox.transit_gids.len(), 1, "{sandbox}");
        assert_eq!(sandbox.config(&format!("setgid+root:{nogroup}")), Ok(()));
        assert_eq!(sandbox.transit_gids.len(), 1, "{sandbox}");
        assert_eq!(sandbox.config(&format!("setgid-root:{nogroup}")), Ok(()));
        assert_eq!(sandbox.transit_gids.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_safesetuser_6() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.transit_uids.len(), 0, "{sandbox}");
        assert_eq!(sandbox.transit_gids.len(), 0, "{sandbox}");

        // Adding a transition with same source but diff target fails.
        assert_eq!(sandbox.config("setuid+root:nobody"), Ok(()));
        assert_eq!(sandbox.transit_uids.len(), 1, "{sandbox}");
        assert_eq!(sandbox.transit_uids[0].0, Uid::from_raw(0), "{sandbox}");
        assert_eq!(sandbox.transit_uids[0].1, Uid::from_raw(65534), "{sandbox}");
        assert_eq!(sandbox.config("setuid+root:nobody"), Ok(()));
        assert_eq!(sandbox.transit_uids.len(), 1, "{sandbox}");
        assert_eq!(sandbox.config("setuid+root:1"), Err(Errno::EEXIST));
        // Removing the transition and then readding with diff target is OK.
        assert_eq!(sandbox.config("setuid-root:nobody"), Ok(()));
        assert_eq!(sandbox.transit_uids.len(), 0, "{sandbox}");
        assert_eq!(sandbox.config("setuid+root:1"), Ok(()));
        assert_eq!(sandbox.transit_uids.len(), 1, "{sandbox}");
        assert_eq!(sandbox.transit_uids[0].0, Uid::from_raw(0), "{sandbox}");
        assert_eq!(sandbox.transit_uids[0].1, Uid::from_raw(1), "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_safesetuser_7() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.transit_uids.len(), 0, "{sandbox}");
        assert_eq!(sandbox.transit_gids.len(), 0, "{sandbox}");

        let (nogroup_gid, nogroup) = match get_nogroup() {
            Ok((nogroup_gid, nogroup)) => (nogroup_gid, nogroup),
            Err(_) => return Ok(()), // should not happen, skip.
        };

        // Adding a transition with same source but diff target fails.
        assert_eq!(sandbox.config(&format!("setgid+root:{nogroup}")), Ok(()));
        assert_eq!(sandbox.transit_gids.len(), 1, "{sandbox}");
        assert_eq!(sandbox.transit_gids[0].0, Gid::from_raw(0), "{sandbox}");
        assert_eq!(sandbox.transit_gids[0].1, nogroup_gid, "{sandbox}");
        assert_eq!(sandbox.config(&format!("setgid+root:{nogroup}")), Ok(()));
        assert_eq!(sandbox.transit_gids.len(), 1, "{sandbox}");
        assert_eq!(sandbox.config("setgid+root:1"), Err(Errno::EEXIST));
        // Removing the transition and then readding with diff target is OK.
        assert_eq!(sandbox.config(&format!("setgid-root:{nogroup}")), Ok(()));
        assert_eq!(sandbox.transit_gids.len(), 0, "{sandbox}");
        assert_eq!(sandbox.config("setgid+root:1"), Ok(()));
        assert_eq!(sandbox.transit_gids.len(), 1, "{sandbox}");
        assert_eq!(sandbox.transit_gids[0].0, Gid::from_raw(0), "{sandbox}");
        assert_eq!(sandbox.transit_gids[0].1, Gid::from_raw(1), "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_safesetuser_8() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.transit_uids.len(), 0, "{sandbox}");
        assert_eq!(sandbox.transit_gids.len(), 0, "{sandbox}");

        assert_eq!(sandbox.config("setuid+root:1"), Ok(()));
        assert_eq!(sandbox.config("setuid+1:2"), Ok(()));
        assert_eq!(sandbox.config("setuid+2:3"), Ok(()));
        assert_eq!(sandbox.transit_uids.len(), 3, "{sandbox}");
        assert_eq!(sandbox.transit_uids[0].0, Uid::from_raw(0), "{sandbox}");
        assert_eq!(sandbox.transit_uids[0].1, Uid::from_raw(1), "{sandbox}");
        assert_eq!(sandbox.transit_uids[1].0, Uid::from_raw(1), "{sandbox}");
        assert_eq!(sandbox.transit_uids[1].1, Uid::from_raw(2), "{sandbox}");
        assert_eq!(sandbox.transit_uids[2].0, Uid::from_raw(2), "{sandbox}");
        assert_eq!(sandbox.transit_uids[2].1, Uid::from_raw(3), "{sandbox}");
        assert_eq!(sandbox.config("setuid^"), Ok(()));
        assert_eq!(sandbox.transit_uids.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_safesetuser_9() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.transit_uids.len(), 0, "{sandbox}");
        assert_eq!(sandbox.transit_gids.len(), 0, "{sandbox}");

        assert_eq!(sandbox.config("setgid+root:1"), Ok(()));
        assert_eq!(sandbox.config("setgid+1:2"), Ok(()));
        assert_eq!(sandbox.config("setgid+2:3"), Ok(()));
        assert_eq!(sandbox.transit_gids.len(), 3, "{sandbox}");
        assert_eq!(sandbox.transit_gids[0].0, Gid::from_raw(0), "{sandbox}");
        assert_eq!(sandbox.transit_gids[0].1, Gid::from_raw(1), "{sandbox}");
        assert_eq!(sandbox.transit_gids[1].0, Gid::from_raw(1), "{sandbox}");
        assert_eq!(sandbox.transit_gids[1].1, Gid::from_raw(2), "{sandbox}");
        assert_eq!(sandbox.transit_gids[2].0, Gid::from_raw(2), "{sandbox}");
        assert_eq!(sandbox.transit_gids[2].1, Gid::from_raw(3), "{sandbox}");
        assert_eq!(sandbox.config("setgid^"), Ok(()));
        assert_eq!(sandbox.transit_gids.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_safesetuser_10() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.transit_uids.len(), 0, "{sandbox}");
        assert_eq!(sandbox.transit_gids.len(), 0, "{sandbox}");

        assert_eq!(sandbox.config("setuid+root:1"), Ok(()));
        assert_eq!(sandbox.config("setuid+1:2"), Ok(()));
        assert_eq!(sandbox.config("setuid+2:3"), Ok(()));
        assert_eq!(sandbox.transit_uids.len(), 3, "{sandbox}");
        assert_eq!(sandbox.transit_uids[0].0, Uid::from_raw(0), "{sandbox}");
        assert_eq!(sandbox.transit_uids[0].1, Uid::from_raw(1), "{sandbox}");
        assert_eq!(sandbox.transit_uids[1].0, Uid::from_raw(1), "{sandbox}");
        assert_eq!(sandbox.transit_uids[1].1, Uid::from_raw(2), "{sandbox}");
        assert_eq!(sandbox.transit_uids[2].0, Uid::from_raw(2), "{sandbox}");
        assert_eq!(sandbox.transit_uids[2].1, Uid::from_raw(3), "{sandbox}");
        assert_eq!(sandbox.config("setuid^root:1"), Err(Errno::EINVAL));
        assert_eq!(sandbox.config("setuid^root"), Ok(()));
        assert_eq!(sandbox.transit_uids.len(), 2, "{sandbox}");
        assert_eq!(sandbox.transit_uids[0].0, Uid::from_raw(1), "{sandbox}");
        assert_eq!(sandbox.transit_uids[0].1, Uid::from_raw(2), "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_safesetuser_11() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.transit_uids.len(), 0, "{sandbox}");
        assert_eq!(sandbox.transit_gids.len(), 0, "{sandbox}");

        assert_eq!(sandbox.config("setgid+root:1"), Ok(()));
        assert_eq!(sandbox.config("setgid+1:2"), Ok(()));
        assert_eq!(sandbox.config("setgid+2:3"), Ok(()));
        assert_eq!(sandbox.transit_gids.len(), 3, "{sandbox}");
        assert_eq!(sandbox.transit_gids[0].0, Gid::from_raw(0), "{sandbox}");
        assert_eq!(sandbox.transit_gids[0].1, Gid::from_raw(1), "{sandbox}");
        assert_eq!(sandbox.transit_gids[1].0, Gid::from_raw(1), "{sandbox}");
        assert_eq!(sandbox.transit_gids[1].1, Gid::from_raw(2), "{sandbox}");
        assert_eq!(sandbox.transit_gids[2].0, Gid::from_raw(2), "{sandbox}");
        assert_eq!(sandbox.transit_gids[2].1, Gid::from_raw(3), "{sandbox}");
        assert_eq!(sandbox.config("setgid^root:1"), Err(Errno::EINVAL));
        assert_eq!(sandbox.config("setgid^root"), Ok(()));
        assert_eq!(sandbox.transit_gids.len(), 2, "{sandbox}");
        assert_eq!(sandbox.transit_gids[0].0, Gid::from_raw(1), "{sandbox}");
        assert_eq!(sandbox.transit_gids[0].1, Gid::from_raw(2), "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_1() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.glob_rules().len();

        sandbox.config("allow/read+/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 1, "{sandbox}");

        sandbox.config("allow/read-/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_2() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.glob_rules().len();

        sandbox.config("allow/read+/usr")?;
        sandbox.config("allow/read+/usr/**")?;
        sandbox.config("allow/read+/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 3, "{sandbox}");

        sandbox.config("allow/read^/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 1, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_3() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.glob_rules().len();

        sandbox.config("allow/write+/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 1, "{sandbox}");
        sandbox.config("allow/write-/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_4() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.glob_rules().len();

        sandbox.config("allow/write+/usr")?;
        sandbox.config("allow/write+/usr/**")?;
        sandbox.config("allow/write+/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 3, "{sandbox}");
        sandbox.config("allow/write^/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 1, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_5() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.glob_rules().len();

        sandbox.config("allow/exec+/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 1, "{sandbox}");
        sandbox.config("allow/exec-/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_6() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.glob_rules().len();

        sandbox.config("allow/exec+/usr")?;
        sandbox.config("allow/exec+/usr/**")?;
        sandbox.config("allow/exec+/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 3, "{sandbox}");
        sandbox.config("allow/exec^/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 1, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_7() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.glob_rules().len();

        sandbox.config("allow/net/bind+/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 1, "{sandbox}");
        sandbox.config("allow/net/bind-/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_8() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.glob_rules().len();

        sandbox.config("allow/net/bind+/usr/**")?;
        sandbox.config("allow/net/bind+/usr")?;
        sandbox.config("allow/net/bind+/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 3, "{sandbox}");
        sandbox.config("allow/net/bind^/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 1, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_9() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.glob_rules().len();

        sandbox.config("allow/net/connect+/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 1, "{sandbox}");
        sandbox.config("allow/net/connect-/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_10() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.glob_rules().len();

        sandbox.config("allow/net/connect+/usr/**")?;
        sandbox.config("allow/net/connect+/usr/**")?;
        sandbox.config("allow/net/connect+/usr")?;
        assert_eq!(sandbox.glob_rules().len(), len + 3, "{sandbox}");
        sandbox.config("allow/net/connect^/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 1, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_11() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/bind+127.0.0.0/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("allow/net/bind-127.0.0.0/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_12() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/bind+127.0.0.0/8!1024")?;
        sandbox.config("allow/net/bind+127.0.0.0/8!1024-65535")?;
        sandbox.config("allow/net/bind+127.0.0.0/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("allow/net/bind^127.0.0.0/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_13() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/connect+127.0.0.0/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("allow/net/connect-127.0.0.0/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_14() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/connect+127.0.0.0/8!1024-65535")?;
        sandbox.config("allow/net/connect+127.0.0.0/7!1024-65535")?;
        sandbox.config("allow/net/connect+127.0.0.0/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("allow/net/connect^127.0.0.0/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_15() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/bind+::1/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("allow/net/bind-::1/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_16() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/bind+::1/8!1024-65535")?;
        sandbox.config("allow/net/bind+::1/8!1024-65535")?;
        sandbox.config("allow/net/bind+::1/8!1024-65525")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("allow/net/bind^::1/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_17() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/connect+::1/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("allow/net/connect-::1/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_18() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/connect+::1/8!1024-65535")?;
        sandbox.config("allow/net/connect+::1/8!1024-65535")?;
        sandbox.config("allow/net/connect+::1/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("allow/net/connect^::1/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_19() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.glob_rules().len();

        sandbox.config("deny/read+/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 1, "{sandbox}");
        sandbox.config("deny/read-/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_20() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.glob_rules().len();

        sandbox.config("deny/read+/usr/**")?;
        sandbox.config("deny/read+/usr/*")?;
        sandbox.config("deny/read+/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 3, "{sandbox}");
        sandbox.config("deny/read^/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 1, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_21() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.glob_rules().len();

        sandbox.config("deny/write+/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 1, "{sandbox}");
        sandbox.config("deny/write-/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_22() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.glob_rules().len();

        sandbox.config("deny/write+/usr/**")?;
        sandbox.config("deny/write+/usr/**")?;
        sandbox.config("deny/write+/usr/*")?;
        assert_eq!(sandbox.glob_rules().len(), len + 3, "{sandbox}");
        sandbox.config("deny/write^/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 1, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_23() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.glob_rules().len();

        sandbox.config("deny/exec+/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 1, "{sandbox}");
        sandbox.config("deny/exec-/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_24() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.glob_rules().len();

        sandbox.config("deny/exec+/usr/**")?;
        sandbox.config("deny/exec+/usr/**")?;
        sandbox.config("deny/exec+/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 3, "{sandbox}");
        sandbox.config("deny/exec^/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_25() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.glob_rules().len();

        sandbox.config("deny/net/bind+/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 1, "{sandbox}");
        sandbox.config("deny/net/bind-/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_26() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.glob_rules().len();

        sandbox.config("deny/net/bind+/usr")?;
        sandbox.config("deny/net/bind+/usr/*")?;
        sandbox.config("deny/net/bind+/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 3, "{sandbox}");
        sandbox.config("deny/net/bind-/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 2, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_27() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.glob_rules().len();

        sandbox.config("deny/net/connect+/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 1, "{sandbox}");
        sandbox.config("deny/net/connect-/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_28() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.glob_rules().len();

        sandbox.config("deny/net/connect+/usr/**")?;
        sandbox.config("deny/net/connect+/usr/*")?;
        sandbox.config("deny/net/connect+/usr")?;
        assert_eq!(sandbox.glob_rules().len(), len + 3, "{sandbox}");
        sandbox.config("deny/net/connect^/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 2, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_29() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/bind+127.0.0.0/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("deny/net/bind-127.0.0.0/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_30() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/bind+127.0.1.0/8!1024-65535")?;
        sandbox.config("deny/net/bind+127.0.0.1/8!1024-65535")?;
        sandbox.config("deny/net/bind+127.0.0.0/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("deny/net/bind^127.0.0.0/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 2, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_31() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/connect+127.0.0.0/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("deny/net/connect-127.0.0.0/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_32() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/connect+127.0.0.0/8!1024-65535")?;
        sandbox.config("deny/net/connect+127.0.0.1/8!1024-65535")?;
        sandbox.config("deny/net/connect+127.0.0.0/8!1024-65535")?;
        sandbox.config("deny/net/connect+127.0.1.0/8!1024-65535")?;
        sandbox.config("deny/net/connect+127.0.0.0/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 5, "{sandbox}");
        sandbox.config("deny/net/connect^127.0.0.0/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 2, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_33() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/bind+::1/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("deny/net/bind-::1/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_34() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/bind+::1/16!1024-65535")?;
        sandbox.config("deny/net/bind+::1/8!1024-65535")?;
        sandbox.config("deny/net/bind+::1/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("deny/net/bind^::1/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_35() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/connect+::1/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("deny/net/connect-::1/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_36() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/connect+::1/8!1024-65535")?;
        sandbox.config("deny/net/connect+::1/8!1024-65535")?;
        sandbox.config("deny/net/connect+::1!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("deny/net/connect^::1/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_37() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.glob_rules().len();

        sandbox.config("filter/read+/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 1, "{sandbox}");
        sandbox.config("filter/read-/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_38() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.glob_rules().len();

        sandbox.config("filter/read+/usr/**")?;
        sandbox.config("filter/read+/usr/**")?;
        sandbox.config("filter/read+/usr/*")?;
        assert_eq!(sandbox.glob_rules().len(), len + 3, "{sandbox}");
        sandbox.config("filter/read^/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 1, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_39() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.glob_rules().len();

        sandbox.config("filter/write+/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 1, "{sandbox}");
        sandbox.config("filter/write-/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_40() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.glob_rules().len();

        sandbox.config("filter/write+/usr/**/")?;
        sandbox.config("filter/write+/usr/**")?;
        sandbox.config("filter/write+/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 3, "{sandbox}");
        sandbox.config("filter/write^/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 1, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_41() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.glob_rules().len();

        sandbox.config("filter/exec+/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 1, "{sandbox}");
        sandbox.config("filter/exec-/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_42() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.glob_rules().len();

        sandbox.config("filter/exec+/usr/**")?;
        sandbox.config("filter/exec+/usr/*")?;
        sandbox.config("filter/exec+/usr/**")?;
        sandbox.config("filter/exec+/usr/./**")?;
        sandbox.config("filter/exec+/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 5, "{sandbox}");
        sandbox.config("filter/exec^/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 2, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_43() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.glob_rules().len();

        sandbox.config("filter/net/bind+/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 1, "{sandbox}");
        sandbox.config("filter/net/bind-/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_44() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.glob_rules().len();

        sandbox.config("filter/net/bind+/usr/**")?;
        sandbox.config("filter/net/bind+/usr/**")?;
        sandbox.config("filter/net/bind+/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 3, "{sandbox}");
        sandbox.config("filter/net/bind^/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_45() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.glob_rules().len();

        sandbox.config("filter/net/connect+/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 1, "{sandbox}");
        sandbox.config("filter/net/connect-/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_46() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.glob_rules().len();

        sandbox.config("filter/net/connect+/usr/**")?;
        sandbox.config("filter/net/connect+/usr/**/")?;
        sandbox.config("filter/net/connect+/usr/*")?;
        assert_eq!(sandbox.glob_rules().len(), len + 3, "{sandbox}");
        sandbox.config("filter/net/connect-/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 2, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_47() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/bind+127.0.0.0/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("filter/net/bind-127.0.0.0/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_48() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/bind+127.0.0.0/8!1024-65535")?;
        sandbox.config("filter/net/bind+127.0.0.0/8!1024-65535")?;
        sandbox.config("filter/net/bind+127.0.0.0/8!1023-65535")?;
        sandbox.config("filter/net/bind+127.0.0.0/8!1023-65534")?;
        assert_eq!(sandbox.cidr_rules.len(), 4, "{sandbox}");
        sandbox.config("filter/net/bind^127.0.0.0/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 2, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_49() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/connect+127.0.0.0/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("filter/net/connect-127.0.0.0/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_50() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/connect+127.0.0.0/8!1024-65534")?;
        sandbox.config("filter/net/connect+127.0.0.0/8!1024-65535")?;
        sandbox.config("filter/net/connect+127.0.0.1/8!1024-65535")?;
        sandbox.config("filter/net/connect+127.0.0.0/8!1024-65535")?;
        sandbox.config("filter/net/connect+127.0.0.0/8!1025-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 5, "{sandbox}");
        sandbox.config("filter/net/connect^127.0.0.0/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_51() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/bind+::1/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("filter/net/bind-::1/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_52() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/bind+::1/8!1024-65535")?;
        sandbox.config("filter/net/bind+::1/8!1024-65535")?;
        sandbox.config("filter/net/bind+::1/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("filter/net/bind^::1/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_53() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/connect+::1/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("filter/net/connect-::1/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_54() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/connect+::1/8!1024-65535")?;
        sandbox.config("filter/net/connect+::1/8!1024-65535")?;
        sandbox.config("filter/net/connect+::1/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("filter/net/connect^::1/8!1024-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_55() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/bind+loopback4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("allow/net/bind-loopback4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_56() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/bind+loopback4!0")?;
        sandbox.config("allow/net/bind+loopback4!0")?;
        sandbox.config("allow/net/bind+loopback4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("allow/net/bind^loopback4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_57() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/connect+loopback4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("allow/net/connect-loopback4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_58() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/connect+loopback4!0")?;
        sandbox.config("allow/net/connect+loopback4!0")?;
        sandbox.config("allow/net/connect+loopback4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("allow/net/connect^loopback4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_59() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/bind+loopback4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("deny/net/bind-loopback4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_60() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/bind+loopback4!0")?;
        sandbox.config("deny/net/bind+loopback4!0")?;
        sandbox.config("deny/net/bind+loopback4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("deny/net/bind^loopback4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_61() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/connect+loopback4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("deny/net/connect-loopback4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_62() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/connect+127.0.0.0/16!0-65535")?;
        sandbox.config("deny/net/connect+loopback4!0")?;
        sandbox.config("deny/net/connect+loopback4!0")?;
        sandbox.config("deny/net/connect+127.0.0.0/16!0-65535")?;
        sandbox.config("deny/net/connect+loopback4!0")?;
        sandbox.config("filter/net/connect+127.0.0.0/16!0-65535")?;
        sandbox.config("deny/net/connect+loopback4!0")?;
        sandbox.config("deny/net/bind+127.0.0.0/8!0-65535")?;
        assert_eq!(sandbox.cidr_rules.len(), 8, "{sandbox}");
        sandbox.config("deny/net/connect^loopback4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 4, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_63() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/bind+loopback4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("filter/net/bind-loopback4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_64() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/bind+loopback4!0")?;
        sandbox.config("filter/net/bind+loopback4!0")?;
        sandbox.config("filter/net/bind+loopback4!1")?;
        sandbox.config("filter/net/bind+loopback4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 4, "{sandbox}");
        sandbox.config("filter/net/bind^loopback4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_65() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/connect+loopback4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("filter/net/connect-loopback4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_66() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/connect+loopback4!0")?;
        sandbox.config("filter/net/connect+loopback4!0")?;
        sandbox.config("filter/net/connect+loopback4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("filter/net/connect^loopback4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_67() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/bind+loopback6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("allow/net/bind-loopback6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_68() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/bind+loopback6!0")?;
        sandbox.config("allow/net/bind+loopback6!0")?;
        sandbox.config("allow/net/bind+loopback6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("allow/net/bind^loopback6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_69() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/connect+loopback6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("allow/net/connect-loopback6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_70() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/connect+loopback6!0")?;
        sandbox.config("allow/net/connect+loopback6!0")?;
        sandbox.config("allow/net/connect+loopback6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("allow/net/connect^loopback6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_71() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/bind+loopback6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("deny/net/bind-loopback6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_72() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/bind+loopback6!0")?;
        sandbox.config("deny/net/bind+loopback6!0")?;
        sandbox.config("deny/net/bind+loopback6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("deny/net/bind^loopback6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_73() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/connect+loopback6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("deny/net/connect-loopback6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_74() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/connect+loopback6!0")?;
        sandbox.config("deny/net/connect+loopback6!0")?;
        sandbox.config("deny/net/connect+loopback6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("deny/net/connect^loopback6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_75() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/bind+loopback6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("filter/net/bind-loopback6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_76() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/bind+loopback6!0")?;
        sandbox.config("filter/net/bind+loopback6!0")?;
        sandbox.config("filter/net/bind+loopback6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("filter/net/bind^loopback6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_77() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/connect+loopback6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("filter/net/connect-loopback6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_78() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/connect+loopback6!0")?;
        sandbox.config("filter/net/connect+loopback6!0")?;
        sandbox.config("filter/net/connect+loopback6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("filter/net/connect^loopback6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_79() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/bind+loopback!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 2, "{sandbox}");
        sandbox.config("allow/net/bind-loopback!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_80() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/bind+loopback!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 2, "{sandbox}");
        sandbox.config("allow/net/bind-loopback!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_81() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/bind+loopback!0")?;
        sandbox.config("allow/net/bind+loopback!0")?;
        sandbox.config("allow/net/bind+loopback!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 6, "{sandbox}");
        sandbox.config("allow/net/bind^loopback!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_82() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/connect+loopback!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 2, "{sandbox}");
        sandbox.config("allow/net/connect-loopback!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_83() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/connect+loopback!0")?;
        sandbox.config("allow/net/connect+loopback!0")?;
        sandbox.config("allow/net/connect+loopback!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 6, "{sandbox}");
        sandbox.config("allow/net/connect^loopback!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_84() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/bind+loopback!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 2, "{sandbox}");
        sandbox.config("deny/net/bind-loopback!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_85() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/bind+loopback!0")?;
        sandbox.config("deny/net/bind+loopback!0")?;
        sandbox.config("deny/net/bind+loopback!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 6, "{sandbox}");
        sandbox.config("deny/net/bind^loopback!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_86() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/connect+loopback!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 2, "{sandbox}");
        sandbox.config("deny/net/connect-loopback!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_87() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/connect+loopback!0")?;
        sandbox.config("deny/net/connect+loopback!0")?;
        sandbox.config("deny/net/connect+loopback!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 6, "{sandbox}");
        sandbox.config("deny/net/connect^loopback!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_88() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/bind+loopback!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 2, "{sandbox}");
        sandbox.config("filter/net/bind-loopback!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_89() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/bind+loopback!0")?;
        sandbox.config("filter/net/bind+loopback!0")?;
        sandbox.config("filter/net/bind+loopback!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 6, "{sandbox}");
        sandbox.config("filter/net/bind^loopback!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_90() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/connect+loopback!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 2, "{sandbox}");
        sandbox.config("filter/net/connect-loopback!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_91() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/connect+loopback!0")?;
        sandbox.config("filter/net/connect+loopback!0")?;
        sandbox.config("filter/net/connect+loopback!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 6, "{sandbox}");
        sandbox.config("filter/net/connect^loopback!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_92() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/bind+local4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 4, "{sandbox}");
        sandbox.config("allow/net/bind-local4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_93() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/bind+local4!0")?;
        sandbox.config("allow/net/bind+local4!0")?;
        sandbox.config("allow/net/bind+local4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 12, "{sandbox}");
        sandbox.config("allow/net/bind^local4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_94() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/connect+local4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 4, "{sandbox}");
        sandbox.config("allow/net/connect-local4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_95() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/connect+local4!0")?;
        sandbox.config("allow/net/connect+local4!0")?;
        sandbox.config("allow/net/connect+local4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 12, "{sandbox}");
        sandbox.config("allow/net/connect^local4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_96() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/bind+local4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 4, "{sandbox}");
        sandbox.config("deny/net/bind-local4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_97() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/bind+local4!0")?;
        sandbox.config("deny/net/bind+local4!0")?;
        sandbox.config("deny/net/bind+local4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 12, "{sandbox}");
        sandbox.config("deny/net/bind^local4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_98() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/connect+local4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 4, "{sandbox}");
        sandbox.config("deny/net/connect-local4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_99() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/connect+local4!0")?;
        sandbox.config("deny/net/connect+local4!0")?;
        sandbox.config("deny/net/connect+local4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 12, "{sandbox}");
        sandbox.config("deny/net/connect^local4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_100() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/bind+local4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 4, "{sandbox}");
        sandbox.config("filter/net/bind-local4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_101() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/bind+local4!0")?;
        sandbox.config("filter/net/bind+local4!0")?;
        sandbox.config("filter/net/bind+local4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 12, "{sandbox}");
        sandbox.config("filter/net/bind^local4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_102() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/connect+local4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 4, "{sandbox}");
        sandbox.config("filter/net/connect-local4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_103() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/connect+local4!0")?;
        sandbox.config("filter/net/connect+local4!0")?;
        sandbox.config("filter/net/connect+local4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 12, "{sandbox}");
        sandbox.config("filter/net/connect^local4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_104() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/bind+local6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 4, "{sandbox}");
        sandbox.config("allow/net/bind-local6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_105() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/bind+local6!0")?;
        sandbox.config("allow/net/bind+local6!0")?;
        sandbox.config("allow/net/bind+local6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 12, "{sandbox}");
        sandbox.config("allow/net/bind^local6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_106() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/connect+local6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 4, "{sandbox}");
        sandbox.config("allow/net/connect-local6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_107() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/connect+local6!0")?;
        sandbox.config("allow/net/connect+local6!0")?;
        sandbox.config("allow/net/connect+local6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 12, "{sandbox}");
        sandbox.config("allow/net/connect^local6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_108() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/bind+local6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 4, "{sandbox}");
        sandbox.config("deny/net/bind-local6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_109() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/bind+local6!0")?;
        sandbox.config("deny/net/bind+local6!0")?;
        sandbox.config("deny/net/bind+local6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 12, "{sandbox}");
        sandbox.config("deny/net/bind^local6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_110() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/connect+local6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 4, "{sandbox}");
        sandbox.config("deny/net/connect-local6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_111() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/connect+local6!0")?;
        sandbox.config("deny/net/connect+local6!0")?;
        sandbox.config("deny/net/connect+local6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 12, "{sandbox}");
        sandbox.config("deny/net/connect^local6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_112() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/bind+local6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 4, "{sandbox}");
        sandbox.config("filter/net/bind-local6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_113() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/bind+local6!0")?;
        sandbox.config("filter/net/bind+local6!0")?;
        sandbox.config("filter/net/bind+local6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 12, "{sandbox}");
        sandbox.config("filter/net/bind^local6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_114() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/connect+local6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 4, "{sandbox}");
        sandbox.config("filter/net/connect-local6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_115() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/connect+local6!0")?;
        sandbox.config("filter/net/connect+local6!0")?;
        sandbox.config("filter/net/connect+local6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 12, "{sandbox}");
        sandbox.config("filter/net/connect^local6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_116() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/bind+local!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 8, "{sandbox}");
        sandbox.config("filter/net/bind-local!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_117() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/bind+local!0")?;
        sandbox.config("filter/net/bind+local!0")?;
        sandbox.config("filter/net/bind+local!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 24, "{sandbox}");
        sandbox.config("filter/net/bind^local!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_118() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/connect+local!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 8, "{sandbox}");
        sandbox.config("filter/net/connect-local!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_119() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/connect+local!0")?;
        sandbox.config("filter/net/connect+local!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 16, "{sandbox}");
        sandbox.config("filter/net/connect^local!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_120() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/bind+local!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 8, "{sandbox}");
        sandbox.config("allow/net/bind-local!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_121() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/bind+local!1")?;
        sandbox.config("allow/net/bind+local!0")?;
        sandbox.config("allow/net/bind+local!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 24, "{sandbox}");
        sandbox.config("allow/net/bind^local!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 8, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_122() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/connect+local!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 8, "{sandbox}");
        sandbox.config("allow/net/connect-local!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_123() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/connect+127.0.0.2!0")?;
        sandbox.config("allow/net/connect+local!0")?;
        sandbox.config("allow/net/connect+local!0")?;
        sandbox.config("allow/net/connect+local!1")?;
        assert_eq!(sandbox.cidr_rules.len(), 25, "{sandbox}");
        sandbox.config("allow/net/connect^local!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 9, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_124() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/bind+local!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 8, "{sandbox}");
        sandbox.config("deny/net/bind-local!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_125() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/bind+local!0")?;
        sandbox.config("deny/net/bind+127.0.0.1!0")?;
        sandbox.config("deny/net/bind+local!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 17, "{sandbox}");
        sandbox.config("deny/net/bind^local!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_126() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/connect+local!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 8, "{sandbox}");
        sandbox.config("deny/net/connect-local!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_127() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/connect+local!0")?;
        sandbox.config("deny/net/connect+local!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 16, "{sandbox}");
        sandbox.config("deny/net/connect^local!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_128() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/bind+linklocal4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("allow/net/bind-linklocal4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_129() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/bind+linklocal4!0")?;
        sandbox.config("allow/net/bind+linklocal4!0")?;
        sandbox.config("allow/net/bind+linklocal4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("allow/net/bind^linklocal4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_130() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/connect+linklocal4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("allow/net/connect-linklocal4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_131() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/bind+127.0.0.3!7")?;
        sandbox.config("allow/net/connect+linklocal4!0")?;
        sandbox.config("allow/net/connect+linklocal4!0")?;
        sandbox.config("allow/net/connect+linklocal4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 4, "{sandbox}");
        sandbox.config("allow/net/connect^linklocal4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_132() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/bind+linklocal4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("deny/net/bind-linklocal4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_133() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/bind+linklocal4!0")?;
        sandbox.config("deny/net/bind+linklocal4!0")?;
        sandbox.config("deny/net/bind+linklocal4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("deny/net/bind^linklocal4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_134() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/connect+linklocal4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("deny/net/connect-linklocal4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_135() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/connect+linklocal4!0")?;
        sandbox.config("deny/net/connect+linklocal4!0")?;
        sandbox.config("deny/net/connect+linklocal4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("deny/net/connect^linklocal4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_136() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/bind+linklocal4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("filter/net/bind-linklocal4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_137() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/bind+linklocal4!0")?;
        sandbox.config("filter/net/bind+linklocal4!0")?;
        sandbox.config("filter/net/bind+linklocal4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("filter/net/bind^linklocal4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_138() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/connect+linklocal4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("filter/net/connect-linklocal4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_139() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/connect+linklocal4!0")?;
        sandbox.config("filter/net/connect+linklocal4!0")?;
        sandbox.config("filter/net/connect+linklocal4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("filter/net/connect^linklocal4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_140() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/bind+linklocal6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("allow/net/bind-linklocal6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_141() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/bind+linklocal6!0")?;
        sandbox.config("allow/net/bind+linklocal6!0")?;
        sandbox.config("allow/net/bind+linklocal6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("allow/net/bind^linklocal6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_142() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/connect+linklocal6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("allow/net/connect-linklocal6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_143() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/connect+linklocal6!0")?;
        sandbox.config("allow/net/connect+linklocal6!0")?;
        sandbox.config("allow/net/connect+linklocal6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("allow/net/connect^linklocal6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_144() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/bind+linklocal6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("deny/net/bind-linklocal6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_145() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/bind+linklocal6!0")?;
        sandbox.config("deny/net/bind+linklocal6!0")?;
        sandbox.config("deny/net/bind+linklocal6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("deny/net/bind^linklocal6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_146() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/connect+linklocal6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("deny/net/connect-linklocal6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_147() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/connect+linklocal6!0")?;
        sandbox.config("deny/net/connect+linklocal6!0")?;
        sandbox.config("deny/net/connect+linklocal6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("deny/net/connect^linklocal6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_148() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/bind+linklocal6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("filter/net/bind-linklocal6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_149() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/bind+linklocal6!0")?;
        sandbox.config("filter/net/bind+linklocal6!0")?;
        sandbox.config("filter/net/bind+linklocal6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("filter/net/bind^linklocal6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_150() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/connect+linklocal6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("filter/net/connect-linklocal6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_151() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/connect+linklocal6!0")?;
        sandbox.config("filter/net/connect+linklocal6!0")?;
        sandbox.config("filter/net/connect+linklocal6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("filter/net/connect^linklocal6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_152() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/bind+linklocal!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 2, "{sandbox}");
        sandbox.config("filter/net/bind-linklocal!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_153() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/bind+linklocal!0")?;
        sandbox.config("filter/net/bind+linklocal!0")?;
        sandbox.config("filter/net/bind+linklocal!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 6, "{sandbox}");
        sandbox.config("filter/net/bind^linklocal!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_154() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/connect+linklocal!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 2, "{sandbox}");
        sandbox.config("filter/net/connect-linklocal!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_155() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/connect+linklocal!0")?;
        sandbox.config("filter/net/connect+linklocal!0")?;
        sandbox.config("filter/net/connect+linklocal!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 6, "{sandbox}");
        sandbox.config("filter/net/connect^linklocal!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_156() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/bind+linklocal!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 2, "{sandbox}");
        sandbox.config("allow/net/bind-linklocal!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_157() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/bind+linklocal!0")?;
        sandbox.config("allow/net/bind+linklocal!0")?;
        sandbox.config("allow/net/bind+linklocal!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 6, "{sandbox}");
        sandbox.config("allow/net/bind^linklocal!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_158() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/connect+linklocal!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 2, "{sandbox}");
        sandbox.config("allow/net/connect-linklocal!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_159() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/connect+linklocal!0")?;
        sandbox.config("allow/net/connect+linklocal!0")?;
        sandbox.config("allow/net/connect+linklocal!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 6, "{sandbox}");
        sandbox.config("allow/net/connect^linklocal!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_160() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/bind+linklocal!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 2, "{sandbox}");
        sandbox.config("deny/net/bind-linklocal!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_161() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/bind+linklocal!0")?;
        sandbox.config("deny/net/bind+linklocal!0")?;
        sandbox.config("deny/net/bind+linklocal!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 6, "{sandbox}");
        sandbox.config("deny/net/bind^linklocal!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_162() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/connect+linklocal!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 2, "{sandbox}");
        sandbox.config("deny/net/connect-linklocal!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_163() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/connect+linklocal!0")?;
        sandbox.config("deny/net/connect+linklocal!0")?;
        sandbox.config("deny/net/connect+linklocal!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 6, "{sandbox}");
        sandbox.config("deny/net/connect^linklocal!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_164() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/bind+any4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("allow/net/bind-any4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_165() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/bind+any4!0")?;
        sandbox.config("allow/net/bind+any4!0")?;
        sandbox.config("allow/net/bind+any4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("allow/net/bind^any4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_166() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/connect+any4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("allow/net/connect-any4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_167() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/connect+any4!0")?;
        sandbox.config("allow/net/connect+any4!0")?;
        sandbox.config("allow/net/connect+any4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("allow/net/connect^any4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_168() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/bind+any4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("deny/net/bind-any4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_169() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/bind+any4!0")?;
        sandbox.config("deny/net/bind+any4!0")?;
        sandbox.config("deny/net/bind+any4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("deny/net/bind^any4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_170() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/connect+any4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("deny/net/connect-any4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_171() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/connect+any4!0")?;
        sandbox.config("deny/net/connect+any4!0")?;
        sandbox.config("deny/net/connect+any4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("deny/net/connect^any4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_172() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/bind+any4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("filter/net/bind-any4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_173() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/bind+any4!0")?;
        sandbox.config("filter/net/bind+any4!0")?;
        sandbox.config("filter/net/bind+any4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("filter/net/bind^any4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_174() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/connect+any4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("filter/net/connect-any4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_175() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/connect+any4!0")?;
        sandbox.config("filter/net/connect+any4!0")?;
        sandbox.config("filter/net/connect+any4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("filter/net/connect^any4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_176() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/bind+any6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("allow/net/bind-any6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_177() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/bind+any6!0")?;
        sandbox.config("allow/net/bind+any6!0")?;
        sandbox.config("allow/net/bind+any6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("allow/net/bind^any6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_178() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/connect+any6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("allow/net/connect-any6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_179() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/connect+any6!0")?;
        sandbox.config("allow/net/connect+any6!0")?;
        sandbox.config("allow/net/connect+any6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("allow/net/connect^any6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_180() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/bind+any6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("deny/net/bind-any6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_181() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/bind+any6!0")?;
        sandbox.config("deny/net/bind+any6!0")?;
        sandbox.config("deny/net/bind+any6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("deny/net/bind^any6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_182() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/connect+any6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("deny/net/connect-any6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_183() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/connect+any6!0")?;
        sandbox.config("deny/net/connect+any6!0")?;
        sandbox.config("deny/net/connect+any6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("deny/net/connect^any6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_184() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/bind+any6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("filter/net/bind-any6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_185() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/bind+any6!0")?;
        sandbox.config("filter/net/bind+any6!0")?;
        sandbox.config("filter/net/bind+any6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("filter/net/bind^any6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_186() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/connect+any6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("filter/net/connect-any6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_187() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/connect+any6!0")?;
        sandbox.config("filter/net/connect+any6!0")?;
        sandbox.config("filter/net/connect+any6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("filter/net/connect^any6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_188() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/bind+any!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 2, "{sandbox}");
        sandbox.config("allow/net/bind-any!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_189() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/bind+any!0")?;
        sandbox.config("allow/net/bind+any!0")?;
        sandbox.config("allow/net/bind+any!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 6, "{sandbox}");
        sandbox.config("allow/net/bind^any!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_190() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/connect+any!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 2, "{sandbox}");
        sandbox.config("allow/net/connect-any!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_191() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/connect+any!0")?;
        sandbox.config("allow/net/connect+any!0")?;
        sandbox.config("allow/net/connect+any!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 6, "{sandbox}");
        sandbox.config("allow/net/connect^any!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_192() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/bind+any!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 2, "{sandbox}");
        sandbox.config("deny/net/bind-any!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_193() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/bind+any!0")?;
        sandbox.config("deny/net/bind+any!0")?;
        sandbox.config("deny/net/bind+any!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 6, "{sandbox}");
        sandbox.config("deny/net/bind^any!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_194() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/connect+any!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 2, "{sandbox}");
        sandbox.config("deny/net/connect-any!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_195() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/connect+any!0")?;
        sandbox.config("deny/net/connect+any!0")?;
        sandbox.config("deny/net/connect+any!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 6, "{sandbox}");
        sandbox.config("deny/net/connect^any!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_196() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/bind+any!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 2, "{sandbox}");
        sandbox.config("filter/net/bind-any!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_197() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/bind+any!0")?;
        sandbox.config("filter/net/bind+any!0")?;
        sandbox.config("filter/net/bind+any!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 6, "{sandbox}");
        sandbox.config("filter/net/bind^any!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_198() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/connect+any!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 2, "{sandbox}");
        sandbox.config("filter/net/connect-any!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_199() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("filter/net/connect+any!0")?;
        sandbox.config("filter/net/connect+any!0")?;
        sandbox.config("filter/net/connect+any!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 6, "{sandbox}");
        sandbox.config("filter/net/connect^any!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_200() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..8 {
            sandbox.config("allow/net/bind+loopback4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 8, "{sandbox}");
        for _ in 0..8 {
            sandbox.config("allow/net/bind-loopback4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_201() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..8 {
            sandbox.config("allow/net/bind+loopback4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 8, "{sandbox}");
        sandbox.config("allow/net/bind^loopback4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_202() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..9 {
            sandbox.config("allow/net/connect+loopback4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 9, "{sandbox}");
        for _ in 0..9 {
            sandbox.config("allow/net/connect-loopback4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_203() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..9 {
            sandbox.config("allow/net/connect+loopback4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 9, "{sandbox}");
        sandbox.config("allow/net/connect^loopback4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_204() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..10 {
            sandbox.config("deny/net/bind+loopback4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 10, "{sandbox}");
        for _ in 0..10 {
            sandbox.config("deny/net/bind-loopback4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_205() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..10 {
            sandbox.config("deny/net/bind+loopback4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 10, "{sandbox}");
        sandbox.config("deny/net/bind^loopback4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_206() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..11 {
            sandbox.config("deny/net/connect+loopback4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 11, "{sandbox}");
        for _ in 0..11 {
            sandbox.config("deny/net/connect-loopback4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_207() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..11 {
            sandbox.config("deny/net/connect+loopback4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 11, "{sandbox}");
        sandbox.config("deny/net/connect^loopback4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_208() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..12 {
            sandbox.config("filter/net/bind+loopback4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 12, "{sandbox}");
        for _ in 0..12 {
            sandbox.config("filter/net/bind-loopback4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_209() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..12 {
            sandbox.config("filter/net/bind+loopback4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 12, "{sandbox}");
        sandbox.config("filter/net/bind^loopback4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_210() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..13 {
            sandbox.config("filter/net/connect+loopback4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 13, "{sandbox}");
        for _ in 0..13 {
            sandbox.config("filter/net/connect-loopback4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_211() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..13 {
            sandbox.config("filter/net/connect+loopback4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 13, "{sandbox}");
        sandbox.config("filter/net/connect^loopback4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_212() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..8 {
            sandbox.config("allow/net/bind+loopback6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 8, "{sandbox}");
        for _ in 0..8 {
            sandbox.config("allow/net/bind-loopback6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_213() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..8 {
            sandbox.config("allow/net/bind+loopback6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 8, "{sandbox}");
        sandbox.config("allow/net/bind^loopback6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_214() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..9 {
            sandbox.config("allow/net/connect+loopback6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 9, "{sandbox}");
        for _ in 0..9 {
            sandbox.config("allow/net/connect-loopback6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_215() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..9 {
            sandbox.config("allow/net/connect+loopback6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 9, "{sandbox}");
        sandbox.config("allow/net/connect^loopback6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_216() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..10 {
            sandbox.config("deny/net/bind+loopback6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 10, "{sandbox}");
        for _ in 0..10 {
            sandbox.config("deny/net/bind-loopback6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_217() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..10 {
            sandbox.config("deny/net/bind+loopback6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 10, "{sandbox}");
        sandbox.config("deny/net/bind^loopback6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_218() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..11 {
            sandbox.config("deny/net/connect+loopback6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 11, "{sandbox}");
        for _ in 0..11 {
            sandbox.config("deny/net/connect-loopback6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_219() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..11 {
            sandbox.config("deny/net/connect+loopback6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 11, "{sandbox}");
        sandbox.config("deny/net/connect^loopback6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_220() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..12 {
            sandbox.config("filter/net/bind+loopback6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 12, "{sandbox}");
        for _ in 0..12 {
            sandbox.config("filter/net/bind-loopback6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_221() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..12 {
            sandbox.config("filter/net/bind+loopback6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 12, "{sandbox}");
        sandbox.config("filter/net/bind^loopback6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_222() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..13 {
            sandbox.config("filter/net/connect+loopback6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 13, "{sandbox}");
        for _ in 0..13 {
            sandbox.config("filter/net/connect-loopback6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_223() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..13 {
            sandbox.config("filter/net/connect+loopback6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 13, "{sandbox}");
        sandbox.config("filter/net/connect^loopback6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_224() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..2 {
            sandbox.config("allow/net/bind+loopback!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 4, "{sandbox}");
        for _ in 0..2 {
            sandbox.config("allow/net/bind-loopback!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_225() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..2 {
            sandbox.config("allow/net/bind+loopback!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 4, "{sandbox}");
        sandbox.config("allow/net/bind^loopback!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_226() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..3 {
            sandbox.config("allow/net/connect+loopback!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 6, "{sandbox}");
        for _ in 0..3 {
            sandbox.config("allow/net/connect-loopback!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_227() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..3 {
            sandbox.config("allow/net/connect+loopback!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 6, "{sandbox}");
        sandbox.config("allow/net/connect^loopback!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_228() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..4 {
            sandbox.config("deny/net/bind+loopback!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 8, "{sandbox}");
        for _ in 0..4 {
            sandbox.config("deny/net/bind-loopback!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_229() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..4 {
            sandbox.config("deny/net/bind+loopback!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 8, "{sandbox}");
        sandbox.config("deny/net/bind^loopback!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_230() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..5 {
            sandbox.config("deny/net/connect+loopback!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 10, "{sandbox}");
        for _ in 0..5 {
            sandbox.config("deny/net/connect-loopback!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_231() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..5 {
            sandbox.config("deny/net/connect+loopback!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 10, "{sandbox}");
        sandbox.config("deny/net/connect^loopback!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_232() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..6 {
            sandbox.config("filter/net/bind+loopback!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 12, "{sandbox}");
        for _ in 0..6 {
            sandbox.config("filter/net/bind-loopback!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_233() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..6 {
            sandbox.config("filter/net/bind+loopback!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 12, "{sandbox}");
        sandbox.config("filter/net/bind^loopback!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_234() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..7 {
            sandbox.config("filter/net/connect+loopback!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 14, "{sandbox}");
        for _ in 0..7 {
            sandbox.config("filter/net/connect-loopback!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_235() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..7 {
            sandbox.config("filter/net/connect+loopback!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 14, "{sandbox}");
        sandbox.config("filter/net/connect^loopback!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_236() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..14 {
            sandbox.config("allow/net/bind+local4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 4 * 14, "{sandbox}");
        for _ in 0..14 {
            sandbox.config("allow/net/bind-local4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_237() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..14 {
            sandbox.config("allow/net/bind+local4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 4 * 14, "{sandbox}");
        sandbox.config("allow/net/bind^local4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_238() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..15 {
            sandbox.config("allow/net/connect+local4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 4 * 15, "{sandbox}");
        for _ in 0..15 {
            sandbox.config("allow/net/connect-local4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_239() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..15 {
            sandbox.config("allow/net/connect+local4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 4 * 15, "{sandbox}");
        sandbox.config("allow/net/connect^local4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_240() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..16 {
            sandbox.config("deny/net/bind+local4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 4 * 16, "{sandbox}");
        for _ in 0..16 {
            sandbox.config("deny/net/bind-local4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_241() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..16 {
            sandbox.config("deny/net/bind+local4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 4 * 16, "{sandbox}");
        sandbox.config("deny/net/bind^local4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_242() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..17 {
            sandbox.config("deny/net/connect+local4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 4 * 17, "{sandbox}");
        for _ in 0..17 {
            sandbox.config("deny/net/connect-local4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_243() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..17 {
            sandbox.config("deny/net/connect+local4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 4 * 17, "{sandbox}");
        sandbox.config("deny/net/connect^local4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_244() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..18 {
            sandbox.config("filter/net/bind+local4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 4 * 18, "{sandbox}");
        for _ in 0..18 {
            sandbox.config("filter/net/bind-local4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_245() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..18 {
            sandbox.config("filter/net/bind+local4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 4 * 18, "{sandbox}");
        sandbox.config("filter/net/bind^local4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_246() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..19 {
            sandbox.config("filter/net/connect+local4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 4 * 19, "{sandbox}");
        for _ in 0..19 {
            sandbox.config("filter/net/connect-local4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_247() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..19 {
            sandbox.config("filter/net/connect+local4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 4 * 19, "{sandbox}");
        sandbox.config("filter/net/connect^local4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_248() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..20 {
            sandbox.config("allow/net/bind+local6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 4 * 20, "{sandbox}");
        for _ in 0..20 {
            sandbox.config("allow/net/bind-local6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_249() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..20 {
            sandbox.config("allow/net/bind+local6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 4 * 20, "{sandbox}");
        sandbox.config("allow/net/bind^local6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_250() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..21 {
            sandbox.config("allow/net/connect+local6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 4 * 21, "{sandbox}");
        for _ in 0..21 {
            sandbox.config("allow/net/connect-local6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_251() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..21 {
            sandbox.config("allow/net/connect+local6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 4 * 21, "{sandbox}");
        sandbox.config("allow/net/connect^local6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_252() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..22 {
            sandbox.config("deny/net/bind+local6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 4 * 22, "{sandbox}");
        for _ in 0..22 {
            sandbox.config("deny/net/bind-local6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_253() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..22 {
            sandbox.config("deny/net/bind+local6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 4 * 22, "{sandbox}");
        sandbox.config("deny/net/bind^local6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_254() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..23 {
            sandbox.config("deny/net/connect+local6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 4 * 23, "{sandbox}");
        for _ in 0..23 {
            sandbox.config("deny/net/connect-local6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_255() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..23 {
            sandbox.config("deny/net/connect+local6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 4 * 23, "{sandbox}");
        sandbox.config("deny/net/connect^local6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_256() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..24 {
            sandbox.config("filter/net/bind+local6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 4 * 24, "{sandbox}");
        for _ in 0..24 {
            sandbox.config("filter/net/bind-local6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_257() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..24 {
            sandbox.config("filter/net/bind+local6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 4 * 24, "{sandbox}");
        sandbox.config("filter/net/bind^local6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_258() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..25 {
            sandbox.config("filter/net/connect+local6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 4 * 25, "{sandbox}");
        for _ in 0..25 {
            sandbox.config("filter/net/connect-local6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_259() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..25 {
            sandbox.config("filter/net/connect+local6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 4 * 25, "{sandbox}");
        sandbox.config("filter/net/connect^local6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_260() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..20 {
            sandbox.config("allow/net/bind+local!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 8 * 20, "{sandbox}");
        for _ in 0..20 {
            sandbox.config("allow/net/bind-local!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_261() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..20 {
            sandbox.config("allow/net/bind+local!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 8 * 20, "{sandbox}");
        sandbox.config("allow/net/bind^local!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_262() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..21 {
            sandbox.config("allow/net/connect+local!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 8 * 21, "{sandbox}");
        for _ in 0..21 {
            sandbox.config("allow/net/connect-local!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_263() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..21 {
            sandbox.config("allow/net/connect+local!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 8 * 21, "{sandbox}");
        sandbox.config("allow/net/connect^local!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_264() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..22 {
            sandbox.config("deny/net/bind+local!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 8 * 22, "{sandbox}");
        for _ in 0..22 {
            sandbox.config("deny/net/bind-local!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_265() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..22 {
            sandbox.config("deny/net/bind+local!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 8 * 22, "{sandbox}");
        sandbox.config("deny/net/bind^local!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_266() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..23 {
            sandbox.config("deny/net/connect+local!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 8 * 23, "{sandbox}");
        for _ in 0..23 {
            sandbox.config("deny/net/connect-local!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_267() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..23 {
            sandbox.config("deny/net/connect+local!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 8 * 23, "{sandbox}");
        sandbox.config("deny/net/connect^local!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_268() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..24 {
            sandbox.config("filter/net/bind+local!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 8 * 24, "{sandbox}");
        for _ in 0..24 {
            sandbox.config("filter/net/bind-local!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_269() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..24 {
            sandbox.config("filter/net/bind+local!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 8 * 24, "{sandbox}");
        sandbox.config("filter/net/bind^local!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_270() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..25 {
            sandbox.config("filter/net/connect+local!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 8 * 25, "{sandbox}");
        for _ in 0..25 {
            sandbox.config("filter/net/connect-local!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_271() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..25 {
            sandbox.config("filter/net/connect+local!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 8 * 25, "{sandbox}");
        sandbox.config("filter/net/connect^local!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_272() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..4 {
            sandbox.config("deny/net/bind+any4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 4, "{sandbox}");
        for _ in 0..4 {
            sandbox.config("deny/net/bind-any4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_273() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..4 {
            sandbox.config("deny/net/bind+any4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 4, "{sandbox}");
        sandbox.config("deny/net/bind^any4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_274() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..5 {
            sandbox.config("deny/net/connect+any4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 5, "{sandbox}");
        for _ in 0..5 {
            sandbox.config("deny/net/connect-any4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_275() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..5 {
            sandbox.config("deny/net/connect+any4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 5, "{sandbox}");
        sandbox.config("deny/net/connect^any4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_276() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..14 {
            sandbox.config("allow/net/bind+linklocal4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 14, "{sandbox}");
        for _ in 0..14 {
            sandbox.config("allow/net/bind-linklocal4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_277() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..14 {
            sandbox.config("allow/net/bind+linklocal4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 14, "{sandbox}");
        sandbox.config("allow/net/bind^linklocal4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_278() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..15 {
            sandbox.config("allow/net/connect+linklocal4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 15, "{sandbox}");
        for _ in 0..15 {
            sandbox.config("allow/net/connect-linklocal4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_279() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..15 {
            sandbox.config("allow/net/connect+linklocal4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 15, "{sandbox}");
        sandbox.config("allow/net/connect^linklocal4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_280() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..16 {
            sandbox.config("deny/net/bind+linklocal4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 16, "{sandbox}");
        for _ in 0..16 {
            sandbox.config("deny/net/bind-linklocal4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_281() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..16 {
            sandbox.config("deny/net/bind+linklocal4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 16, "{sandbox}");
        sandbox.config("deny/net/bind^linklocal4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_282() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..17 {
            sandbox.config("deny/net/connect+linklocal4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 17, "{sandbox}");
        for _ in 0..17 {
            sandbox.config("deny/net/connect-linklocal4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_283() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..17 {
            sandbox.config("deny/net/connect+linklocal4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 17, "{sandbox}");
        sandbox.config("deny/net/connect^linklocal4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_284() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..18 {
            sandbox.config("filter/net/bind+linklocal4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 18, "{sandbox}");
        for _ in 0..18 {
            sandbox.config("filter/net/bind-linklocal4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_285() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..18 {
            sandbox.config("filter/net/bind+linklocal4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 18, "{sandbox}");
        sandbox.config("filter/net/bind^linklocal4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_286() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..19 {
            sandbox.config("filter/net/connect+linklocal4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 19, "{sandbox}");
        for _ in 0..19 {
            sandbox.config("filter/net/connect-linklocal4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_287() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..19 {
            sandbox.config("filter/net/connect+linklocal4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 19, "{sandbox}");
        sandbox.config("filter/net/connect^linklocal4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_288() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..20 {
            sandbox.config("allow/net/bind+linklocal6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 20, "{sandbox}");
        for _ in 0..20 {
            sandbox.config("allow/net/bind-linklocal6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_289() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..20 {
            sandbox.config("allow/net/bind+linklocal6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 20, "{sandbox}");
        sandbox.config("allow/net/bind^linklocal6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_290() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..21 {
            sandbox.config("allow/net/connect+linklocal6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 21, "{sandbox}");
        for _ in 0..21 {
            sandbox.config("allow/net/connect-linklocal6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_291() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..21 {
            sandbox.config("allow/net/connect+linklocal6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 21, "{sandbox}");
        sandbox.config("allow/net/connect^linklocal6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_292() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..22 {
            sandbox.config("deny/net/bind+linklocal6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 22, "{sandbox}");
        for _ in 0..22 {
            sandbox.config("deny/net/bind-linklocal6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_293() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..22 {
            sandbox.config("deny/net/bind+linklocal6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 22, "{sandbox}");
        sandbox.config("deny/net/bind^linklocal6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_294() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..23 {
            sandbox.config("deny/net/connect+linklocal6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 23, "{sandbox}");
        for _ in 0..23 {
            sandbox.config("deny/net/connect-linklocal6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_295() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..23 {
            sandbox.config("deny/net/connect+linklocal6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 23, "{sandbox}");
        sandbox.config("deny/net/connect^linklocal6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_296() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..24 {
            sandbox.config("filter/net/bind+linklocal6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 24, "{sandbox}");
        for _ in 0..24 {
            sandbox.config("filter/net/bind-linklocal6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_297() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..24 {
            sandbox.config("filter/net/bind+linklocal6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 24, "{sandbox}");
        sandbox.config("filter/net/bind^linklocal6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_298() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..25 {
            sandbox.config("filter/net/connect+linklocal6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 25, "{sandbox}");
        for _ in 0..25 {
            sandbox.config("filter/net/connect-linklocal6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_299() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..25 {
            sandbox.config("filter/net/connect+linklocal6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 25, "{sandbox}");
        sandbox.config("filter/net/connect^linklocal6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_300() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..20 {
            sandbox.config("allow/net/bind+linklocal!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 2 * 20, "{sandbox}");
        for _ in 0..20 {
            sandbox.config("allow/net/bind-linklocal!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_301() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..20 {
            sandbox.config("allow/net/bind+linklocal!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 2 * 20, "{sandbox}");
        sandbox.config("allow/net/bind^linklocal!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_302() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..21 {
            sandbox.config("allow/net/connect+linklocal!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 2 * 21, "{sandbox}");
        for _ in 0..21 {
            sandbox.config("allow/net/connect-linklocal!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_303() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..21 {
            sandbox.config("allow/net/connect+linklocal!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 2 * 21, "{sandbox}");
        sandbox.config("allow/net/connect^linklocal!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_304() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..22 {
            sandbox.config("deny/net/bind+linklocal!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 2 * 22, "{sandbox}");
        for _ in 0..22 {
            sandbox.config("deny/net/bind-linklocal!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_305() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..22 {
            sandbox.config("deny/net/bind+linklocal!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 2 * 22, "{sandbox}");
        sandbox.config("deny/net/bind^linklocal!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_306() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..23 {
            sandbox.config("deny/net/connect+linklocal!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 2 * 23, "{sandbox}");
        for _ in 0..23 {
            sandbox.config("deny/net/connect-linklocal!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_307() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..23 {
            sandbox.config("deny/net/connect+linklocal!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 2 * 23, "{sandbox}");
        sandbox.config("deny/net/connect^linklocal!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_308() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..24 {
            sandbox.config("filter/net/bind+linklocal!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 2 * 24, "{sandbox}");
        for _ in 0..24 {
            sandbox.config("filter/net/bind-linklocal!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_309() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..24 {
            sandbox.config("filter/net/bind+linklocal!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 2 * 24, "{sandbox}");
        sandbox.config("filter/net/bind^linklocal!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_310() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..25 {
            sandbox.config("filter/net/connect+linklocal!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 2 * 25, "{sandbox}");
        for _ in 0..25 {
            sandbox.config("filter/net/connect-linklocal!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_311() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..25 {
            sandbox.config("filter/net/connect+linklocal!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 2 * 25, "{sandbox}");
        sandbox.config("filter/net/connect^linklocal!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_312() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..2 {
            sandbox.config("allow/net/bind+any4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 2, "{sandbox}");
        for _ in 0..2 {
            sandbox.config("allow/net/bind-any4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_313() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..2 {
            sandbox.config("allow/net/bind+any4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 2, "{sandbox}");
        sandbox.config("allow/net/bind^any4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_314() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..3 {
            sandbox.config("allow/net/connect+any4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        for _ in 0..3 {
            sandbox.config("allow/net/connect-any4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_315() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..3 {
            sandbox.config("allow/net/connect+any4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 3, "{sandbox}");
        sandbox.config("allow/net/connect^any4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_316() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..6 {
            sandbox.config("filter/net/bind+any4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 6, "{sandbox}");
        for _ in 0..6 {
            sandbox.config("filter/net/bind-any4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_317() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..6 {
            sandbox.config("filter/net/bind+any4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 6, "{sandbox}");
        sandbox.config("filter/net/bind^any4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_318() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..7 {
            sandbox.config("filter/net/connect+any4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 7, "{sandbox}");
        for _ in 0..7 {
            sandbox.config("filter/net/connect-any4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_319() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..7 {
            sandbox.config("filter/net/connect+any4!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 7, "{sandbox}");
        sandbox.config("filter/net/connect^any4!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_320() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..8 {
            sandbox.config("allow/net/bind+any6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 8, "{sandbox}");
        for _ in 0..8 {
            sandbox.config("allow/net/bind-any6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_321() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..8 {
            sandbox.config("allow/net/bind+any6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 8, "{sandbox}");
        sandbox.config("allow/net/bind^any6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_322() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..9 {
            sandbox.config("allow/net/connect+any6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 9, "{sandbox}");
        for _ in 0..9 {
            sandbox.config("allow/net/connect-any6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_323() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..9 {
            sandbox.config("allow/net/connect+any6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 9, "{sandbox}");
        sandbox.config("allow/net/connect^any6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_324() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..10 {
            sandbox.config("deny/net/bind+any6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 10, "{sandbox}");
        for _ in 0..10 {
            sandbox.config("deny/net/bind-any6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_325() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..10 {
            sandbox.config("deny/net/bind+any6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 10, "{sandbox}");
        sandbox.config("deny/net/bind^any6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_326() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..11 {
            sandbox.config("deny/net/connect+any6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 11, "{sandbox}");
        for _ in 0..11 {
            sandbox.config("deny/net/connect-any6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_327() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..11 {
            sandbox.config("deny/net/connect+any6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 11, "{sandbox}");
        sandbox.config("deny/net/connect^any6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_328() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..12 {
            sandbox.config("filter/net/bind+any6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 12, "{sandbox}");
        for _ in 0..12 {
            sandbox.config("filter/net/bind-any6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_329() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..12 {
            sandbox.config("filter/net/bind+any6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 12, "{sandbox}");
        sandbox.config("filter/net/bind^any6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_330() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..13 {
            sandbox.config("filter/net/connect+any6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 13, "{sandbox}");
        for _ in 0..13 {
            sandbox.config("filter/net/connect-any6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_331() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..13 {
            sandbox.config("filter/net/connect+any6!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 13, "{sandbox}");
        sandbox.config("filter/net/connect^any6!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_332() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..14 {
            sandbox.config("allow/net/bind+any!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 14 * 2, "{sandbox}");
        for _ in 0..14 {
            sandbox.config("allow/net/bind-any!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_333() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..14 {
            sandbox.config("allow/net/bind+any!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 14 * 2, "{sandbox}");
        sandbox.config("allow/net/bind^any!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_334() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..15 {
            sandbox.config("allow/net/connect+any!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 15 * 2, "{sandbox}");
        for _ in 0..15 {
            sandbox.config("allow/net/connect-any!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_335() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..15 {
            sandbox.config("allow/net/connect+any!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 15 * 2, "{sandbox}");
        sandbox.config("allow/net/connect^any!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_336() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..16 {
            sandbox.config("deny/net/bind+any!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 16 * 2, "{sandbox}");
        for _ in 0..16 {
            sandbox.config("deny/net/bind-any!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_337() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..16 {
            sandbox.config("deny/net/bind+any!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 16 * 2, "{sandbox}");
        sandbox.config("deny/net/bind^any!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_338() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..17 {
            sandbox.config("deny/net/connect+any!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 17 * 2, "{sandbox}");
        for _ in 0..17 {
            sandbox.config("deny/net/connect-any!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_339() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..17 {
            sandbox.config("deny/net/connect+any!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 17 * 2, "{sandbox}");
        sandbox.config("deny/net/connect^any!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_340() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..18 {
            sandbox.config("filter/net/bind+any!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 18 * 2, "{sandbox}");
        for _ in 0..18 {
            sandbox.config("filter/net/bind-any!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_341() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..18 {
            sandbox.config("filter/net/bind+any!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 18 * 2, "{sandbox}");
        sandbox.config("filter/net/bind^any!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_342() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..19 {
            sandbox.config("filter/net/connect+any!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 19 * 2, "{sandbox}");
        for _ in 0..19 {
            sandbox.config("filter/net/connect-any!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_343() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        for _ in 0..19 {
            sandbox.config("filter/net/connect+any!0")?;
        }
        assert_eq!(sandbox.cidr_rules.len(), 19 * 2, "{sandbox}");
        sandbox.config("filter/net/connect^any!0")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_344() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.glob_rules().len();

        sandbox.config("allow/stat+/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 1, "{sandbox}");
        sandbox.config("allow/stat-/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_345() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.glob_rules().len();

        sandbox.config("allow/stat+/usr/*")?;
        sandbox.config("allow/stat+/usr/**")?;
        sandbox.config("allow/stat+/usr/**")?;
        sandbox.config("allow/stat+/usr/**")?;
        sandbox.config("allow/stat+/usr")?;
        assert_eq!(sandbox.glob_rules().len(), len + 5, "{sandbox}");
        sandbox.config("allow/stat^/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 2, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_346() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.glob_rules().len();

        sandbox.config("deny/stat+/usr/**")?;
        sandbox.config("deny/stat+/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 2, "{sandbox}");
        sandbox.config("deny/stat-/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 1, "{sandbox}");
        sandbox.config("deny/stat-/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_347() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.glob_rules().len();

        sandbox.config("filter/stat+/usr/**")?;
        sandbox.config("filter/stat+/usr/**")?;
        sandbox.config("filter/stat+/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 3, "{sandbox}");
        sandbox.config("filter/stat-/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 2, "{sandbox}");
        sandbox.config("filter/stat-/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len + 1, "{sandbox}");
        sandbox.config("filter/stat-/usr/**")?;
        assert_eq!(sandbox.glob_rules().len(), len, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_348() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/bind+1.1.1.1!80")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("allow/net/bind-1.1.1.1!80")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/bind+1.1.1.1!80")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("deny/net/bind-1.1.1.1!80")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("allow/net/connect+1.1.1.1!80")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("allow/net/connect-1.1.1.1!80")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        sandbox.config("deny/net/connect+1.1.1.1!80")?;
        assert_eq!(sandbox.cidr_rules.len(), 1, "{sandbox}");
        sandbox.config("deny/net/connect-1.1.1.1!80")?;
        assert_eq!(sandbox.cidr_rules.len(), 0, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_349() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.config("mask"), Err(Errno::EINVAL));
        assert_eq!(sandbox.config("mask+"), Err(Errno::EINVAL));
        assert_eq!(sandbox.config("mask-"), Err(Errno::EINVAL));
        assert_eq!(sandbox.config("mask^"), Err(Errno::EINVAL));
        assert_eq!(sandbox.config("mask!"), Err(Errno::EINVAL));
        assert_eq!(sandbox.config("mask!/proc"), Err(Errno::EINVAL));

        assert!(sandbox.is_masked(Path::new("/proc/cmdline")));
        assert!(sandbox.is_masked(Path::new("/dev/kmsg")));
        assert!(sandbox.is_masked(Path::new("/proc/kmsg")));
        assert!(!sandbox.is_masked(Path::new("/proc/version")));

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_350() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.acl_mask.len();
        sandbox.config("mask-/proc/cmdline")?;
        assert_eq!(sandbox.acl_mask.len(), len - 1, "{sandbox}");
        sandbox.config("mask-/proc/kmsg")?;
        assert_eq!(sandbox.acl_mask.len(), len - 2, "{sandbox}");
        sandbox.config("mask-/dev/kmsg")?;
        assert_eq!(sandbox.acl_mask.len(), len - 3, "{sandbox}");

        assert!(!sandbox.is_masked(Path::new("/proc/cmdline")));
        assert!(!sandbox.is_masked(Path::new("/dev/kmsg")));
        assert!(!sandbox.is_masked(Path::new("/proc/kmsg")));
        assert!(!sandbox.is_masked(Path::new("/proc/version")));

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_351() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.acl_mask.len();
        sandbox.config("mask+/proc/vers?on")?;
        assert_eq!(sandbox.acl_mask.len(), len + 1, "{sandbox}");

        assert!(sandbox.is_masked(Path::new("/proc/cmdline")));
        assert!(sandbox.is_masked(Path::new("/dev/kmsg")));
        assert!(sandbox.is_masked(Path::new("/proc/kmsg")));
        assert!(sandbox.is_masked(Path::new("/proc/version")));

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_352() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.acl_mask.len();
        sandbox.config("mask+/proc/vers?on")?;
        assert_eq!(sandbox.acl_mask.len(), len + 1, "{sandbox}");
        sandbox.config("mask-/proc/vers?on")?;
        assert_eq!(sandbox.acl_mask.len(), len, "{sandbox}");

        assert!(sandbox.is_masked(Path::new("/proc/cmdline")));
        assert!(sandbox.is_masked(Path::new("/dev/kmsg")));
        assert!(sandbox.is_masked(Path::new("/proc/kmsg")));
        assert!(!sandbox.is_masked(Path::new("/proc/version")));

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_353() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.acl_mask.len();
        sandbox.config("mask+/proc/***")?;
        assert_eq!(sandbox.acl_mask.len(), len + 1, "{sandbox}");
        sandbox.config("mask-/proc/***")?;
        assert_eq!(sandbox.acl_mask.len(), len, "{sandbox}");

        assert!(sandbox.is_masked(Path::new("/proc/cmdline")));
        assert!(sandbox.is_masked(Path::new("/dev/kmsg")));
        assert!(sandbox.is_masked(Path::new("/proc/kmsg")));
        assert!(!sandbox.is_masked(Path::new("/proc/version")));

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_354() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.acl_mask.len();
        for _ in 0..7 {
            sandbox.config("mask+/proc/vers?on")?;
        }
        assert_eq!(sandbox.acl_mask.len(), len + 7, "{sandbox}");
        sandbox.config("mask^/proc/vers?on")?;
        assert_eq!(sandbox.acl_mask.len(), len, "{sandbox}");

        assert!(sandbox.is_masked(Path::new("/proc/cmdline")));
        assert!(sandbox.is_masked(Path::new("/dev/kmsg")));
        assert!(sandbox.is_masked(Path::new("/proc/kmsg")));
        assert!(!sandbox.is_masked(Path::new("/proc/version")));

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_355() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.acl_mask.len();
        for _ in 0..7 {
            sandbox.config("mask+/proc/***")?;
        }
        assert_eq!(sandbox.acl_mask.len(), len + 7, "{sandbox}");
        sandbox.config("mask^/proc/***")?;
        assert_eq!(sandbox.acl_mask.len(), len, "{sandbox}");

        assert!(sandbox.is_masked(Path::new("/proc/cmdline")));
        assert!(sandbox.is_masked(Path::new("/dev/kmsg")));
        assert!(sandbox.is_masked(Path::new("/proc/kmsg")));
        assert!(!sandbox.is_masked(Path::new("/proc/version")));

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_356() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert_eq!(sandbox.config("append"), Err(Errno::EINVAL));
        assert_eq!(sandbox.config("append+"), Err(Errno::EINVAL));
        assert_eq!(sandbox.config("append-"), Err(Errno::EINVAL));
        assert_eq!(sandbox.config("append^"), Err(Errno::EINVAL));
        assert_eq!(sandbox.config("append!"), Err(Errno::EINVAL));
        assert_eq!(sandbox.config("append!/proc"), Err(Errno::EINVAL));

        assert_eq!(sandbox.config("append+/proc/cmd*"), Ok(()));
        assert_eq!(sandbox.config("append+/*/*msg"), Ok(()));

        assert!(sandbox.is_append(Path::new("/proc/cmdline")));
        assert!(sandbox.is_append(Path::new("/dev/kmsg")));
        assert!(sandbox.is_append(Path::new("/proc/kmsg")));
        assert!(!sandbox.is_append(Path::new("/proc/version")));

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_357() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.acl_append.len();
        sandbox.config("append+/proc/cmd*ine")?;
        assert_eq!(sandbox.acl_append.len(), len + 1, "{sandbox}");
        sandbox.config("append+/proc/*msg")?;
        assert_eq!(sandbox.acl_append.len(), len + 2, "{sandbox}");
        sandbox.config("append+/dev/km*")?;
        assert_eq!(sandbox.acl_append.len(), len + 3, "{sandbox}");

        assert!(sandbox.is_append(Path::new("/proc/cmdline")));
        assert!(sandbox.is_append(Path::new("/dev/kmsg")));
        assert!(sandbox.is_append(Path::new("/proc/kmsg")));
        assert!(!sandbox.is_append(Path::new("/proc/version")));

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_358() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.acl_append.len();
        sandbox.config("append+/proc/vers?on")?;
        assert_eq!(sandbox.acl_append.len(), len + 1, "{sandbox}");

        assert!(sandbox.is_append(Path::new("/proc/version")));

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_359() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.acl_append.len();
        sandbox.config("append+/proc/vers?on")?;
        assert_eq!(sandbox.acl_append.len(), len + 1, "{sandbox}");
        sandbox.config("append-/proc/vers?on")?;
        assert_eq!(sandbox.acl_append.len(), len, "{sandbox}");

        assert!(!sandbox.is_append(Path::new("/proc/version")));

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_360() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.acl_append.len();
        sandbox.config("append+/proc/***")?;
        assert_eq!(sandbox.acl_append.len(), len + 1, "{sandbox}");
        sandbox.config("append-/proc/***")?;
        assert_eq!(sandbox.acl_append.len(), len, "{sandbox}");
        sandbox.config("append+/proc/***")?;
        assert_eq!(sandbox.acl_append.len(), len + 1, "{sandbox}");

        assert!(sandbox.is_append(Path::new("/proc/cmdline")));
        assert!(!sandbox.is_append(Path::new("/dev/kmsg")));
        assert!(sandbox.is_append(Path::new("/proc/kmsg")));
        assert!(sandbox.is_append(Path::new("/proc/version")));

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_361() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.acl_append.len();
        for _ in 0..7 {
            sandbox.config("append+/proc/vers?on")?;
        }
        assert_eq!(sandbox.acl_append.len(), len + 7, "{sandbox}");
        sandbox.config("append^/proc/vers?on")?;
        assert_eq!(sandbox.acl_append.len(), len, "{sandbox}");

        assert!(!sandbox.is_append(Path::new("/proc/version")));

        Ok(())
    }

    #[test]
    fn sandbox_config_rules_362() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        let len = sandbox.acl_append.len();
        for _ in 0..7 {
            sandbox.config("append+/proc/***")?;
        }
        assert_eq!(sandbox.acl_append.len(), len + 7, "{sandbox}");
        sandbox.config("append^/proc/***")?;
        assert_eq!(sandbox.acl_append.len(), len, "{sandbox}");

        Ok(())
    }

    #[test]
    fn sandbox_glob_doublestar_does_not_match_basename() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        sandbox.config("sandbox/read:on")?;

        sandbox.config("allow/read+/dev/**")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_READ, Path::new("/dev")),
            None,
            "/dev =~ /dev/**, {sandbox}"
        );

        Ok(())
    }

    #[test]
    fn sandbox_glob_doublestar_matches_basename_with_slash() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        sandbox.config("sandbox/read:on")?;

        sandbox.config("allow/read+/dev/**")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_READ, Path::new("/dev/")),
            Some(Action::Allow),
            "/dev/ !~ /dev/**, {sandbox}"
        );

        Ok(())
    }

    #[test]
    fn sandbox_glob_doublestar_matches_pathname() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        sandbox.config("sandbox/read:on")?;

        sandbox.config("allow/read+/dev/**")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_READ, Path::new("/dev/null")),
            Some(Action::Allow),
            "/dev/null !~ /dev/**, {sandbox}"
        );

        Ok(())
    }

    #[test]
    fn sandbox_glob_triplestar_matches_basename_with_literal() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        sandbox.config("sandbox/read:on")?;

        sandbox.config("allow/read+/dev/***")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_READ, Path::new("/dev")),
            Some(Action::Allow),
            "/dev =~ /dev/***, {sandbox}"
        );

        Ok(())
    }

    #[test]
    fn sandbox_glob_triplestar_matches_basename_with_glob() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        sandbox.config("sandbox/read:on")?;

        sandbox.config("allow/read+/*/***")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_READ, Path::new("/dev")),
            Some(Action::Allow),
            "/dev =~ /*/***, {sandbox}"
        );

        Ok(())
    }

    #[test]
    fn sandbox_glob_triplestar_matches_basename_with_slash_and_literal() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        sandbox.config("sandbox/read:on")?;

        sandbox.config("allow/read+/dev/***")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_READ, Path::new("/dev/")),
            Some(Action::Allow),
            "/dev/ !~ /dev/***, {sandbox}"
        );

        Ok(())
    }

    #[test]
    fn sandbox_glob_triplestar_matches_basename_with_slash_and_glob() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        sandbox.config("sandbox/read:on")?;

        sandbox.config("allow/read+/*/***")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_READ, Path::new("/dev/")),
            Some(Action::Allow),
            "/dev/ !~ /*/***, {sandbox}"
        );

        Ok(())
    }

    #[test]
    fn sandbox_glob_triplestar_matches_pathname_with_literal() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        sandbox.config("sandbox/read:on")?;

        sandbox.config("allow/read+/dev/***")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_READ, Path::new("/dev/null")),
            Some(Action::Allow),
            "/dev/null !~ /dev/***, {sandbox}"
        );

        Ok(())
    }

    #[test]
    fn sandbox_glob_triplestar_matches_pathname_with_glob() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        sandbox.config("sandbox/read:on")?;

        sandbox.config("allow/read+/*/***")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_READ, Path::new("/dev/null")),
            Some(Action::Allow),
            "/dev/null !~ /*/***, {sandbox}"
        );

        Ok(())
    }

    #[test]
    fn sandbox_access_last_matching_rule_wins() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        sandbox.config("sandbox/read:on")?;

        assert_eq!(
            sandbox.match_action(Capability::CAP_READ, Path::new("/etc/passwd")),
            None,
            "{sandbox}"
        );
        sandbox.config("allow/read+/etc/passwd")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_READ, Path::new("/etc/passwd")),
            Some(Action::Allow),
            "{sandbox}"
        );
        sandbox.config("deny/read+/etc/passwd")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_READ, Path::new("/etc/passwd")),
            Some(Action::Deny),
            "{sandbox}"
        );
        sandbox.config("allow/read+/etc/passwd")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_READ, Path::new("/etc/passwd")),
            Some(Action::Allow),
            "{sandbox}"
        );
        sandbox.config("deny/read+/etc/passwd")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_READ, Path::new("/etc/passwd")),
            Some(Action::Deny),
            "{sandbox}"
        );
        for _ in 0..2 {
            sandbox.config("deny/read-/etc/passwd")?;
        }
        assert_eq!(
            sandbox.match_action(Capability::CAP_READ, Path::new("/etc/passwd")),
            Some(Action::Allow),
            "{sandbox}"
        );
        for _ in 0..2 {
            sandbox.config("allow/read-/etc/passwd")?;
        }
        assert_eq!(
            sandbox.match_action(Capability::CAP_READ, Path::new("/etc/passwd")),
            None,
            "{sandbox}"
        );

        assert_eq!(
            sandbox.match_action(Capability::CAP_WRITE, Path::new("/etc/passwd")),
            None,
            "{sandbox}"
        );
        sandbox.config("allow/write+/etc/**")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_WRITE, Path::new("/etc/passwd")),
            Some(Action::Allow),
            "{sandbox}"
        );
        sandbox.config("deny/write+/etc/**")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_WRITE, Path::new("/etc/passwd")),
            Some(Action::Deny),
            "{sandbox}"
        );
        sandbox.config("allow/write+/etc/**")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_WRITE, Path::new("/etc/passwd")),
            Some(Action::Allow),
            "{sandbox}"
        );
        sandbox.config("deny/write+/etc/**")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_WRITE, Path::new("/etc/passwd")),
            Some(Action::Deny),
            "{sandbox}"
        );
        for _ in 0..2 {
            sandbox.config("deny/write-/etc/**")?;
        }
        assert_eq!(
            sandbox.match_action(Capability::CAP_WRITE, Path::new("/etc/passwd")),
            Some(Action::Allow),
            "{sandbox}"
        );
        for _ in 0..2 {
            sandbox.config("allow/write-/etc/**")?;
        }
        assert_eq!(
            sandbox.match_action(Capability::CAP_WRITE, Path::new("/etc/passwd")),
            None,
            "{sandbox}"
        );

        assert_eq!(
            sandbox.match_action(Capability::CAP_EXEC, Path::new("/etc/passwd")),
            None,
            "{sandbox}"
        );
        sandbox.config("allow/exec+/etc/***")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_EXEC, Path::new("/etc/passwd")),
            Some(Action::Allow),
            "{sandbox}"
        );
        sandbox.config("deny/exec+/etc/***")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_EXEC, Path::new("/etc/passwd")),
            Some(Action::Deny),
            "{sandbox}"
        );
        sandbox.config("allow/exec+/etc/***")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_EXEC, Path::new("/etc/passwd")),
            Some(Action::Allow),
            "{sandbox}"
        );
        sandbox.config("deny/exec+/etc/***")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_EXEC, Path::new("/etc/passwd")),
            Some(Action::Deny),
            "{sandbox}"
        );
        for _ in 0..2 {
            sandbox.config("deny/exec-/etc/***")?;
        }
        assert_eq!(
            sandbox.match_action(Capability::CAP_EXEC, Path::new("/etc/passwd")),
            Some(Action::Allow),
            "{sandbox}"
        );
        for _ in 0..2 {
            sandbox.config("allow/exec-/etc/***")?;
        }
        assert_eq!(
            sandbox.match_action(Capability::CAP_EXEC, Path::new("/etc/passwd")),
            None,
            "{sandbox}"
        );

        assert_eq!(
            sandbox.match_action(Capability::CAP_STAT, Path::new("/etc/passwd")),
            None,
            "{sandbox}"
        );
        sandbox.config("allow/stat+/***")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_STAT, Path::new("/etc/passwd")),
            Some(Action::Allow),
            "{sandbox}"
        );
        sandbox.config("deny/stat+/etc/***")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_STAT, Path::new("/etc/passwd")),
            Some(Action::Deny),
            "{sandbox}"
        );
        sandbox.config("allow/stat+/***")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_STAT, Path::new("/etc/passwd")),
            Some(Action::Allow),
            "{sandbox}"
        );
        sandbox.config("deny/stat+/etc/passwd")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_STAT, Path::new("/etc/passwd")),
            Some(Action::Deny),
            "{sandbox}"
        );
        sandbox.config("deny/stat-/etc/***")?;
        sandbox.config("deny/stat-/etc/passwd")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_STAT, Path::new("/etc/passwd")),
            Some(Action::Allow),
            "{sandbox}"
        );
        for _ in 0..2 {
            sandbox.config("allow/stat-/***")?;
        }
        assert_eq!(
            sandbox.match_action(Capability::CAP_STAT, Path::new("/etc/passwd")),
            None,
            "{sandbox}"
        );

        assert_eq!(
            sandbox.match_action(Capability::CAP_BIND, Path::new("/etc/passwd")),
            None,
            "{sandbox}"
        );
        sandbox.config("allow/net/bind+/***")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_BIND, Path::new("/etc/passwd")),
            Some(Action::Allow),
            "{sandbox}"
        );
        sandbox.config("deny/net/bind+/etc/***")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_BIND, Path::new("/etc/passwd")),
            Some(Action::Deny),
            "{sandbox}"
        );
        sandbox.config("allow/net/bind+/***")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_BIND, Path::new("/etc/passwd")),
            Some(Action::Allow),
            "{sandbox}"
        );
        sandbox.config("deny/net/bind+/etc/passwd")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_BIND, Path::new("/etc/passwd")),
            Some(Action::Deny),
            "{sandbox}"
        );
        sandbox.config("deny/net/bind-/etc/***")?;
        sandbox.config("deny/net/bind-/etc/passwd")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_BIND, Path::new("/etc/passwd")),
            Some(Action::Allow),
            "{sandbox}"
        );
        for _ in 0..2 {
            sandbox.config("allow/net/bind-/***")?;
        }
        assert_eq!(
            sandbox.match_action(Capability::CAP_BIND, Path::new("/etc/passwd")),
            None,
            "{sandbox}"
        );

        assert_eq!(
            sandbox.match_action(Capability::CAP_CONNECT, Path::new("/etc/passwd")),
            None,
            "{sandbox}"
        );
        sandbox.config("allow/net/connect+/***")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_CONNECT, Path::new("/etc/passwd")),
            Some(Action::Allow),
            "{sandbox}"
        );
        sandbox.config("deny/net/connect+/etc/***")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_CONNECT, Path::new("/etc/passwd")),
            Some(Action::Deny),
            "{sandbox}"
        );
        sandbox.config("allow/net/connect+/***")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_CONNECT, Path::new("/etc/passwd")),
            Some(Action::Allow),
            "{sandbox}"
        );
        sandbox.config("deny/net/connect+/etc/passwd")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_CONNECT, Path::new("/etc/passwd")),
            Some(Action::Deny),
            "{sandbox}"
        );
        sandbox.config("deny/net/connect-/etc/***")?;
        sandbox.config("deny/net/connect-/etc/passwd")?;
        assert_eq!(
            sandbox.match_action(Capability::CAP_CONNECT, Path::new("/etc/passwd")),
            Some(Action::Allow),
            "{sandbox}"
        );
        for _ in 0..2 {
            sandbox.config("allow/net/connect-/***")?;
        }
        assert_eq!(
            sandbox.match_action(Capability::CAP_CONNECT, Path::new("/etc/passwd")),
            None,
            "{sandbox}"
        );

        Ok(())
    }

    #[test]
    fn sandbox_check_filter_ip_port_range() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        sandbox.config("sandbox/net:on")?;
        sandbox.config("allow/net/connect+any!0")?;

        let addr = "127.0.0.1".parse::<IpAddr>().unwrap();
        assert_eq!(
            sandbox.check_ip(Capability::CAP_CONNECT, addr, 0),
            (Action::Allow, true)
        );
        for port in 1..=65535 {
            assert_eq!(
                sandbox.check_ip(Capability::CAP_CONNECT, addr, port),
                (Action::Deny, false),
                "{addr}!{port} {sandbox}"
            );
        }

        sandbox.config("filter/net/connect+any!1-65535")?;
        assert_eq!(
            sandbox.check_ip(Capability::CAP_CONNECT, addr, 0),
            (Action::Allow, true)
        );
        for port in 1..=65535 {
            assert_eq!(
                sandbox.check_ip(Capability::CAP_CONNECT, addr, port),
                (Action::Deny, true),
                "{addr}!{port} {sandbox}"
            );
        }

        Ok(())
    }

    #[test]
    fn sandbox_check_netlink_01() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert!(
            sandbox.netlink_families.is_empty(),
            "netlink_families:{}",
            sandbox.netlink_families.bits()
        );

        sandbox.config("allow/net/link+route")?;
        assert!(
            !sandbox.netlink_families.is_empty(),
            "netlink_families:{}",
            sandbox.netlink_families.bits()
        );
        assert!(
            sandbox
                .netlink_families
                .contains(NetlinkFamily::NETLINK_ROUTE),
            "netlink_families:{}",
            sandbox.netlink_families.bits()
        );

        Ok(())
    }

    #[test]
    fn sandbox_check_netlink_02() -> TestResult<()> {
        let mut sandbox = Sandbox::default();
        assert!(
            sandbox.netlink_families.is_empty(),
            "netlink_families:{}",
            sandbox.netlink_families.bits()
        );

        sandbox.config("allow/net/link+route,crypto,ecryptfs,inet_diag")?;
        sandbox.config("allow/net/link-ecryptfs,sock_diag")?;
        assert!(
            !sandbox.netlink_families.is_empty(),
            "netlink_families:{}",
            sandbox.netlink_families.bits()
        );
        assert!(
            sandbox
                .netlink_families
                .contains(NetlinkFamily::NETLINK_ROUTE),
            "netlink_families:{}",
            sandbox.netlink_families.bits()
        );
        assert!(
            sandbox
                .netlink_families
                .contains(NetlinkFamily::NETLINK_CRYPTO),
            "netlink_families:{}",
            sandbox.netlink_families.bits()
        );
        assert!(
            !sandbox
                .netlink_families
                .contains(NetlinkFamily::NETLINK_ECRYPTFS),
            "netlink_families:{}",
            sandbox.netlink_families.bits()
        );
        assert!(
            !sandbox
                .netlink_families
                .contains(NetlinkFamily::NETLINK_SOCK_DIAG),
            "netlink_families:{}",
            sandbox.netlink_families.bits()
        );

        Ok(())
    }
}
