mirror of
https://github.com/uutils/coreutils.git
synced 2026-06-10 15:48:22 -07:00
Add SMACK support to id, mkdir, mkfifo, mknod utilities (#9910)
* Add SMACK support to id, mkdir, mkfifo, mknod utilities * Address review comments: refactor SMACK helpers and rename SELinux flags * Use official Arch Linux download URL for SMACK CI * smack: refactor to single set_smack_label_and_cleanup function
This commit is contained in:
+7
-1
@@ -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
|
||||
|
||||
@@ -29,3 +29,4 @@ path = "src/main.rs"
|
||||
|
||||
[features]
|
||||
feat_selinux = ["selinux"]
|
||||
smack = ["uucore/smack"]
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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 }
|
||||
|
||||
+52
-28
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -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,
|
||||
};
|
||||
@@ -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"))]
|
||||
// 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() {
|
||||
@@ -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()
|
||||
@@ -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")))]
|
||||
|
||||
@@ -24,6 +24,7 @@ fluent = { workspace = true }
|
||||
|
||||
[features]
|
||||
selinux = ["uucore/selinux"]
|
||||
smack = ["uucore/smack"]
|
||||
|
||||
[[bin]]
|
||||
name = "mkdir"
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
@@ -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>,
|
||||
@@ -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) {
|
||||
@@ -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)
|
||||
@@ -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),
|
||||
@@ -292,7 +292,7 @@ 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);
|
||||
@@ -300,6 +300,13 @@ fn create_single_dir(path: &Path, is_parent: bool, config: &Config) -> UResult<(
|
||||
}
|
||||
}
|
||||
|
||||
// Apply SMACK context if requested
|
||||
#[cfg(feature = "smack")]
|
||||
if config.set_security_context {
|
||||
uucore::smack::set_smack_label_and_cleanup(path, config.context, |p| {
|
||||
std::fs::remove_dir(p)
|
||||
})?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ fluent = { workspace = true }
|
||||
|
||||
[features]
|
||||
selinux = ["uucore/selinux"]
|
||||
smack = ["uucore/smack"]
|
||||
|
||||
[[bin]]
|
||||
name = "mkfifo"
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
@@ -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)
|
||||
@@ -75,6 +75,18 @@ 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_and_cleanup(&f, context, |p| {
|
||||
std::fs::remove_file(p)
|
||||
})?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -95,7 +107,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),
|
||||
|
||||
@@ -26,6 +26,7 @@ fluent = { workspace = true }
|
||||
|
||||
[features]
|
||||
selinux = ["uucore/selinux"]
|
||||
smack = ["uucore/smack"]
|
||||
|
||||
[[bin]]
|
||||
name = "mknod"
|
||||
|
||||
@@ -23,7 +23,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";
|
||||
}
|
||||
|
||||
@@ -54,10 +54,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>,
|
||||
}
|
||||
|
||||
@@ -88,7 +88,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,
|
||||
@@ -100,6 +100,19 @@ 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_and_cleanup(file_name, config.context, |p| {
|
||||
std::fs::remove_file(p)
|
||||
})
|
||||
{
|
||||
eprintln!("{}: {}", uucore::util_name(), e);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
errno
|
||||
}
|
||||
}
|
||||
@@ -124,8 +137,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 (
|
||||
@@ -153,7 +166,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,
|
||||
};
|
||||
|
||||
@@ -204,7 +217,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),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -6,13 +6,14 @@
|
||||
// spell-checker:ignore smackfs
|
||||
//! SMACK (Simplified Mandatory Access Control Kernel) support
|
||||
|
||||
use std::io;
|
||||
use std::fs;
|
||||
use std::io::{self, Read, Write};
|
||||
use std::path::Path;
|
||||
use std::sync::OnceLock;
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::error::{UError, strip_errno};
|
||||
use crate::error::{UError, USimpleError, strip_errno};
|
||||
use crate::translate;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
@@ -50,6 +51,32 @@ pub fn is_smack_enabled() -> bool {
|
||||
*SMACK_ENABLED.get_or_init(|| Path::new("/sys/fs/smackfs").exists())
|
||||
}
|
||||
|
||||
/// Gets the SMACK label for the current process.
|
||||
pub fn get_smack_label_for_self() -> Result<String, SmackError> {
|
||||
if !is_smack_enabled() {
|
||||
return Err(SmackError::SmackNotEnabled);
|
||||
}
|
||||
|
||||
let mut label = String::new();
|
||||
fs::File::open("/proc/self/attr/current")
|
||||
.map_err(SmackError::LabelRetrievalFailure)?
|
||||
.read_to_string(&mut label)
|
||||
.map_err(SmackError::LabelRetrievalFailure)?;
|
||||
|
||||
Ok(label.trim().to_string())
|
||||
}
|
||||
|
||||
/// Sets the SMACK label for the current process.
|
||||
pub fn set_smack_label_for_self(label: &str) -> Result<(), SmackError> {
|
||||
if !is_smack_enabled() {
|
||||
return Err(SmackError::SmackNotEnabled);
|
||||
}
|
||||
|
||||
fs::File::create("/proc/self/attr/current")
|
||||
.and_then(|mut f| f.write_all(label.as_bytes()))
|
||||
.map_err(|e| SmackError::LabelSetFailure(label.to_string(), e))
|
||||
}
|
||||
|
||||
/// Gets the SMACK label for a filesystem path via xattr.
|
||||
pub fn get_smack_label_for_path(path: &Path) -> Result<String, SmackError> {
|
||||
if !is_smack_enabled() {
|
||||
@@ -75,3 +102,20 @@ pub fn set_smack_label_for_path(path: &Path, label: &str) -> Result<(), SmackErr
|
||||
xattr::set(path, "security.SMACK64", label.as_bytes())
|
||||
.map_err(|e| SmackError::LabelSetFailure(label.to_string(), e))
|
||||
}
|
||||
|
||||
/// Sets SMACK label for a new path, calling cleanup on failure.
|
||||
pub fn set_smack_label_and_cleanup(
|
||||
path: impl AsRef<Path>,
|
||||
context: Option<&String>,
|
||||
cleanup: impl FnOnce(&Path) -> io::Result<()>,
|
||||
) -> Result<(), Box<dyn UError>> {
|
||||
let Some(ctx) = context else { return Ok(()) };
|
||||
if !is_smack_enabled() {
|
||||
return Ok(());
|
||||
}
|
||||
let path = path.as_ref();
|
||||
set_smack_label_for_path(path, ctx).map_err(|e| {
|
||||
let _ = cleanup(path);
|
||||
USimpleError::new(1, e.to_string())
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
# Run GNU SMACK tests in QEMU with SMACK-enabled kernel
|
||||
# Usage: run-gnu-tests-smack-ci.sh [GNU_DIR] [OUTPUT_DIR]
|
||||
# spell-checker:ignore rootfs zstd unzstd cpio newc nographic smackfs devtmpfs tmpfs poweroff libm libgcc libpthread libdl librt sysfs rwxat
|
||||
# spell-checker:ignore rootfs zstd unzstd cpio newc nographic smackfs devtmpfs tmpfs poweroff libm libgcc libpthread libdl librt sysfs rwxat setuidgid
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
@@ -17,10 +17,7 @@ mkdir -p "$SMACK_DIR"/{rootfs/{bin,lib64,proc,sys,dev,tmp,etc,gnu},kernel}
|
||||
# Download Arch Linux kernel (has SMACK built-in)
|
||||
if [ ! -f /tmp/arch-vmlinuz ]; then
|
||||
echo "Downloading Arch Linux kernel..."
|
||||
MIRROR="https://geo.mirror.pkgbuild.com/core/os/x86_64"
|
||||
KERNEL_PKG=$(curl -sL "$MIRROR/" | grep -oP 'linux-[0-9][^"]*-x86_64\.pkg\.tar\.zst' | grep -v headers | sort -V | tail -1)
|
||||
[ -z "$KERNEL_PKG" ] && { echo "Error: Could not find kernel package"; exit 1; }
|
||||
curl -sL -o /tmp/arch-kernel.pkg.tar.zst "$MIRROR/$KERNEL_PKG"
|
||||
curl -sL -o /tmp/arch-kernel.pkg.tar.zst "https://archlinux.org/packages/core/x86_64/linux/download/"
|
||||
zstd -d /tmp/arch-kernel.pkg.tar.zst -o /tmp/arch-kernel.pkg.tar 2>/dev/null || unzstd /tmp/arch-kernel.pkg.tar.zst -o /tmp/arch-kernel.pkg.tar
|
||||
VMLINUZ_PATH=$(tar -tf /tmp/arch-kernel.pkg.tar | grep 'vmlinuz$' | head -1)
|
||||
tar -xf /tmp/arch-kernel.pkg.tar -C /tmp "$VMLINUZ_PATH"
|
||||
@@ -65,17 +62,22 @@ ln -sf /proc/mounts /etc/mtab
|
||||
mkdir -p /tmp && mount -t tmpfs tmpfs /tmp
|
||||
chmod 1777 /tmp
|
||||
export PATH="/bin:$PATH" srcdir="/gnu" LD_LIBRARY_PATH="/lib64"
|
||||
cd /gnu/tests
|
||||
sh "$TEST_SCRIPT"
|
||||
if [ -n "$RUN_AS_USER" ]; then
|
||||
# Run in /tmp so non-root user can create temp directories
|
||||
cd /tmp
|
||||
setuidgid "$RUN_AS_USER" sh "/gnu/tests/$TEST_SCRIPT"
|
||||
else
|
||||
cd /gnu/tests
|
||||
sh "$TEST_SCRIPT"
|
||||
fi
|
||||
echo "EXIT:$?"
|
||||
poweroff -f
|
||||
INIT
|
||||
chmod +x "$SMACK_DIR/rootfs/init"
|
||||
|
||||
# Build utilities with SMACK support (only ls has SMACK support for now)
|
||||
# TODO: When other utilities have SMACK support, build: ls id mkdir mknod mkfifo
|
||||
# Build utilities with SMACK support
|
||||
echo "Building utilities with SMACK support..."
|
||||
cargo build --release --manifest-path="$REPO_DIR/Cargo.toml" --package uu_ls --bin ls --features uu_ls/smack
|
||||
cargo build --release --manifest-path="$REPO_DIR/Cargo.toml" --package uu_id --features uu_id/smack --package uu_ls --features uu_ls/smack --package uu_mkdir --features uu_mkdir/smack --package uu_mkfifo --features uu_mkfifo/smack --package uu_mknod --features uu_mknod/smack
|
||||
|
||||
# Find SMACK tests
|
||||
SMACK_TESTS=$(grep -l 'require_smack_' -r "$GNU_DIR/tests/" 2>/dev/null || true)
|
||||
@@ -95,19 +97,30 @@ for TEST_PATH in $SMACK_TESTS; do
|
||||
|
||||
echo "Running: $TEST_REL"
|
||||
|
||||
# Determine if test needs non-root user
|
||||
RUN_AS_USER=""
|
||||
if echo "$TEST_REL" | grep -q "no-root"; then
|
||||
RUN_AS_USER="nobody"
|
||||
fi
|
||||
|
||||
# Create working copy
|
||||
WORK="/tmp/smack-test-$$"
|
||||
rm -rf "$WORK" "$WORK.gz"
|
||||
cp -a "$SMACK_DIR/rootfs" "$WORK"
|
||||
|
||||
# Copy built utilities (only ls has SMACK support for now)
|
||||
# TODO: When other utilities have SMACK support, use:
|
||||
# for U in ls id mkdir mknod mkfifo; do cp "$REPO_DIR/target/release/$U" "$WORK/bin/$U"; done
|
||||
rm -f "$WORK/bin/ls"
|
||||
cp "$REPO_DIR/target/release/ls" "$WORK/bin/ls"
|
||||
# Copy built utilities with SMACK support
|
||||
for U in id ls mkdir mkfifo mknod; do
|
||||
rm -f "$WORK/bin/$U"
|
||||
cp "$REPO_DIR/target/release/$U" "$WORK/bin/$U"
|
||||
done
|
||||
|
||||
# Set test script path
|
||||
# Set test script path and user
|
||||
sed -i "s|\$TEST_SCRIPT|$TEST_REL|g" "$WORK/init"
|
||||
if [ -n "$RUN_AS_USER" ]; then
|
||||
sed -i "s|\$RUN_AS_USER|$RUN_AS_USER|g" "$WORK/init"
|
||||
else
|
||||
sed -i "s|\$RUN_AS_USER||g" "$WORK/init"
|
||||
fi
|
||||
|
||||
# Build initramfs and run
|
||||
(cd "$WORK" && find . | cpio -o -H newc 2>/dev/null | gzip > "$WORK.gz")
|
||||
|
||||
Reference in New Issue
Block a user