You've already forked Magisk
mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-09-06 06:36:58 +00:00
Move magiskpolicy cli to argh
This commit is contained in:
@@ -119,8 +119,6 @@ LOCAL_STATIC_LIBRARIES := \
|
|||||||
libpolicy \
|
libpolicy \
|
||||||
libpolicy-rs
|
libpolicy-rs
|
||||||
|
|
||||||
LOCAL_SRC_FILES := sepolicy/main.cpp
|
|
||||||
|
|
||||||
include $(BUILD_EXECUTABLE)
|
include $(BUILD_EXECUTABLE)
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|||||||
Generated
+1
@@ -527,6 +527,7 @@ dependencies = [
|
|||||||
name = "magiskpolicy"
|
name = "magiskpolicy"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"argh",
|
||||||
"base",
|
"base",
|
||||||
"cxx",
|
"cxx",
|
||||||
"cxx-gen",
|
"cxx-gen",
|
||||||
|
|||||||
@@ -12,5 +12,5 @@ cxx-gen = { workspace = true }
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
base = { path = "../base" }
|
base = { path = "../base" }
|
||||||
magiskpolicy = { path = "../sepolicy" }
|
magiskpolicy = { path = "../sepolicy", default-features = false }
|
||||||
cxx = { workspace = true }
|
cxx = { workspace = true }
|
||||||
|
|||||||
@@ -10,6 +10,11 @@ path = "lib.rs"
|
|||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
cxx-gen = { workspace = true }
|
cxx-gen = { workspace = true }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["main"]
|
||||||
|
main = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
base = { path = "../base" }
|
base = { path = "../base" }
|
||||||
cxx = { workspace = true }
|
cxx = { workspace = true }
|
||||||
|
argh = { workspace = true }
|
||||||
|
|||||||
@@ -0,0 +1,133 @@
|
|||||||
|
use crate::ffi::SePolicy;
|
||||||
|
use argh::FromArgs;
|
||||||
|
use base::{
|
||||||
|
EarlyExitExt, LoggedResult, Utf8CStr, cmdline_logging, cstr, libc::umask, log_err, map_args,
|
||||||
|
};
|
||||||
|
use std::{ffi::c_char, io::Cursor};
|
||||||
|
|
||||||
|
#[derive(FromArgs)]
|
||||||
|
struct Cli {
|
||||||
|
#[argh(switch)]
|
||||||
|
live: bool,
|
||||||
|
|
||||||
|
#[argh(switch)]
|
||||||
|
magisk: bool,
|
||||||
|
|
||||||
|
#[argh(switch)]
|
||||||
|
compile_split: bool,
|
||||||
|
|
||||||
|
#[argh(switch)]
|
||||||
|
load_split: bool,
|
||||||
|
|
||||||
|
#[argh(switch)]
|
||||||
|
print_rules: bool,
|
||||||
|
|
||||||
|
#[argh(option)]
|
||||||
|
load: Option<String>,
|
||||||
|
|
||||||
|
#[argh(option)]
|
||||||
|
save: Option<String>,
|
||||||
|
|
||||||
|
#[argh(option)]
|
||||||
|
apply: Vec<String>,
|
||||||
|
|
||||||
|
#[argh(positional)]
|
||||||
|
polices: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_usage(cmd: &str) {
|
||||||
|
eprintln!(
|
||||||
|
r#"MagiskPolicy - SELinux Policy Patch Tool
|
||||||
|
|
||||||
|
Usage: {} [--options...] [policy statements...]
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--help show help message for policy statements
|
||||||
|
--load FILE load monolithic sepolicy from FILE
|
||||||
|
--load-split load from precompiled sepolicy or compile
|
||||||
|
split cil policies
|
||||||
|
--compile-split compile split cil policies
|
||||||
|
--save FILE dump monolithic sepolicy to FILE
|
||||||
|
--live immediately load sepolicy into the kernel
|
||||||
|
--magisk apply built-in Magisk sepolicy rules
|
||||||
|
--apply FILE apply rules from FILE, read and parsed
|
||||||
|
line by line as policy statements
|
||||||
|
(multiple --apply are allowed)
|
||||||
|
--print-rules print all rules in the loaded sepolicy
|
||||||
|
|
||||||
|
If neither --load, --load-split, nor --compile-split is specified,
|
||||||
|
it will load from current live policies (/sys/fs/selinux/policy)
|
||||||
|
"#,
|
||||||
|
cmd
|
||||||
|
);
|
||||||
|
|
||||||
|
SePolicy::print_statement_help();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unsafe(no_mangle)]
|
||||||
|
pub unsafe extern "C" fn main(
|
||||||
|
argc: i32,
|
||||||
|
argv: *const *const c_char,
|
||||||
|
_envp: *const *const c_char,
|
||||||
|
) -> i32 {
|
||||||
|
cmdline_logging();
|
||||||
|
unsafe {
|
||||||
|
umask(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
let res: LoggedResult<()> = try {
|
||||||
|
let cmds = map_args(argc, argv)?;
|
||||||
|
if argc < 2 {
|
||||||
|
print_usage(cmds.first().unwrap_or(&"magiskpolicy"));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
let mut cli = Cli::from_args(&[cmds[0]], &cmds[1..]).on_early_exit(|| print_usage(cmds[0]));
|
||||||
|
|
||||||
|
let mut sepol = match (&mut cli.load, cli.load_split, cli.compile_split) {
|
||||||
|
(Some(file), false, false) => SePolicy::from_file(Utf8CStr::from_string(file)),
|
||||||
|
(None, true, false) => SePolicy::from_split(),
|
||||||
|
(None, false, true) => SePolicy::compile_split(),
|
||||||
|
(None, false, false) => SePolicy::from_file(cstr!("/sys/fs/selinux/policy")),
|
||||||
|
_ => Err(log_err!("Multiple load source supplied"))?,
|
||||||
|
};
|
||||||
|
if sepol._impl.is_null() {
|
||||||
|
Err(log_err!("Cannot load policy"))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if cli.print_rules {
|
||||||
|
if cli.magisk
|
||||||
|
|| !cli.apply.is_empty()
|
||||||
|
|| !cli.polices.is_empty()
|
||||||
|
|| cli.live
|
||||||
|
|| cli.save.is_some()
|
||||||
|
{
|
||||||
|
Err(log_err!("Cannot print rules with other options"))?;
|
||||||
|
}
|
||||||
|
sepol.print_rules();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if cli.magisk {
|
||||||
|
sepol.magisk_rules();
|
||||||
|
}
|
||||||
|
|
||||||
|
for file in &mut cli.apply {
|
||||||
|
sepol.load_rule_file(Utf8CStr::from_string(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
for statement in &cli.polices {
|
||||||
|
sepol.load_rules_from_reader(&mut Cursor::new(statement));
|
||||||
|
}
|
||||||
|
|
||||||
|
if cli.live && !sepol.to_file(cstr!("/sys/fs/selinux/load")) {
|
||||||
|
Err(log_err!("Cannot apply policy"))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(file) = &mut cli.save {
|
||||||
|
if !sepol.to_file(Utf8CStr::from_string(file)) {
|
||||||
|
Err(log_err!("Cannot dump policy to {}", file))?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if res.is_ok() { 0 } else { 1 }
|
||||||
|
}
|
||||||
@@ -10,6 +10,8 @@ use std::io::{BufRead, BufReader, Cursor};
|
|||||||
|
|
||||||
use crate::ffi::SePolicy;
|
use crate::ffi::SePolicy;
|
||||||
|
|
||||||
|
#[cfg(feature = "main")]
|
||||||
|
mod cli;
|
||||||
mod rules;
|
mod rules;
|
||||||
mod statement;
|
mod statement;
|
||||||
|
|
||||||
@@ -88,8 +90,6 @@ pub mod ffi {
|
|||||||
fn load_rules(self: &mut SePolicy, rules: &CxxString);
|
fn load_rules(self: &mut SePolicy, rules: &CxxString);
|
||||||
#[Self = SePolicy]
|
#[Self = SePolicy]
|
||||||
fn xperm_to_string(perm: &Xperm) -> String;
|
fn xperm_to_string(perm: &Xperm) -> String;
|
||||||
#[Self = SePolicy]
|
|
||||||
fn print_statement_help();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,130 +0,0 @@
|
|||||||
#include <base.hpp>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "include/sepolicy.hpp"
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
[[noreturn]] static void usage(char *arg0) {
|
|
||||||
fprintf(stderr,
|
|
||||||
R"EOF(MagiskPolicy - SELinux Policy Patch Tool
|
|
||||||
|
|
||||||
Usage: %s [--options...] [policy statements...]
|
|
||||||
|
|
||||||
Options:
|
|
||||||
--help show help message for policy statements
|
|
||||||
--load FILE load monolithic sepolicy from FILE
|
|
||||||
--load-split load from precompiled sepolicy or compile
|
|
||||||
split cil policies
|
|
||||||
--compile-split compile split cil policies
|
|
||||||
--save FILE dump monolithic sepolicy to FILE
|
|
||||||
--live immediately load sepolicy into the kernel
|
|
||||||
--magisk apply built-in Magisk sepolicy rules
|
|
||||||
--apply FILE apply rules from FILE, read and parsed
|
|
||||||
line by line as policy statements
|
|
||||||
(multiple --apply are allowed)
|
|
||||||
--print-rules print all rules in the loaded sepolicy
|
|
||||||
|
|
||||||
If neither --load, --load-split, nor --compile-split is specified,
|
|
||||||
it will load from current live policies (/sys/fs/selinux/policy)
|
|
||||||
|
|
||||||
)EOF", arg0);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
|
||||||
cmdline_logging();
|
|
||||||
const char *out_file = nullptr;
|
|
||||||
vector<string_view> rule_files;
|
|
||||||
SePolicy sepol;
|
|
||||||
bool magisk = false;
|
|
||||||
bool live = false;
|
|
||||||
bool print = false;
|
|
||||||
|
|
||||||
if (argc < 2) usage(argv[0]);
|
|
||||||
int i = 1;
|
|
||||||
for (; i < argc; ++i) {
|
|
||||||
// Parse options
|
|
||||||
if (argv[i][0] == '-' && argv[i][1] == '-') {
|
|
||||||
auto option = argv[i] + 2;
|
|
||||||
if (option == "live"sv)
|
|
||||||
live = true;
|
|
||||||
else if (option == "magisk"sv)
|
|
||||||
magisk = true;
|
|
||||||
else if (option == "print-rules"sv)
|
|
||||||
print = true;
|
|
||||||
else if (option == "load"sv) {
|
|
||||||
if (argv[i + 1] == nullptr)
|
|
||||||
usage(argv[0]);
|
|
||||||
sepol = SePolicy::from_file(argv[i + 1]);
|
|
||||||
if (!sepol.impl) {
|
|
||||||
fprintf(stderr, "Cannot load policy from %s\n", argv[i + 1]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
++i;
|
|
||||||
} else if (option == "load-split"sv) {
|
|
||||||
sepol = SePolicy::from_split();
|
|
||||||
if (!sepol.impl) {
|
|
||||||
fprintf(stderr, "Cannot load split cil\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
} else if (option == "compile-split"sv) {
|
|
||||||
sepol = SePolicy::compile_split();
|
|
||||||
if (!sepol.impl) {
|
|
||||||
fprintf(stderr, "Cannot compile split cil\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
} else if (option == "save"sv) {
|
|
||||||
if (argv[i + 1] == nullptr)
|
|
||||||
usage(argv[0]);
|
|
||||||
out_file = argv[i + 1];
|
|
||||||
++i;
|
|
||||||
} else if (option == "apply"sv) {
|
|
||||||
if (argv[i + 1] == nullptr)
|
|
||||||
usage(argv[0]);
|
|
||||||
rule_files.emplace_back(argv[i + 1]);
|
|
||||||
++i;
|
|
||||||
} else if (option == "help"sv) {
|
|
||||||
SePolicy::print_statement_help();
|
|
||||||
exit(0);
|
|
||||||
} else {
|
|
||||||
usage(argv[0]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use current policy if nothing is loaded
|
|
||||||
if (!sepol.impl && !(sepol = SePolicy::from_file(SELINUX_POLICY)).impl) {
|
|
||||||
fprintf(stderr, "Cannot load policy from " SELINUX_POLICY "\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (print) {
|
|
||||||
sepol.print_rules();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (magisk)
|
|
||||||
sepol.magisk_rules();
|
|
||||||
|
|
||||||
if (!rule_files.empty())
|
|
||||||
for (const auto &rule_file : rule_files)
|
|
||||||
sepol.load_rule_file(rule_file.data());
|
|
||||||
|
|
||||||
for (; i < argc; ++i)
|
|
||||||
sepol.parse_statement(argv[i]);
|
|
||||||
|
|
||||||
if (live && !sepol.to_file(SELINUX_LOAD)) {
|
|
||||||
fprintf(stderr, "Cannot apply policy\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (out_file && !sepol.to_file(out_file)) {
|
|
||||||
fprintf(stderr, "Cannot dump policy to %s\n", out_file);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user