kernel: harden the signature check (#1027)
This commit is contained in:
131
userspace/ksud/Cargo.lock
generated
131
userspace/ksud/Cargo.lock
generated
@@ -2,6 +2,15 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97"
|
||||
dependencies = [
|
||||
"gimli",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
@@ -74,12 +83,38 @@ version = "1.0.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61"
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.38",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.67"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
"object",
|
||||
"rustc-demangle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base64ct"
|
||||
version = "1.6.0"
|
||||
@@ -132,6 +167,12 @@ version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
|
||||
|
||||
[[package]]
|
||||
name = "bzip2"
|
||||
version = "0.4.4"
|
||||
@@ -234,7 +275,7 @@ dependencies = [
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.107",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -407,7 +448,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"scratch",
|
||||
"syn",
|
||||
"syn 1.0.107",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -424,7 +465,7 @@ checksum = "81bbeb29798b407ccd82a3324ade1a7286e0d29851475990b612670f6f5124d2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.107",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -435,7 +476,7 @@ checksum = "3418329ca0ad70234b9735dc4ceed10af4df60eff9c8e7b06cb5e520d92c3535"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.107",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -604,6 +645,12 @@ dependencies = [
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.27.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e"
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.1"
|
||||
@@ -700,7 +747,7 @@ dependencies = [
|
||||
"proc-macro-hack",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.107",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -816,6 +863,7 @@ dependencies = [
|
||||
"rust-embed",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha256",
|
||||
"sys-mount",
|
||||
"which",
|
||||
"zip 0.6.4",
|
||||
@@ -979,6 +1027,15 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.30.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03b4680b86d9cfafba8fc491dc9b6df26b68cf40e9e6cd73909194759a63c385"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.17.0"
|
||||
@@ -1053,7 +1110,7 @@ dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.107",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
@@ -1076,9 +1133,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.50"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2"
|
||||
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@@ -1100,9 +1157,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.23"
|
||||
version = "1.0.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
|
||||
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
@@ -1212,7 +1269,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rust-embed-utils",
|
||||
"syn",
|
||||
"syn 1.0.107",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
@@ -1226,6 +1283,12 @@ dependencies = [
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
@@ -1312,6 +1375,19 @@ dependencies = [
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha256"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7895c8ae88588ccead14ff438b939b0c569cd619116f14b4d13fdff7b8333386"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
"hex",
|
||||
"sha2",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.1.0"
|
||||
@@ -1326,7 +1402,7 @@ checksum = "133659a15339456eeeb07572eb02a91c91e9815e9cbc89566944d2c8d3efdbf6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.107",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1352,6 +1428,17 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sys-mount"
|
||||
version = "2.0.2"
|
||||
@@ -1391,7 +1478,7 @@ checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.107",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1421,6 +1508,18 @@ version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd"
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.29.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"backtrace",
|
||||
"bytes",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.37"
|
||||
@@ -1441,7 +1540,7 @@ checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.107",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1527,7 +1626,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.107",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@@ -1549,7 +1648,7 @@ checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.107",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@@ -33,6 +33,7 @@ rust-embed = { version = "6.4.2", features = [
|
||||
] }
|
||||
which = "4.2.2"
|
||||
getopts = "0.2.21"
|
||||
sha256 = "1.4.0"
|
||||
|
||||
[target.'cfg(any(target_os = "android", target_os = "linux"))'.dependencies]
|
||||
sys-mount = { git = "https://github.com/tiann/sys-mount", branch = "loopfix" }
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use anyhow::{ensure, Result};
|
||||
use std::io::{Read, Seek, SeekFrom};
|
||||
|
||||
pub fn get_apk_signature(apk: &str) -> Result<(u32, u32)> {
|
||||
pub fn get_apk_signature(apk: &str) -> Result<(u32, String)> {
|
||||
let mut buffer = [0u8; 0x10];
|
||||
let mut size4 = [0u8; 4];
|
||||
let mut size8 = [0u8; 8];
|
||||
@@ -49,9 +49,11 @@ pub fn get_apk_signature(apk: &str) -> Result<(u32, u32)> {
|
||||
|
||||
ensure!(size_of_block == size8, "not a signed apk");
|
||||
|
||||
let mut v2_signing: Option<(u32, String)> = None;
|
||||
let mut v3_signing: Option<(u32, String)> = None;
|
||||
loop {
|
||||
let mut id = [0u8; 4];
|
||||
let offset = 4u32;
|
||||
let mut offset = 4u32;
|
||||
|
||||
f.read_exact(&mut size8)?; // sequence length
|
||||
if size8 == size_of_block {
|
||||
@@ -61,36 +63,10 @@ pub fn get_apk_signature(apk: &str) -> Result<(u32, u32)> {
|
||||
f.read_exact(&mut id)?; // id
|
||||
|
||||
let id = u32::from_le_bytes(id);
|
||||
if (id ^ 0xdead_beef_u32) == 0xafa4_39f5_u32 || (id ^ 0xdead_beef_u32) == 0x2efe_d62f_u32 {
|
||||
f.read_exact(&mut size4)?; // signer-sequence length
|
||||
f.read_exact(&mut size4)?; // signer length
|
||||
f.read_exact(&mut size4)?; // signed data length
|
||||
// offset += 0x4 * 3;
|
||||
|
||||
f.read_exact(&mut size4)?; // digests-sequcence length
|
||||
let pos = u32::from_le_bytes(size4);
|
||||
f.seek(SeekFrom::Current(i64::from(pos)))?;
|
||||
// offset += 0x4 + pos;
|
||||
|
||||
f.read_exact(&mut size4)?; // certificates length
|
||||
f.read_exact(&mut size4)?; // certificate length
|
||||
// offset += 0x4 * 2;
|
||||
|
||||
let mut hash = 1i32;
|
||||
let mut c = [0u8; 1];
|
||||
|
||||
let j = u32::from_le_bytes(size4);
|
||||
for _ in 0..j {
|
||||
f.read_exact(&mut c)?;
|
||||
hash = hash.wrapping_mul(31).wrapping_add(i32::from(c[0] as i8));
|
||||
}
|
||||
|
||||
// offset += j;
|
||||
|
||||
let out_size = j;
|
||||
let out_hash = (hash as u32) ^ 0x1413_1211_u32;
|
||||
|
||||
return Ok((out_size, out_hash));
|
||||
if id == 0x7109_871a_u32 {
|
||||
v2_signing = Some(calc_cert_sha256(&mut f, &mut size4, &mut offset)?);
|
||||
} else if id == 0xf053_68c0_u32 {
|
||||
v3_signing = Some(calc_cert_sha256(&mut f, &mut size4, &mut offset)?);
|
||||
}
|
||||
|
||||
f.seek(SeekFrom::Current(
|
||||
@@ -98,5 +74,47 @@ pub fn get_apk_signature(apk: &str) -> Result<(u32, u32)> {
|
||||
))?;
|
||||
}
|
||||
|
||||
Err(anyhow::anyhow!("Unknown error"))
|
||||
match (v2_signing, v3_signing) {
|
||||
(None, Some(s)) => Ok(s),
|
||||
(Some(s), None) => Ok(s),
|
||||
(Some(s1), Some(s2)) => {
|
||||
if s1 == s2 {
|
||||
Ok(s1)
|
||||
} else {
|
||||
Err(anyhow::anyhow!(
|
||||
"Inconsisent signature, v2: {}, v3: {}!",
|
||||
s1.1,
|
||||
s2.1
|
||||
))
|
||||
}
|
||||
}
|
||||
_ => Err(anyhow::anyhow!("Unknown signature!")),
|
||||
}
|
||||
}
|
||||
|
||||
fn calc_cert_sha256(
|
||||
f: &mut std::fs::File,
|
||||
size4: &mut [u8; 4],
|
||||
offset: &mut u32,
|
||||
) -> Result<(u32, String)> {
|
||||
f.read_exact(size4)?; // signer-sequence length
|
||||
f.read_exact(size4)?; // signer length
|
||||
f.read_exact(size4)?; // signed data length
|
||||
*offset += 0x4 * 3;
|
||||
|
||||
f.read_exact(size4)?; // digests-sequence length
|
||||
let pos = u32::from_le_bytes(*size4); // skip digests
|
||||
f.seek(SeekFrom::Current(i64::from(pos)))?;
|
||||
*offset += 0x4 + pos;
|
||||
|
||||
f.read_exact(size4)?; // certificates length
|
||||
f.read_exact(size4)?; // certificate length
|
||||
*offset += 0x4 * 2;
|
||||
|
||||
let cert_len = u32::from_le_bytes(*size4);
|
||||
let mut cert: Vec<u8> = vec![0; cert_len as usize];
|
||||
f.read_exact(&mut cert)?;
|
||||
*offset += cert_len;
|
||||
|
||||
Ok((cert_len, sha256::digest(&cert)))
|
||||
}
|
||||
|
||||
@@ -228,7 +228,7 @@ pub fn run() -> Result<()> {
|
||||
Debug::SetManager { apk } => debug::set_manager(&apk),
|
||||
Debug::GetSign { apk } => {
|
||||
let sign = apk_sign::get_apk_signature(&apk)?;
|
||||
println!("size: {:#x}, hash: {:#x}", sign.0, sign.1);
|
||||
println!("size: {:#x}, hash: {}", sign.0, sign.1);
|
||||
Ok(())
|
||||
}
|
||||
Debug::Version => {
|
||||
|
||||
@@ -15,24 +15,25 @@ fn read_u32(path: &PathBuf) -> Result<u32> {
|
||||
Ok(content)
|
||||
}
|
||||
|
||||
fn set_kernel_param(size: u32, hash: u32) -> Result<()> {
|
||||
fn set_kernel_param(size: u32, hash: String) -> Result<()> {
|
||||
let kernel_param_path = Path::new(KERNEL_PARAM_PATH).join("parameters");
|
||||
|
||||
let expeced_size_path = kernel_param_path.join("ksu_expected_size");
|
||||
let expeced_hash_path = kernel_param_path.join("ksu_expected_hash");
|
||||
|
||||
println!(
|
||||
"before size: {:#x} hash: {:#x}",
|
||||
"before size: {:#x} hash: {}",
|
||||
read_u32(&expeced_size_path)?,
|
||||
read_u32(&expeced_hash_path)?
|
||||
std::fs::read_to_string(&expeced_hash_path)?
|
||||
);
|
||||
|
||||
std::fs::write(&expeced_size_path, size.to_string())?;
|
||||
std::fs::write(&expeced_hash_path, hash.to_string())?;
|
||||
std::fs::write(&expeced_hash_path, hash)?;
|
||||
|
||||
println!(
|
||||
"after size: {:#x} hash: {:#x}",
|
||||
"after size: {:#x} hash: {}",
|
||||
read_u32(&expeced_size_path)?,
|
||||
read_u32(&expeced_hash_path)?
|
||||
std::fs::read_to_string(&expeced_hash_path)?
|
||||
);
|
||||
|
||||
Ok(())
|
||||
|
||||
Reference in New Issue
Block a user