Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,13 @@ feat_selinux = [
# "feat_smack" == enable support for SMACK Security Context (by using `--features feat_smack`)
# NOTE:
# * Running a uutils compiled with `feat_smack` requires a SMACK enabled Kernel at run time.
feat_smack = ["ls/smack"]
feat_smack = [
"id/smack",
"ls/smack",
"mkdir/smack",
"mkfifo/smack",
"mknod/smack",
]
##
## feature sets
## (common/core and Tier1) feature sets
Expand Down
1 change: 1 addition & 0 deletions src/uu/id/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,4 @@ path = "src/main.rs"

[features]
feat_selinux = ["selinux"]
smack = ["uucore/smack"]
2 changes: 1 addition & 1 deletion src/uu/id/locales/en-US.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ id-error-names-real-ids-require-flags = printing only names or real IDs requires
id-error-zero-not-permitted-default = option --zero not permitted in default format
id-error-cannot-print-context-with-user = cannot print security context when user specified
id-error-cannot-get-context = can't get process context
id-error-context-selinux-only = --context (-Z) works only on an SELinux-enabled kernel
id-error-context-security-only = --context (-Z) works only on an SELinux/SMACK-enabled kernel
id-error-no-such-user = { $user }: no such user
id-error-cannot-find-group-name = cannot find name for group ID { $gid }
id-error-cannot-find-user-name = cannot find name for user ID { $uid }
Expand Down
2 changes: 1 addition & 1 deletion src/uu/id/locales/fr-FR.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ id-error-names-real-ids-require-flags = l'affichage des noms uniquement ou des I
id-error-zero-not-permitted-default = l'option --zero n'est pas autorisée dans le format par défaut
id-error-cannot-print-context-with-user = impossible d'afficher le contexte de sécurité quand un utilisateur est spécifié
id-error-cannot-get-context = impossible d'obtenir le contexte du processus
id-error-context-selinux-only = --context (-Z) ne fonctionne que sur un noyau avec SELinux activé
id-error-context-security-only = --context (-Z) ne fonctionne que sur un noyau avec SELinux/SMACK activé
id-error-no-such-user = { $user } : utilisateur inexistant
id-error-cannot-find-group-name = impossible de trouver le nom pour l'ID de groupe { $gid }
id-error-cannot-find-user-name = impossible de trouver le nom pour l'ID utilisateur { $uid }
Expand Down
80 changes: 52 additions & 28 deletions src/uu/id/src/id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ macro_rules! cstr2cow {
}

fn get_context_help_text() -> String {
#[cfg(not(feature = "selinux"))]
#[cfg(not(any(feature = "selinux", feature = "smack")))]
return translate!("id-context-help-disabled");
#[cfg(feature = "selinux")]
#[cfg(any(feature = "selinux", feature = "smack"))]
return translate!("id-context-help-enabled");
}

Expand Down Expand Up @@ -98,7 +98,10 @@ struct State {
rflag: bool, // --real
zflag: bool, // --zero
cflag: bool, // --context
#[cfg(feature = "selinux")]
selinux_supported: bool,
#[cfg(feature = "smack")]
smack_supported: bool,
ids: Option<Ids>,
// The behavior for calling GNU's `id` and calling GNU's `id $USER` is similar but different.
// * The SELinux context is only displayed without a specified user.
Expand Down Expand Up @@ -136,16 +139,10 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
zflag: matches.get_flag(options::OPT_ZERO),
cflag: matches.get_flag(options::OPT_CONTEXT),

selinux_supported: {
#[cfg(feature = "selinux")]
{
uucore::selinux::is_selinux_enabled()
}
#[cfg(not(feature = "selinux"))]
{
false
}
},
#[cfg(feature = "selinux")]
selinux_supported: uucore::selinux::is_selinux_enabled(),
#[cfg(feature = "smack")]
smack_supported: uucore::smack::is_smack_enabled(),
user_specified: !users.is_empty(),
ids: None,
};
Expand Down Expand Up @@ -179,26 +176,42 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let line_ending = LineEnding::from_zero_flag(state.zflag);

if state.cflag {
return if state.selinux_supported {
// print SElinux context and exit
#[cfg(all(any(target_os = "linux", target_os = "android"), feature = "selinux"))]
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unrelated to the SMACK fixes, but I am unsure as to why we need this linux and android flag here if we are targeting the SELINUX feature

// SELinux context
#[cfg(feature = "selinux")]
if state.selinux_supported {
if let Ok(context) = selinux::SecurityContext::current(false) {
let bytes = context.as_bytes();
print!("{}{line_ending}", String::from_utf8_lossy(bytes));
} else {
// print error because `cflag` was explicitly requested
return Err(USimpleError::new(
1,
translate!("id-error-cannot-get-context"),
));
return Ok(());
}
Ok(())
} else {
Err(USimpleError::new(
return Err(USimpleError::new(
1,
translate!("id-error-context-selinux-only"),
))
};
translate!("id-error-cannot-get-context"),
));
}

// SMACK label
#[cfg(feature = "smack")]
if state.smack_supported {
match uucore::smack::get_smack_label_for_self() {
Ok(label) => {
print!("{label}{line_ending}");
return Ok(());
}
Err(_) => {
return Err(USimpleError::new(
1,
translate!("id-error-cannot-get-context"),
));
}
}
}

// Neither SELinux nor SMACK supported
return Err(USimpleError::new(
1,
translate!("id-error-context-security-only"),
));
}

for i in 0..=users.len() {
Expand Down Expand Up @@ -666,7 +679,7 @@ fn id_print(state: &State, groups: &[u32]) {
.join(",")
);

#[cfg(all(any(target_os = "linux", target_os = "android"), feature = "selinux"))]
#[cfg(feature = "selinux")]
if state.selinux_supported
&& !state.user_specified
&& std::env::var_os("POSIXLY_CORRECT").is_none()
Expand All @@ -677,6 +690,17 @@ fn id_print(state: &State, groups: &[u32]) {
print!(" context={}", String::from_utf8_lossy(bytes));
}
}

#[cfg(feature = "smack")]
if state.smack_supported
&& !state.user_specified
&& std::env::var_os("POSIXLY_CORRECT").is_none()
{
// print SMACK label (does not depend on "-Z")
if let Ok(label) = uucore::smack::get_smack_label_for_self() {
print!(" context={label}");
}
}
}

