Check correct KernelSU version

This commit is contained in:
Nullptr
2023-02-20 16:28:15 +08:00
parent b99d042002
commit 5365ab1f12
10 changed files with 108 additions and 35 deletions

View File

@@ -33,6 +33,9 @@ val moduleId by extra("zygisksu")
val moduleName by extra("Zygisk on KernelSU") val moduleName by extra("Zygisk on KernelSU")
val verName by extra("v4-0.4.1") val verName by extra("v4-0.4.1")
val verCode by extra(gitCommitCount) val verCode by extra(gitCommitCount)
val minKsuVersion by extra(10626)
val maxKsuVersion by extra(100000)
val minMagiskVersion by extra(25000)
val androidMinSdkVersion by extra(29) val androidMinSdkVersion by extra(29)
val androidTargetSdkVersion by extra(33) val androidTargetSdkVersion by extra(33)

View File

@@ -11,6 +11,9 @@ val moduleId: String by rootProject.extra
val moduleName: String by rootProject.extra val moduleName: String by rootProject.extra
val verCode: Int by rootProject.extra val verCode: Int by rootProject.extra
val verName: String by rootProject.extra val verName: String by rootProject.extra
val minKsuVersion: Int by rootProject.extra
val maxKsuVersion: Int by rootProject.extra
val minMagiskVersion: Int by rootProject.extra
android.buildFeatures { android.buildFeatures {
androidResources = false androidResources = false
@@ -49,7 +52,10 @@ androidComponents.onVariants { variant ->
from("$projectDir/src") { from("$projectDir/src") {
include("customize.sh", "daemon.sh") include("customize.sh", "daemon.sh")
val tokens = mapOf( val tokens = mapOf(
"DEBUG" to if (buildTypeLowered == "debug") "true" else "false" "DEBUG" to if (buildTypeLowered == "debug") "true" else "false",
"MIN_KSU_VERSION" to "$minKsuVersion",
"MAX_KSU_VERSION" to "$maxKsuVersion",
"MIN_MAGISK_VERSION" to "$minMagiskVersion",
) )
filter<ReplaceTokens>("tokens" to tokens) filter<ReplaceTokens>("tokens" to tokens)
filter<FixCrLfFilter>("eol" to FixCrLfFilter.CrLf.newInstance("lf")) filter<FixCrLfFilter>("eol" to FixCrLfFilter.CrLf.newInstance("lf"))

View File

@@ -2,19 +2,28 @@
SKIPUNZIP=1 SKIPUNZIP=1
DEBUG=@DEBUG@ DEBUG=@DEBUG@
MIN_KSU_VERSION=@MIN_KSU_VERSION@
MAX_KSU_VERSION=@MAX_KSU_VERSION@
MIN_MAGISK_VERSION=@MIN_MAGISK_VERSION@
if [ "$BOOTMODE" ] && [ "$KSU" ]; then if [ "$BOOTMODE" ] && [ "$KSU" ]; then
ui_print "- Installing from KernelSU app" ui_print "- Installing from KernelSU app"
ui_print "- KernelSU version: $KSU_KERNEL_VER_CODE (kernel) + $KSU_VER_CODE (ksud)" ui_print "- KernelSU version: $KSU_KERNEL_VER_CODE (kernel) + $KSU_VER_CODE (ksud)"
if [ "$KSU_KERNEL_VER_CODE" ] && [ "$KSU_KERNEL_VER_CODE" -lt 10575 ]; then if [ "$KSU_KERNEL_VER_CODE" ] && [ "$KSU_KERNEL_VER_CODE" -lt "$MIN_KSU_VERSION" ]; then
ui_print "*********************************************************" ui_print "*********************************************************"
ui_print "! KernelSU version is too old!" ui_print "! KernelSU version is too old!"
ui_print "! Please update KernelSU to latest version" ui_print "! Please update KernelSU to latest version"
abort "*********************************************************" abort "*********************************************************"
elif [ "$KSU_KERNEL_VER_CODE" -ge "$MAX_KSU_VERSION" ]; then
ui_print "*********************************************************"
ui_print "! KernelSU version abnormal!"
ui_print "! Please integrate KernelSU into your kernel"
ui_print " as submodule instead of copying the source code"
abort "*********************************************************"
fi fi
elif [ "$BOOTMODE" ] && [ "$MAGISK_VER_CODE" ]; then elif [ "$BOOTMODE" ] && [ "$MAGISK_VER_CODE" ]; then
ui_print "- Installing from Magisk app" ui_print "- Installing from Magisk app"
if [ "$MAGISK_VER_CODE" -lt 25000 ]; then if [ "$MAGISK_VER_CODE" -lt "$MIN_MAGISK_VERSION" ]; then
ui_print "*********************************************************" ui_print "*********************************************************"
ui_print "! Magisk version is too old!" ui_print "! Magisk version is too old!"
ui_print "! Please update Magisk to latest version" ui_print "! Please update Magisk to latest version"

View File

@@ -10,11 +10,13 @@ android_logger = "0.12.0"
anyhow = { version = "1.0.68", features = ["backtrace"] } anyhow = { version = "1.0.68", features = ["backtrace"] }
clap = { version = "4.1.4", features = ["derive"] } clap = { version = "4.1.4", features = ["derive"] }
const_format = "0.2.5" const_format = "0.2.5"
konst = "0.3.4"
lazy_static = "1.4.0" lazy_static = "1.4.0"
log = "0.4.17" log = "0.4.17"
memfd = "0.6.2" memfd = "0.6.2"
nix = "0.26.2" nix = "0.26.2"
num_enum = "0.5.9" num_enum = "0.5.9"
once_cell = "1.17.1"
passfd = "0.1.5" passfd = "0.1.5"
rand = "0.8.5" rand = "0.8.5"

View File

@@ -5,6 +5,9 @@ plugins {
val verName: String by rootProject.extra val verName: String by rootProject.extra
val verCode: Int by rootProject.extra val verCode: Int by rootProject.extra
val minKsuVersion: Int by rootProject.extra
val maxKsuVersion: Int by rootProject.extra
val minMagiskVersion: Int by rootProject.extra
android.buildFeatures { android.buildFeatures {
androidResources = false androidResources = false
@@ -23,5 +26,8 @@ cargo {
spec.environment("ANDROID_NDK_HOME", android.ndkDirectory.path) spec.environment("ANDROID_NDK_HOME", android.ndkDirectory.path)
spec.environment("VERSION_CODE", verCode) spec.environment("VERSION_CODE", verCode)
spec.environment("VERSION_NAME", verName) spec.environment("VERSION_NAME", verName)
spec.environment("MIN_KSU_VERSION", minKsuVersion)
spec.environment("MAX_KSU_VERSION", maxKsuVersion)
spec.environment("MIN_MAGISK_VERSION", minMagiskVersion)
} }
} }

View File

@@ -1,10 +1,15 @@
use const_format::concatcp; use const_format::concatcp;
use konst::primitive::parse_i32;
use konst::unwrap_ctx;
use log::LevelFilter; use log::LevelFilter;
use num_enum::TryFromPrimitive; use num_enum::TryFromPrimitive;
pub const VERSION_NAME: &str = env!("VERSION_NAME"); pub const VERSION_NAME: &str = env!("VERSION_NAME");
pub const VERSION_CODE: &str = env!("VERSION_CODE"); pub const VERSION_CODE: &str = env!("VERSION_CODE");
pub const VERSION_FULL: &str = concatcp!(VERSION_NAME, " (", VERSION_CODE, ")"); pub const VERSION_FULL: &str = concatcp!(VERSION_NAME, " (", VERSION_CODE, ")");
pub const MIN_KSU_VERSION: i32 = unwrap_ctx!(parse_i32(env!("MIN_KSU_VERSION")));
pub const MAX_KSU_VERSION: i32 = unwrap_ctx!(parse_i32(env!("MAX_KSU_VERSION")));
pub const MIN_MAGISK_VERSION: i32 = unwrap_ctx!(parse_i32(env!("MIN_MAGISK_VERSION")));
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
pub const MAX_LOG_LEVEL: LevelFilter = LevelFilter::Trace; pub const MAX_LOG_LEVEL: LevelFilter = LevelFilter::Trace;

View File

@@ -8,6 +8,7 @@ mod utils;
mod watchdog; mod watchdog;
mod zygiskd; mod zygiskd;
use anyhow::Result;
use clap::{Subcommand, Parser}; use clap::{Subcommand, Parser};
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
@@ -36,19 +37,23 @@ fn init_android_logger(tag: &str) {
); );
} }
fn start() -> Result<()> {
root_impl::setup()?;
let cli = Args::parse();
match cli.command {
Commands::Watchdog => watchdog::entry()?,
Commands::Daemon => zygiskd::entry()?,
Commands::Companion { fd } => companion::entry(fd)?,
};
Ok(())
}
fn main() { fn main() {
let process = std::env::args().next().unwrap(); let process = std::env::args().next().unwrap();
let nice_name = process.split('/').last().unwrap(); let nice_name = process.split('/').last().unwrap();
init_android_logger(nice_name); init_android_logger(nice_name);
let cli = Args::parse(); if let Err(e) = start() {
let result = match cli.command {
Commands::Watchdog => watchdog::entry(),
Commands::Daemon => zygiskd::entry(),
Commands::Companion { fd } => companion::entry(fd),
};
if let Err(e) = &result {
log::error!("Crashed: {}\n{}", e, e.backtrace()); log::error!("Crashed: {}\n{}", e, e.backtrace());
} }
} }

View File

@@ -1,15 +1,22 @@
use anyhow::{bail, Result};
use nix::libc::prctl; use nix::libc::prctl;
use crate::constants::{MIN_KSU_VERSION, MAX_KSU_VERSION};
const KERNEL_SU_OPTION: i32 = 0xdeadbeefu32 as i32; const KERNEL_SU_OPTION: i32 = 0xdeadbeefu32 as i32;
const CMD_GET_VERSION: u64 = 2; const CMD_GET_VERSION: usize = 2;
const CMD_GET_ALLOW_LIST: u64 = 5; const CMD_GET_ALLOW_LIST: usize = 5;
const CMD_GET_DENY_LIST: u64 = 6; const CMD_GET_DENY_LIST: usize = 6;
pub fn is_kernel_su() -> bool { pub fn is_kernel_su() -> Result<bool> {
let mut version = 0; let mut version = 0;
unsafe { prctl(KERNEL_SU_OPTION, CMD_GET_VERSION, &mut version as *mut i32) }; unsafe { prctl(KERNEL_SU_OPTION, CMD_GET_VERSION, &mut version as *mut i32) };
version > 0 return match version {
0 => Ok(false),
MIN_KSU_VERSION..=MAX_KSU_VERSION => Ok(true),
1..=MIN_KSU_VERSION => bail!("KernelSU version too old: {}", version),
_ => bail!("KernelSU version abnormal: {}", version)
}
} }
pub fn uid_on_allowlist(uid: i32) -> bool { pub fn uid_on_allowlist(uid: i32) -> bool {

View File

@@ -1,13 +1,30 @@
use anyhow::{bail, Result};
use std::process::{Command, Stdio};
use crate::constants::MIN_MAGISK_VERSION;
pub fn is_magisk() -> Result<bool> {
pub fn is_magisk() -> bool { let version: Option<i32> = Command::new("magisk")
todo!("is_magisk") .arg("--version")
.stdout(Stdio::piped())
.spawn().ok()
.and_then(|child| child.wait_with_output().ok())
.and_then(|output| String::from_utf8(output.stdout).ok())
.and_then(|output| output.parse().ok());
if let Some(version) = version {
if version < MIN_MAGISK_VERSION {
bail!("Magisk version too old: {}", version);
}
return Ok(true);
}
Ok(false)
} }
pub fn uid_on_allowlist(uid: i32) -> bool { pub fn uid_on_allowlist(uid: i32) -> bool {
todo!("uid_on_allowlist") // TODO: uid_on_allowlist
return false;
} }
pub fn uid_on_denylist(uid: i32) -> bool { pub fn uid_on_denylist(uid: i32) -> bool {
todo!("uid_on_denylist") // TODO: uid_on_denylist
return false;
} }

View File

@@ -1,24 +1,37 @@
mod kernelsu; mod kernelsu;
mod magisk; mod magisk;
pub fn uid_on_allowlist(uid: i32) -> bool { use once_cell::sync::OnceCell;
if kernelsu::is_kernel_su() { use anyhow::{bail, Result};
kernelsu::uid_on_allowlist(uid)
} else if magisk::is_magisk() { enum RootImpl {
magisk::uid_on_allowlist(uid) KernelSU,
Magisk,
}
static ROOT_IMPL: OnceCell<RootImpl> = OnceCell::new();
pub fn setup() -> Result<()> {
if kernelsu::is_kernel_su()? {
let _ = ROOT_IMPL.set(RootImpl::KernelSU);
} else if magisk::is_magisk()? {
let _ = ROOT_IMPL.set(RootImpl::Magisk);
} else { } else {
log::warn!("Unknown root implementation"); bail!("Unknown root implementation");
false }
Ok(())
}
pub fn uid_on_allowlist(uid: i32) -> bool {
match ROOT_IMPL.get().unwrap() {
RootImpl::KernelSU => kernelsu::uid_on_allowlist(uid),
RootImpl::Magisk => magisk::uid_on_allowlist(uid),
} }
} }
pub fn uid_on_denylist(uid: i32) -> bool { pub fn uid_on_denylist(uid: i32) -> bool {
if kernelsu::is_kernel_su() { match ROOT_IMPL.get().unwrap() {
kernelsu::uid_on_denylist(uid) RootImpl::KernelSU => kernelsu::uid_on_denylist(uid),
} else if magisk::is_magisk() { RootImpl::Magisk => magisk::uid_on_denylist(uid),
magisk::uid_on_denylist(uid)
} else {
log::warn!("Unknown root implementation");
false
} }
} }