Skip to content

Commit a34b2f0

Browse files
committed
Add SMACK support to id, mkdir, mkfifo, mknod utilities
1 parent 77c3498 commit a34b2f0

File tree

12 files changed

+170
-42
lines changed

12 files changed

+170
-42
lines changed

Cargo.toml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,13 @@ feat_selinux = [
6868
# "feat_smack" == enable support for SMACK Security Context (by using `--features feat_smack`)
6969
# NOTE:
7070
# * Running a uutils compiled with `feat_smack` requires a SMACK enabled Kernel at run time.
71-
feat_smack = ["ls/smack"]
71+
feat_smack = [
72+
"id/smack",
73+
"ls/smack",
74+
"mkdir/smack",
75+
"mkfifo/smack",
76+
"mknod/smack",
77+
]
7278
##
7379
## feature sets
7480
## (common/core and Tier1) feature sets

src/uu/id/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,4 @@ path = "src/main.rs"
2929

3030
[features]
3131
feat_selinux = ["selinux"]
32+
smack = ["uucore/smack"]

src/uu/id/src/id.rs

Lines changed: 52 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ macro_rules! cstr2cow {
6262
}
6363

6464
fn get_context_help_text() -> String {
65-
#[cfg(not(feature = "selinux"))]
65+
#[cfg(not(any(feature = "selinux", feature = "smack")))]
6666
return translate!("id-context-help-disabled");
67-
#[cfg(feature = "selinux")]
67+
#[cfg(any(feature = "selinux", feature = "smack"))]
6868
return translate!("id-context-help-enabled");
6969
}
7070

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

139-
selinux_supported: {
140-
#[cfg(feature = "selinux")]
141-
{
142-
uucore::selinux::is_selinux_enabled()
143-
}
144-
#[cfg(not(feature = "selinux"))]
145-
{
146-
false
147-
}
148-
},
142+
#[cfg(feature = "selinux")]
143+
selinux_supported: uucore::selinux::is_selinux_enabled(),
144+
#[cfg(feature = "smack")]
145+
smack_supported: uucore::smack::is_smack_enabled(),
149146
user_specified: !users.is_empty(),
150147
ids: None,
151148
};
@@ -179,26 +176,42 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
179176
let line_ending = LineEnding::from_zero_flag(state.zflag);
180177

181178
if state.cflag {
182-
return if state.selinux_supported {
183-
// print SElinux context and exit
184-
#[cfg(all(any(target_os = "linux", target_os = "android"), feature = "selinux"))]
179+
// SELinux context
180+
#[cfg(feature = "selinux")]
181+
if state.selinux_supported {
185182
if let Ok(context) = selinux::SecurityContext::current(false) {
186183
let bytes = context.as_bytes();
187184
print!("{}{line_ending}", String::from_utf8_lossy(bytes));
188-
} else {
189-
// print error because `cflag` was explicitly requested
190-
return Err(USimpleError::new(
191-
1,
192-
translate!("id-error-cannot-get-context"),
193-
));
185+
return Ok(());
194186
}
195-
Ok(())
196-
} else {
197-
Err(USimpleError::new(
187+
return Err(USimpleError::new(
198188
1,
199-
translate!("id-error-context-selinux-only"),
200-
))
201-
};
189+
translate!("id-error-cannot-get-context"),
190+
));
191+
}
192+
193+
// SMACK label
194+
#[cfg(feature = "smack")]
195+
if state.smack_supported {
196+
match uucore::smack::get_smack_label_for_self() {
197+
Ok(label) => {
198+
print!("{label}{line_ending}");
199+
return Ok(());
200+
}
201+
Err(_) => {
202+
return Err(USimpleError::new(
203+
1,
204+
translate!("id-error-cannot-get-context"),
205+
));
206+
}
207+
}
208+
}
209+
210+
// Neither SELinux nor SMACK supported
211+
return Err(USimpleError::new(
212+
1,
213+
translate!("id-error-context-selinux-only"),
214+
));
202215
}
203216

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