#[cfg(not(any(target_os = "linux", target_os = "android", target_os = "openbsd")))]
Expand Down
1 change: 1 addition & 0 deletions src/uu/mkdir/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ fluent = { workspace = true }

[features]
selinux = ["uucore/selinux"]
smack = ["uucore/smack"]

[[bin]]
name = "mkdir"
Expand Down
19 changes: 12 additions & 7 deletions src/uu/mkdir/src/mkdir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ mod options {
pub const PARENTS: &str = "parents";
pub const VERBOSE: &str = "verbose";
pub const DIRS: &str = "dirs";
pub const SELINUX: &str = "z";
pub const SECURITY_CONTEXT: &str = "z";
pub const CONTEXT: &str = "context";
}

Expand All @@ -42,8 +42,8 @@ pub struct Config<'a> {
/// Print message for each created directory.
pub verbose: bool,

/// Set `SELinux` security context.
pub set_selinux_context: bool,
/// Set security context (SELinux/SMACK).
pub set_security_context: bool,

/// Specific `SELinux` context.
pub context: Option<&'a String>,
Expand Down Expand Up @@ -79,7 +79,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let recursive = matches.get_flag(options::PARENTS);

// Extract the SELinux related flags and options
let set_selinux_context = matches.get_flag(options::SELINUX);
let set_security_context = matches.get_flag(options::SECURITY_CONTEXT);
let context = matches.get_one::<String>(options::CONTEXT);

