pub enum UsernsGrant {
ApparmorAbsent,
RestrictionDisabledHostWide,
ProfileConfining,
Withheld,
}Expand description
Where this host’s permission to create an unprivileged user namespace comes from.
Three of the four variants permit the namespace, and they are not interchangeable: AppArmor
being absent is a distribution fact nobody chose, the shipped profile confining mur is the
configuration murmur ships, and the restriction being switched off host-wide removes the
hardening for every binary on the machine. The three reach the same achieved class, so
mur doctor, --explain-scope and the session trace each report the variant: without it a
sealed result obtained on a weakened host cannot be told apart from one obtained through the
profile.
The grant never decides anything: whether a namespace, a private /tmp or sealed is
available is decided by crate::namespace_probe creating them. The grant only words a
refusal once an attempt has failed.
Variants§
ApparmorAbsent
AppArmor is not enabled on this host (Fedora, Arch, a kernel built without it, …). There is no restriction to lift and no profile to install.
RestrictionDisabledHostWide
AppArmor is enabled but kernel.apparmor_restrict_unprivileged_userns is 0, so no binary
on this host is transitioned into the restricted unprivileged_userns profile. Legitimate,
and on some hosts the only option — but it is not the configuration murmur ships, and it is
what W-SEC-013 reports.
ProfileConfining
The restriction is on and this process is confined by a profile whose name begins with
SEALED_APPARMOR_PROFILE_NAME — the shipped profile, or the checkout profile
scripts/install-dev-apparmor.sh generates. The grant is narrow: it applies to this binary
and nothing else.
Withheld
The restriction is on and nothing grants this binary anything. A container whose own profile permits user namespaces reads this too, and is not refused for it. The default, so an unprobed host claims nothing.
Implementations§
Source§impl UsernsGrant
impl UsernsGrant
Sourcepub const ALL: &'static [UsernsGrant]
pub const ALL: &'static [UsernsGrant]
Every variant, so a caller reasoning about “which grant did this host give” cannot silently
miss one. Same convention as SealedBlocker::ALL.
Sourcepub fn wire_name(self) -> &'static str
pub fn wire_name(self) -> &'static str
Stable wire name, as it appears in --explain-scope --json, in session_start and in
mur doctor. Distinct per variant, and not a Debug rendering, which is free to change.
Sourcepub fn summary(self) -> &'static str
pub fn summary(self) -> &'static str
One line naming the mechanism in words, for the mur doctor block. States what the grant
covers — one binary or the whole host — because that is the difference the wire name alone
does not spell out.
Sourcepub fn from_readings(
enabled: Option<&str>,
restricted: Option<&str>,
current_profile: Option<&str>,
) -> UsernsGrant
pub fn from_readings( enabled: Option<&str>, restricted: Option<&str>, current_profile: Option<&str>, ) -> UsernsGrant
The whole decision, over the three host readings that produce it: whether AppArmor is
enabled, whether its restrict_unprivileged_userns knob is on, and what profile confines
this process. Each argument is the file’s trimmed contents, or None when it is missing or
empty.
Pure, and separate from the reading for the same reason classify_installed_profile is:
every combination is then testable on any OS, with no /sys and no /proc.
linux::userns_grant is the reader and holds no logic of its own.
A missing or unreadable restriction knob counts as not restricted, not as withheld — a kernel that does not implement the knob does not restrict anything.
Trait Implementations§
Source§impl Clone for UsernsGrant
impl Clone for UsernsGrant
impl Copy for UsernsGrant
Source§impl Debug for UsernsGrant
impl Debug for UsernsGrant
Source§impl Default for UsernsGrant
impl Default for UsernsGrant
impl Eq for UsernsGrant
Source§impl Hash for UsernsGrant
impl Hash for UsernsGrant
Source§impl PartialEq for UsernsGrant
impl PartialEq for UsernsGrant
Source§impl Serialize for UsernsGrant
impl Serialize for UsernsGrant
impl StructuralPartialEq for UsernsGrant
Auto Trait Implementations§
impl Forget for UsernsGrant
impl Freeze for UsernsGrant
impl Move for UsernsGrant
impl RefUnwindSafe for UsernsGrant
impl Send for UsernsGrant
impl Sync for UsernsGrant
impl Unpin for UsernsGrant
impl UnsafeUnpin for UsernsGrant
impl UnwindSafe for UsernsGrant
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 moreSource§impl<T> NoneValue for Twhere
T: Default,
impl<T> NoneValue for Twhere
T: Default,
Source§type NoneType = T
type NoneType = T
NoneValue::null_value produces.