669-
#[cfg(all(any(target_os = "linux", target_os = "android"), feature = "selinux"))]
682+
#[cfg(feature = "selinux")]
670683
if state.selinux_supported
671684
&& !state.user_specified
672685
&& std::env::var_os("POSIXLY_CORRECT").is_none()
@@ -677,6 +690,17 @@ fn id_print(state: &State, groups: &[u32]) {
677690
print!(" context={}", String::from_utf8_lossy(bytes));
678691
}
679692
}
693+
694+
#[cfg(feature = "smack")]
695+
if state.smack_supported
696+
&& !state.user_specified
697+
&& std::env::var_os("POSIXLY_CORRECT").is_none()
698+
{
699+
// print SMACK label (does not depend on "-Z")
700+
if let Ok(label) = uucore::smack::get_smack_label_for_self() {
701+
print!(" context={label}");
702+
}
703+
}
680704
}
681705

682706
#[cfg(not(any(target_os = "linux", target_os = "android", target_os = "openbsd")))]

src/uu/mkdir/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ fluent = { workspace = true }
2424

2525
[features]
2626
selinux = ["uucore/selinux"]
27+
smack = ["uucore/smack"]
2728

2829
[[bin]]
2930
name = "mkdir"

src/uu/mkdir/src/mkdir.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,16 @@ fn create_single_dir(path: &Path, is_parent: bool, config: &Config) -> UResult<(
300300
}
301301
}
302302

303+
// Apply SMACK context if requested
304+
#[cfg(feature = "smack")]
305+
if config.set_selinux_context && uucore::smack::is_smack_enabled() {
306+
if let Some(ctx) = config.context {
307+
if let Err(e) = uucore::smack::set_smack_label_for_path(path, ctx) {
308+
let _ = std::fs::remove_dir(path);
309+
return Err(USimpleError::new(1, e.to_string()));
310+
}
311+
}
312+
}
303313
Ok(())
304314
}
305315

src/uu/mkfifo/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ fluent = { workspace = true }
2525

2626
[features]
2727
selinux = ["uucore/selinux"]
28+
smack = ["uucore/smack"]
2829

2930
[[bin]]
3031
name = "mkfifo"

src/uu/mkfifo/src/mkfifo.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,23 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
7575
}
7676
}
7777
}
78+
79+
// Apply SMACK context if requested
80+
#[cfg(feature = "smack")]
81+
{
82+
let set_smack_context = matches.get_flag(options::SELINUX);
83+
let context = matches.get_one::<String>(options::CONTEXT);
84+
85+
if (set_smack_context || context.is_some()) && uucore::smack::is_smack_enabled() {
86+
if let Some(ctx) = context {
87+
use std::path::Path;
88+
if let Err(e) = uucore::smack::set_smack_label_for_path(Path::new(&f), ctx) {
89+
let _ = fs::remove_file(&f);
90+
return Err(USimpleError::new(1, e.to_string()));
91+
}
92+
}
93+
}
94+
}
7895
}
7996

8097
Ok(())

src/uu/mknod/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ fluent = { workspace = true }
2626

2727
[features]
2828
selinux = ["uucore/selinux"]
29+
smack = ["uucore/smack"]
2930

3031
[[bin]]
3132
name = "mknod"

src/uu/mknod/src/mknod.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,21 @@ fn mknod(file_name: &str, config: Config) -> i32 {
105105
}
106106
}
107107

108+
// Apply SMACK context if requested
109+
#[cfg(feature = "smack")]
110+
if config.set_selinux_context && uucore::smack::is_smack_enabled() {
111+
if let Some(ctx) = config.context {
112+
if let Err(e) =
113+
uucore::smack::set_smack_label_for_path(std::path::Path::new(file_name), ctx)
114+
{
115+
// if it fails, delete the file
116+
let _ = std::fs::remove_file(file_name);
117+
eprintln!("{}: {}", uucore::util_name(), e);
118+
return 1;
119+
}
120+
}
121+
}
122+
108123
errno
109124
}
110125
}

src/uucore/locales/en-US.ftl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ selinux-error-context-retrieval-failure = failed to retrieve the security contex
4646
selinux-error-context-set-failure = failed to set default file creation context to '{ $context }': { $error }
4747
selinux-error-context-conversion-failure = failed to set default file creation context to '{ $context }': { $error }
4848
49+
# SMACK error messages
50+
smack-error-not-enabled = SMACK is not enabled on this system
51+
smack-error-label-retrieval-failure = failed to get security context: { $error }
52+
smack-error-label-set-failure = failed to set default file creation context to '{ $context }': { $error }
53+
smack-error-no-label-set = no security context set
4954
5055
# Safe traversal error messages
5156
safe-traversal-error-path-contains-null = path contains null byte

0 commit comments

Comments
 (0)