match get_mode(&matches) {
Expand All @@ -88,7 +88,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
recursive,
mode,
verbose,
set_selinux_context: set_selinux_context || context.is_some(),
set_security_context: set_security_context || context.is_some(),
context,
};
exec(dirs, &config)
Expand Down Expand Up @@ -129,7 +129,7 @@ pub fn uu_app() -> Command {
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(options::SELINUX)
Arg::new(options::SECURITY_CONTEXT)
.short('Z')
.help(translate!("mkdir-help-selinux"))
.action(ArgAction::SetTrue),
Expand Down Expand Up @@ -292,14 +292,19 @@ fn create_single_dir(path: &Path, is_parent: bool, config: &Config) -> UResult<(

// Apply SELinux context if requested
#[cfg(feature = "selinux")]
if config.set_selinux_context && uucore::selinux::is_selinux_enabled() {
if config.set_security_context && uucore::selinux::is_selinux_enabled() {
if let Err(e) = uucore::selinux::set_selinux_security_context(path, config.context)
{
let _ = std::fs::remove_dir(path);
return Err(USimpleError::new(1, e.to_string()));
}
}

// Apply SMACK context if requested
#[cfg(feature = "smack")]
if config.set_security_context {
uucore::smack::set_smack_label_for_new_dir(path, config.context)?;
}
Ok(())
}

Expand Down
1 change: 1 addition & 0 deletions src/uu/mkfifo/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ fluent = { workspace = true }

[features]
selinux = ["uucore/selinux"]
smack = ["uucore/smack"]

[[bin]]
name = "mkfifo"
Expand Down
18 changes: 14 additions & 4 deletions src/uu/mkfifo/src/mkfifo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use uucore::{format_usage, show};

mod options {
pub static MODE: &str = "mode";
pub static SELINUX: &str = "Z";
pub static SECURITY_CONTEXT: &str = "Z";
pub static CONTEXT: &str = "context";
pub static FIFO: &str = "fifo";
}
Expand Down Expand Up @@ -62,10 +62,10 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
#[cfg(feature = "selinux")]
{
// Extract the SELinux related flags and options
let set_selinux_context = matches.get_flag(options::SELINUX);
let set_security_context = matches.get_flag(options::SECURITY_CONTEXT);
let context = matches.get_one::<String>(options::CONTEXT);

if set_selinux_context || context.is_some() {
if set_security_context || context.is_some() {
use std::path::Path;
if let Err(e) =
uucore::selinux::set_selinux_security_context(Path::new(&f), context)
Expand All @@ -75,6 +75,16 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
}
}
}

// Apply SMACK context if requested
#[cfg(feature = "smack")]
{
let set_security_context = matches.get_flag(options::SECURITY_CONTEXT);
let context = matches.get_one::<String>(options::CONTEXT);
if set_security_context || context.is_some() {
uucore::smack::set_smack_label_for_new_file(&f, context)?;
}
}
}

Ok(())
Expand All @@ -95,7 +105,7 @@ pub fn uu_app() -> Command {
.value_name("MODE"),
)
.arg(
Arg::new(options::SELINUX)
Arg::new(options::SECURITY_CONTEXT)
.short('Z')
.help(translate!("mkfifo-help-selinux"))
.action(ArgAction::SetTrue),
Expand Down
1 change: 1 addition & 0 deletions src/uu/mknod/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ fluent = { workspace = true }

[features]
selinux = ["uucore/selinux"]
smack = ["uucore/smack"]

[[bin]]
name = "mknod"
Expand Down
27 changes: 18 additions & 9 deletions src/uu/mknod/src/mknod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ mod options {
pub const TYPE: &str = "type";
pub const MAJOR: &str = "major";
pub const MINOR: &str = "minor";
pub const SELINUX: &str = "z";
pub const SECURITY_CONTEXT: &str = "z";
pub const CONTEXT: &str = "context";
}

Expand Down Expand Up @@ -59,10 +59,10 @@ pub struct Config<'a> {

pub dev: dev_t,

/// Set `SELinux` security context.
pub set_selinux_context: bool,
/// Set security context (SELinux/SMACK).
pub set_security_context: bool,

/// Specific `SELinux` context.
/// Specific security context (SELinux/SMACK).
pub context: Option<&'a String>,
}

Expand Down Expand Up @@ -93,7 +93,7 @@ fn mknod(file_name: &str, config: Config) -> i32 {

// Apply SELinux context if requested
#[cfg(feature = "selinux")]
if config.set_selinux_context {
if config.set_security_context {
if let Err(e) = uucore::selinux::set_selinux_security_context(
std::path::Path::new(file_name),
config.context,
Expand All @@ -105,6 +105,15 @@ fn mknod(file_name: &str, config: Config) -> i32 {
}
}

// Apply SMACK context if requested
#[cfg(feature = "smack")]
if config.set_security_context {
if let Err(e) = uucore::smack::set_smack_label_for_new_file(file_name, config.context) {
eprintln!("{}: {}", uucore::util_name(), e);
return 1;
}
}

errno
}
}
Expand All @@ -129,8 +138,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
.get_one::<String>("name")
.expect("Missing argument 'NAME'");

// Extract the SELinux related flags and options
let set_selinux_context = matches.get_flag(options::SELINUX);
// Extract the security context related flags and options
let set_security_context = matches.get_flag(options::SECURITY_CONTEXT);
let context = matches.get_one::<String>(options::CONTEXT);

let dev = match (
Expand Down Expand Up @@ -158,7 +167,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
mode,
use_umask,
dev,
set_selinux_context: set_selinux_context || context.is_some(),
set_security_context: set_security_context || context.is_some(),
context,
};

Expand Down Expand Up @@ -209,7 +218,7 @@ pub fn uu_app() -> Command {
.value_parser(value_parser!(u64)),
)
.arg(
Arg::new(options::SELINUX)
Arg::new(options::SECURITY_CONTEXT)
.short('Z')
.help(translate!("mknod-help-selinux"))
.action(ArgAction::SetTrue),
Expand Down
5 changes: 5 additions & 0 deletions src/uucore/locales/en-US.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ selinux-error-context-retrieval-failure = failed to retrieve the security contex
selinux-error-context-set-failure = failed to set default file creation context to '{ $context }': { $error }
selinux-error-context-conversion-failure = failed to set default file creation context to '{ $context }': { $error }

# SMACK error messages
smack-error-not-enabled = SMACK is not enabled on this system
smack-error-label-retrieval-failure = failed to get security context: { $error }
smack-error-label-set-failure = failed to set default file creation context to '{ $context }': { $error }
smack-error-no-label-set = no security context set

# Safe traversal error messages
safe-traversal-error-path-contains-null = path contains null byte
Expand Down
Loading
Loading