pub enum SealedBlocker {
NotLinux,
AppArmorProfileMissing,
NamespaceCreationDenied,
IdMapDenied,
MountDenied,
PivotRootDenied,
KernelUnsupported,
LandlockUnavailable,
NetworkNamespaceUnavailable,
ProbeUnavailable,
}Expand description
The one mechanism that stands between this host and sealed, named specifically enough that
the refusal carries a command the operator can run.
Deliberately a small closed enum rather than a free-form string: containment.rs renders it,
sandbox.rs derives it from the probe, and the manual-verification document asserts the exact
text of each rendering.
Variants§
NotLinux
Not Linux. Mount namespaces do not exist here and never will — the same permanence
EnforcementTier::EnvironmentOnly carries.
AppArmorProfileMissing
AppArmor’s unprivileged-user-namespace restriction is active and this binary is not
confined by the shipped SEALED_APPARMOR_PROFILE_NAME profile.
NamespaceCreationDenied
unshare(CLONE_NEWUSER | CLONE_NEWNS) was refused outright — the container case: no
CAP_SYS_ADMIN, or the container’s own seccomp filter blocking the syscall.
IdMapDenied
The namespace was created, but writing the identity uid_map/gid_map was refused, so the
process cannot own it. Nothing to do with CAP_SYS_ADMIN or containers.
MountDenied
The namespace was created, but mount(2) inside it was refused. The signature of a
confinement that permits userns_create and then denies CAP_SYS_ADMIN.
PivotRootDenied
The namespace was created and mount(2) inside it worked, but the pivot_root(2)
sequence the composed root’s step 6 performs did not. A separate finding from
Self::MountDenied because the two have separate remediations: mount is what an
AppArmor profile grants, while pivot_root is a distinct rule in that profile and a
distinct entry in a container runtime’s seccomp allowlist, so a host can grant one and
refuse the other.
KernelUnsupported
The kernel has no unprivileged user namespace support at all (CONFIG_USER_NS=n, or
user.max_user_namespaces=0).
Namespaces are available but Landlock is not, so the defence-in-depth layer sealed
is required to keep would be missing. sealed is strictly stronger than scoped; a host
that cannot back scoped cannot back sealed either.
The composed root is built inside the capsule’s network namespace, and this host created the user namespace but could not finish the network namespace or enter it.
The probe itself could not run — a child could not be forked, waited for, or reported
nothing — so whether this host can back sealed is unknown.
Implementations§
Source§impl SealedBlocker
impl SealedBlocker
Sourcepub const ALL: &'static [SealedBlocker]
pub const ALL: &'static [SealedBlocker]
Every variant, so a caller that has to reason about “which refusal did this host give”
cannot silently miss one. Added because a hand-maintained list of the expected refusal
texts in murmur-cli’s CLI test drifted the moment a variant was added, and the drift
showed up as a failing assertion about the host rather than about the list.
Trait Implementations§
Source§impl Clone for SealedBlocker
impl Clone for SealedBlocker
impl Copy for SealedBlocker
Source§impl Debug for SealedBlocker
impl Debug for SealedBlocker
impl Eq for SealedBlocker
Source§impl Hash for SealedBlocker
impl Hash for SealedBlocker
Source§impl PartialEq for SealedBlocker
impl PartialEq for SealedBlocker
Source§impl Serialize for SealedBlocker
impl Serialize for SealedBlocker
impl StructuralPartialEq for SealedBlocker
Auto Trait Implementations§
impl Forget for SealedBlocker
impl Freeze for SealedBlocker
impl Move for SealedBlocker
impl RefUnwindSafe for SealedBlocker
impl Send for SealedBlocker
impl Sync for SealedBlocker
impl Unpin for SealedBlocker
impl UnsafeUnpin for SealedBlocker
impl UnwindSafe for SealedBlocker
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more