ksud: replace some utils with rust libraries (#142)

This commit is contained in:
skbeh 2023-01-30 12:57:25 +08:00 committed by GitHub
parent bd6b0d3d12
commit 7785d2a3f8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 525 additions and 178 deletions

View File

@ -29,18 +29,49 @@ dependencies = [
"memchr",
]
[[package]]
name = "android-properties"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04"
[[package]]
name = "anyhow"
version = "1.0.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61"
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "base64ct"
version = "1.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf"
[[package]]
name = "bindgen"
version = "0.59.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bd2a9a458e8f4304c52c43ebb0cfbd520289f8379a52e329a38afda99bf8eb8"
dependencies = [
"bitflags",
"cexpr",
"clang-sys",
"lazy_static",
"lazycell",
"peeking_take_while",
"proc-macro2",
"quote",
"regex",
"rustc-hash",
"shlex",
]
[[package]]
name = "bitflags"
version = "1.3.2"
@ -64,9 +95,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "bzip2"
version = "0.4.3"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6afcd980b5f3a45017c57e57a2fcccbb351cc43a356ce117ef760ef8052b89b0"
checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8"
dependencies = [
"bzip2-sys",
"libc",
@ -85,13 +116,22 @@ dependencies = [
[[package]]
name = "cc"
version = "1.0.78"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d"
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
dependencies = [
"jobserver",
]
[[package]]
name = "cexpr"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
dependencies = [
"nom",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
@ -108,10 +148,21 @@ dependencies = [
]
[[package]]
name = "clap"
version = "4.0.32"
name = "clang-sys"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7db700bc935f9e43e88d00b0850dae18a63773cfbec6d8e070fccf7fef89a39"
checksum = "fa2e27ae6ab525c3d369ded447057bca5438d86dc3a68f6faafb8269ba82ebf3"
dependencies = [
"glob",
"libc",
"libloading",
]
[[package]]
name = "clap"
version = "4.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f13b9c79b5d1dd500d20ef541215a6423c75829ef43117e1b4d17fd8af0b5d76"
dependencies = [
"bitflags",
"clap_derive",
@ -124,9 +175,9 @@ dependencies = [
[[package]]
name = "clap_derive"
version = "4.0.21"
version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014"
checksum = "684a277d672e91966334af371f1a7b5833f9aa00b07c84e92fbce95e00208ce8"
dependencies = [
"heck",
"proc-macro-error",
@ -137,9 +188,9 @@ dependencies = [
[[package]]
name = "clap_lex"
version = "0.3.0"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8"
checksum = "783fe232adfca04f90f56201b26d79682d4cd2625e0bc7290b95123afe558ade"
dependencies = [
"os_str_bytes",
]
@ -188,6 +239,64 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "crossbeam"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2801af0d36612ae591caa9568261fddce32ce6e08a7275ea334a06a4ad021a2c"
dependencies = [
"cfg-if",
"crossbeam-channel",
"crossbeam-deque",
"crossbeam-epoch",
"crossbeam-queue",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc"
dependencies = [
"cfg-if",
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a"
dependencies = [
"autocfg",
"cfg-if",
"crossbeam-utils",
"memoffset",
"scopeguard",
]
[[package]]
name = "crossbeam-queue"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.14"
@ -218,6 +327,12 @@ dependencies = [
"subtle",
]
[[package]]
name = "either"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
[[package]]
name = "encoding"
version = "0.2.33"
@ -316,6 +431,17 @@ dependencies = [
"libc",
]
[[package]]
name = "extattr"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b59f8a77817ff1b795adafc535941bdf664184f5f95e0b6d1d77dd6d12815dc"
dependencies = [
"bitflags",
"errno",
"libc",
]
[[package]]
name = "flate2"
version = "1.0.25"
@ -347,6 +473,12 @@ dependencies = [
"wasi 0.11.0+wasi-snapshot-preview1",
]
[[package]]
name = "glob"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]]
name = "heck"
version = "0.4.0"
@ -388,9 +520,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]]
name = "io-lifetimes"
version = "1.0.3"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c"
checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e"
dependencies = [
"libc",
"windows-sys",
@ -408,6 +540,15 @@ dependencies = [
"windows-sys",
]
[[package]]
name = "is_executable"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa9acdc6d67b75e626ad644734e8bc6df893d9cd2a834129065d3dd6158ea9c8"
dependencies = [
"winapi",
]
[[package]]
name = "itoa"
version = "1.0.5"
@ -434,17 +575,31 @@ dependencies = [
"libc",
]
[[package]]
name = "jwalk"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2735847566356cd2179a2a38264839308f7079fa96e6bd5a42d740460e003c56"
dependencies = [
"crossbeam",
"rayon",
]
[[package]]
name = "ksud"
version = "0.1.0"
dependencies = [
"android-properties",
"anyhow",
"clap",
"const_format",
"encoding",
"env_logger",
"extattr",
"humansize",
"is_executable",
"java-properties",
"jwalk",
"libc",
"log",
"regex",
@ -452,6 +607,7 @@ dependencies = [
"serde",
"serde_json",
"subprocess",
"sys-mount",
"zip 0.6.3",
"zip-extensions",
]
@ -462,12 +618,28 @@ version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "lazycell"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
version = "0.2.139"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
[[package]]
name = "libloading"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
dependencies = [
"cfg-if",
"winapi",
]
[[package]]
name = "libm"
version = "0.2.6"
@ -489,12 +661,38 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "loopdev"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5bfa0855b04611e38acaff718542e9e809cddfc16535d39f9d9c694ab19f7388"
dependencies = [
"bindgen",
"errno",
"libc",
]
[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "memoffset"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4"
dependencies = [
"autocfg",
]
[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "miniz_oxide"
version = "0.6.2"
@ -504,6 +702,26 @@ dependencies = [
"adler",
]
[[package]]
name = "nom"
version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
dependencies = [
"memchr",
"minimal-lexical",
]
[[package]]
name = "num_cpus"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
dependencies = [
"hermit-abi",
"libc",
]
[[package]]
name = "once_cell"
version = "1.17.0"
@ -545,6 +763,18 @@ dependencies = [
"sha2",
]
[[package]]
name = "peeking_take_while"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
[[package]]
name = "pin-project-lite"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
[[package]]
name = "pkg-config"
version = "0.3.26"
@ -583,9 +813,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.49"
version = "1.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5"
checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2"
dependencies = [
"unicode-ident",
]
@ -630,10 +860,32 @@ dependencies = [
]
[[package]]
name = "regex"
version = "1.7.0"
name = "rayon"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a"
checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7"
dependencies = [
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "356a0625f1954f730c0201cdab48611198dc6ce21f4acff55089b5a78e6e835b"
dependencies = [
"crossbeam-channel",
"crossbeam-deque",
"crossbeam-utils",
"num_cpus",
]
[[package]]
name = "regex"
version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733"
dependencies = [
"aho-corasick",
"memchr",
@ -656,10 +908,16 @@ dependencies = [
]
[[package]]
name = "rustix"
version = "0.36.6"
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4feacf7db682c6c329c4ede12649cd36ecab0f3be5b7d74e6a20304725db4549"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustix"
version = "0.36.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4fdebc4b395b7fbb9ab11e462e20ed9051e7b16e42d24042c776eca0ac81b03"
dependencies = [
"bitflags",
"errno",
@ -675,6 +933,12 @@ version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde"
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "serde"
version = "1.0.152"
@ -714,6 +978,23 @@ dependencies = [
"digest",
]
[[package]]
name = "shlex"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
[[package]]
name = "smart-default"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "133659a15339456eeeb07572eb02a91c91e9815e9cbc89566944d2c8d3efdbf6"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "strsim"
version = "0.10.0"
@ -748,10 +1029,24 @@ dependencies = [
]
[[package]]
name = "termcolor"
version = "1.1.3"
name = "sys-mount"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
checksum = "793d38aa916d55e979587ea7cf551106f5f091e548a91e89ee4f0698bc9cf289"
dependencies = [
"bitflags",
"libc",
"loopdev",
"smart-default",
"thiserror",
"tracing",
]
[[package]]
name = "termcolor"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
dependencies = [
"winapi-util",
]
@ -814,6 +1109,38 @@ dependencies = [
"time-core",
]
[[package]]
name = "tracing"
version = "0.1.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
dependencies = [
"cfg-if",
"pin-project-lite",
"tracing-attributes",
"tracing-core",
]
[[package]]
name = "tracing-attributes"
version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tracing-core"
version = "0.1.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a"
dependencies = [
"once_cell",
]
[[package]]
name = "typenum"
version = "1.16.0"
@ -898,45 +1225,45 @@ dependencies = [
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.0"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e"
checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608"
[[package]]
name = "windows_aarch64_msvc"
version = "0.42.0"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4"
checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7"
[[package]]
name = "windows_i686_gnu"
version = "0.42.0"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7"
checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640"
[[package]]
name = "windows_i686_msvc"
version = "0.42.0"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246"
checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605"
[[package]]
name = "windows_x86_64_gnu"
version = "0.42.0"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed"
checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.0"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028"
checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463"
[[package]]
name = "windows_x86_64_msvc"
version = "0.42.0"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
[[package]]
name = "zip"
@ -1002,10 +1329,11 @@ dependencies = [
[[package]]
name = "zstd-sys"
version = "2.0.4+zstd.1.5.2"
version = "2.0.5+zstd.1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fa202f2ef00074143e219d15b62ffc317d17cc33909feac471c044087cad7b0"
checksum = "edc50ffce891ad571e9f9afe5039c4837bede781ac4bb13052ed7ae695518596"
dependencies = [
"cc",
"libc",
"pkg-config",
]

View File

@ -23,8 +23,13 @@ encoding = "0.2.33"
retry = "2.0.0"
humansize = "2.0.0"
libc = "0.2"
sys-mount = "2.0.1"
android-properties = { version = "0.2.2", features = ["bionic-deprecated"] }
extattr = "1.0.0"
jwalk = "0.8.1"
is_executable = "1.0.1"
[profile.release]
strip = true
opt-level = "z"
lto = true
lto = true

View File

@ -39,8 +39,8 @@ fn set_kernel_param(size: u32, hash: u32) -> Result<()> {
}
fn get_apk_path(package_name: &str) -> Result<String> {
let cmd = format!("pm path {}", package_name);
let output = Command::new("sh").arg("-c").arg(cmd).output()?;
// `cmd package path` is not available below Android 9
let output = Command::new("pm").args(["path", package_name]).output()?;
// package:/data/app/<xxxx>/base.apk
let output = String::from_utf8_lossy(&output.stdout);
@ -54,7 +54,7 @@ pub fn set_manager(pkg: &str) -> Result<()> {
"CONFIG_KSU_DEBUG is not enabled"
);
let path = get_apk_path(pkg).with_context(|| format!("{} not exist!", pkg))?;
let path = get_apk_path(pkg).with_context(|| format!("{pkg} does not exist!"))?;
let sign = get_apk_signature(path.as_str())?;
set_kernel_param(sign.0, sign.1)?;
Ok(())

View File

@ -5,11 +5,11 @@ use crate::{
utils::{ensure_clean_dir, mount_image},
};
use anyhow::{bail, Result};
use subprocess::Exec;
use sys_mount::{FilesystemType, Mount, MountFlags};
fn mount_partition(partition: &str, lowerdir: &mut Vec<String>) {
if lowerdir.is_empty() {
println!("partition: {} lowerdir is empty", partition);
println!("partition: {partition} lowerdir is empty");
return;
}
@ -19,22 +19,19 @@ fn mount_partition(partition: &str, lowerdir: &mut Vec<String>) {
return;
}
// add /partition as the lowerest dir
let lowest_dir = format!("/{}", partition);
let lowest_dir = format!("/{partition}");
lowerdir.push(lowest_dir.clone());
let lowerdir = lowerdir.join(":");
println!("partition: {} lowerdir: {}", partition, lowerdir);
println!("partition: {partition} lowerdir: {lowerdir}");
let mount_args = format!(
"mount -t overlay overlay -o ro,lowerdir={} {}",
lowerdir, lowest_dir
);
if let Ok(result) = Exec::shell(mount_args).join() {
if !result.success() {
println!("mount partition: {} overlay failed", partition);
}
} else {
println!("mount partition: {} overlay failed", partition);
if let Err(err) = Mount::builder()
.fstype(FilesystemType::from("overlay"))
.flags(MountFlags::RDONLY)
.data(&format!("lowerdir={lowerdir}"))
.mount("overlay", lowest_dir)
{
println!("mount partition: {partition} overlay failed: {err}");
}
}
@ -136,7 +133,7 @@ pub fn on_post_data_fs() -> Result<()> {
}
// module mounted, exec modules post-fs-data scripts
if !crate::utils::is_safe_mode().unwrap_or(false) {
if !crate::utils::is_safe_mode() {
// todo: Add timeout
let _ = crate::module::exec_post_fs_data();
let _ = crate::module::load_system_prop();
@ -149,7 +146,7 @@ pub fn on_post_data_fs() -> Result<()> {
pub fn on_services() -> Result<()> {
// exec modules service.sh scripts
if !crate::utils::is_safe_mode().unwrap_or(false) {
if !crate::utils::is_safe_mode() {
let _ = crate::module::exec_services();
} else {
println!("safe mode, skip module service scripts");

View File

@ -1,3 +1,4 @@
#!/system/bin/sh
############################################
# KernelSU installer script
# Credit to Magisk!!!
@ -89,14 +90,15 @@ setup_flashable() {
}
ensure_bb() {
:
}
recovery_actions() {
:
}
recovery_cleanup() {
:
}
#######################

View File

@ -1,7 +1,7 @@
#![allow(dead_code, unused_mut, unused_variables, unused_imports)]
use anyhow::{ensure, Result};
use std::os::unix::process::CommandExt;
use anyhow::{Result, ensure};
const KERNEL_SU_OPTION: u32 = 0xDEADBEEF;
@ -31,8 +31,7 @@ pub fn grant_root() -> Result<()> {
}
ensure!(result == KERNEL_SU_OPTION, "grant root failed");
std::process::Command::new("/system/bin/sh").exec();
Ok(())
return Err(std::process::Command::new("sh").exec().into());
}
#[cfg(not(target_os = "android"))]
@ -56,11 +55,7 @@ pub fn get_version() -> i32 {
fn report_event(event: u64) {
#[cfg(target_os = "android")]
unsafe {
libc::prctl(
KERNEL_SU_OPTION as i32,
CMD_REPORT_EVENT,
event,
);
libc::prctl(KERNEL_SU_OPTION as i32, CMD_REPORT_EVENT, event);
}
}
@ -70,4 +65,4 @@ pub fn report_post_fs_data() {
pub fn report_boot_complete() {
report_event(EVENT_BOOT_COMPLETED);
}
}

View File

@ -1,20 +1,19 @@
use crate::{defs, restorecon};
use crate::{restorecon::setsyscon, utils::*};
use const_format::concatcp;
use java_properties::PropertiesIter;
use log::{info, warn};
use std::{
collections::HashMap,
fs::{create_dir_all, remove_dir_all, File, OpenOptions},
io::{Cursor, Write},
io::{Cursor, Read, Write},
os::unix::{prelude::PermissionsExt, process::CommandExt},
path::{Path, PathBuf},
process::{Command, Stdio},
str::FromStr,
};
use subprocess::Exec;
use zip_extensions::*;
use crate::{defs, restorecon};
use crate::{restorecon::setsyscon, utils::*};
use zip_extensions::zip_extract_file_to_memory;
use anyhow::{bail, ensure, Context, Result};
@ -24,15 +23,15 @@ const INSTALL_MODULE_SCRIPT: &str =
fn exec_install_script(module_file: &str) -> Result<()> {
let realpath = std::fs::canonicalize(module_file)
.with_context(|| format!("realpath: {} failed", module_file))?;
.with_context(|| format!("realpath: {module_file} failed"))?;
let result = Command::new("/system/bin/sh")
let result = Command::new("sh")
.args(["-c", INSTALL_MODULE_SCRIPT])
.env("OUTFD", "1")
.env("ZIPFILE", realpath)
.stderr(Stdio::null())
.status()?;
ensure!(result.success(), "install module script failed!");
ensure!(result.success(), "Failed to install module script");
Ok(())
}
@ -41,13 +40,8 @@ fn exec_install_script(module_file: &str) -> Result<()> {
// if someone(such as the module) install a module before the boot_completed
// then it may cause some problems, just forbid it
fn ensure_boot_completed() -> Result<()> {
// ensure getprop sys.boot_completed = 1
let output = Command::new("getprop")
.arg("sys.boot_completed")
.stdout(Stdio::piped())
.output()?;
let output = String::from_utf8_lossy(&output.stdout);
if output.trim() != "1" {
// ensure getprop sys.boot_completed == 1
if getprop("sys.boot_completed").as_deref() != Some("1") {
bail!("Android is Booting!");
}
Ok(())
@ -103,7 +97,7 @@ fn check_image(img: &str) -> Result<()> {
.stdout(Stdio::null())
.stderr(Stdio::null())
.status()
.with_context(|| format!("Failed exec e2fsck {}", img))?;
.with_context(|| format!("Failed to exec e2fsck {img}"))?;
let code = result.code();
// 0 or 1 is ok
// 0: no error
@ -111,7 +105,7 @@ fn check_image(img: &str) -> Result<()> {
// https://man7.org/linux/man-pages/man8/e2fsck.8.html
ensure!(
code == Some(0) || code == Some(1),
"check image e2fsck exec failed: {}",
"Failed to check image, e2fsck exit code: {}",
code.unwrap_or(-1)
);
Ok(())
@ -130,12 +124,12 @@ fn grow_image_size(img: &str, extra_size: u64) -> Result<()> {
);
let target_size = target_size / 1024 + 1;
let result = Exec::shell(format!("resize2fs {} {}K", img, target_size))
.stdout(subprocess::NullFile)
.stderr(subprocess::Redirection::Merge)
.join()
.with_context(|| format!("Failed to resize2fs {}", img))?;
ensure!(result.success(), "resize2fs exec failed.");
let result = Command::new("resize2fs")
.args([img, &format!("{target_size}K")])
.stdout(Stdio::null())
.status()
.with_context(|| format!("Failed to exec resize2fs {img}"))?;
ensure!(result.success(), "Failed to resize2fs: {}", result);
Ok(())
}
@ -148,20 +142,33 @@ fn switch_cgroup(grp: &str, pid: u32) {
let fp = OpenOptions::new().append(true).open(path);
if let Ok(mut fp) = fp {
let _ = writeln!(fp, "{}", pid);
let _ = writeln!(fp, "{pid}");
}
}
fn switch_cgroups() -> Result<()> {
fn switch_cgroups() {
let pid = std::process::id();
switch_cgroup("/acct", pid);
switch_cgroup("/dev/cg2_bpf", pid);
switch_cgroup("/sys/fs/cgroup", pid);
if getprop("ro.config.per_app_memcg")? != "false" {
if getprop("ro.config.per_app_memcg")
.filter(|prop| prop == "false")
.is_none()
{
switch_cgroup("/dev/memcg/apps", pid);
}
}
Ok(())
fn is_executable(path: &Path) -> bool {
let mut buffer: [u8; 2] = [0; 2];
is_executable::is_executable(path)
&& File::open(path).unwrap().read_exact(&mut buffer).is_ok()
&& (
buffer == [0x23, 0x21] // shebang #!
|| buffer == [0x7f, 0x45]
// ELF magic number 0x7F 'E'
)
}
/// execute every modules' post-fs-data.sh
@ -182,21 +189,30 @@ pub fn exec_post_fs_data() -> Result<()> {
}
println!("exec {} post-fs-data.sh", path.display());
// pre_exec is unsafe!
let mut command_new;
let mut command;
if is_executable(&post_fs_data) {
command_new = Command::new("sh");
command = command_new.arg(&post_fs_data);
} else {
command_new = Command::new(&post_fs_data);
command = &mut command_new;
};
command = command
.process_group(0)
.current_dir(path)
.env("KSU", "true");
unsafe {
Command::new("/system/bin/sh")
.arg(&post_fs_data)
.process_group(0)
.pre_exec(|| {
// ignore the error?
let _ = switch_cgroups();
Ok(())
})
.current_dir(path)
.env("KSU", "true")
.status()
.with_context(|| format!("Failed to exec {}", post_fs_data.display()))?;
command = command.pre_exec(|| {
// ignore the error?
switch_cgroups();
Ok(())
});
}
command
.status()
.with_context(|| format!("Failed to exec {}", post_fs_data.display()))?;
}
Ok(())
@ -220,21 +236,29 @@ pub fn exec_services() -> Result<()> {
}
println!("exec {} service.sh", path.display());
// pre_exec is unsafe!
let mut command_new;
let mut command;
if is_executable(&service) {
command_new = Command::new("sh");
command = command_new.arg(&service);
} else {
command_new = Command::new(&service);
command = &mut command_new;
};
command = command
.process_group(0)
.current_dir(path)
.env("KSU", "true");
unsafe {
Command::new("/system/bin/sh")
.arg(&service)
.process_group(0)
.pre_exec(|| {
// ignore the error?
let _ = switch_cgroups();
Ok(())
})
.current_dir(path)
.env("KSU", "true")
.spawn() // don't wait
.with_context(|| format!("Failed to exec {}", service.display()))?;
command = command.pre_exec(|| {
// ignore the error?
switch_cgroups();
Ok(())
});
}
command
.spawn() // don't wait
.with_context(|| format!("Failed to exec {}", service.display()))?;
}
Ok(())
@ -271,7 +295,7 @@ pub fn load_system_prop() -> Result<()> {
}
println!("load {} system.prop", path.display());
// resetprop --file system.prop
// resetprop -n --file system.prop
Command::new(RESETPROP_PATH)
.arg("-n")
.arg("--file")
@ -335,7 +359,6 @@ pub fn install_module(zip: String) -> Result<()> {
let default_reserve_size = 64 * 1024 * 1024;
let zip_uncompressed_size = get_zip_uncompressed_size(&zip)?;
let grow_size = default_reserve_size + zip_uncompressed_size;
let grow_size_per_m = grow_size / 1024 / 1024 + 1;
println!("- Preparing image");
println!(
@ -346,21 +369,21 @@ pub fn install_module(zip: String) -> Result<()> {
if !modules_img_exist && !modules_update_img_exist {
// if no modules and modules_update, it is brand new installation, we should create a new img
// create a tmp module img and mount it to modules_update
let result = Exec::shell(format!(
"dd if=/dev/zero of={} bs=1M count={}",
tmp_module_img, grow_size_per_m
))
.stdout(subprocess::NullFile)
.stderr(subprocess::Redirection::Merge)
.join()?;
ensure!(result.success(), "create ext4 image failed!");
File::create(tmp_module_img)
.context("Failed to create ext4 image file")?
.set_len(grow_size)
.context("Failed to extend ext4 image")?;
// format the img to ext4 filesystem
let result = Exec::shell(format!("mkfs.ext4 {}", tmp_module_img))
.stdout(subprocess::NullFile)
.stderr(subprocess::Redirection::Merge)
.join()?;
ensure!(result.success(), "format ext4 image failed!");
let result = Command::new("mkfs.ext4")
.arg(tmp_module_img)
.stdout(Stdio::null())
.output()?;
ensure!(
result.status.success(),
"Failed to format ext4 image: {}",
String::from_utf8(result.stderr).unwrap()
);
check_image(tmp_module_img)?;
} else if modules_update_img_exist {

View File

@ -1,16 +1,13 @@
use anyhow::ensure;
use anyhow::Ok;
use anyhow::Result;
use subprocess::Exec;
use anyhow::{Context, Ok, Result};
use extattr::{setxattr, Flags as XattrFlags};
use jwalk::{Parallelism::Serial, WalkDir};
const SYSTEM_CON: &str = "u:object_r:system_file:s0";
const _ADB_CON: &str = "u:object_r:adb_data_file:s0";
pub fn setcon(path: &str, con: &str) -> Result<()> {
// todo use libselinux directly
let cmd = format!("chcon {} {}", con, path);
let result = Exec::shell(cmd).join()?;
ensure!(result.success(), "chcon for: {} failed.", path);
setxattr(path, "security.selinux", con, XattrFlags::empty())
.with_context(|| format!("Failed to change SELinux context for {path}"))?;
Ok(())
}
@ -19,9 +16,17 @@ pub fn setsyscon(path: &str) -> Result<()> {
}
pub fn restore_syscon(dir: &str) -> Result<()> {
// todo use libselinux directly
let cmd = format!("chcon -R {} {}", SYSTEM_CON, dir);
let result = Exec::shell(cmd).join()?;
ensure!(result.success(), "chcon for: {} failed.", dir);
for dir_entry in WalkDir::new(dir).parallelism(Serial) {
if let Some(path) = dir_entry.ok().map(|dir_entry| dir_entry.path()) {
setxattr(&path, "security.selinux", SYSTEM_CON, XattrFlags::empty()).with_context(
|| {
format!(
"Failed to change SELinux context for {}",
path.to_str().unwrap()
)
},
)?;
}
}
Ok(())
}

View File

@ -1,18 +1,14 @@
use std::{
path::Path,
process::{Command, Stdio},
};
use std::path::Path;
use anyhow::{ensure, Result};
use anyhow::{ensure, Context, Result};
use retry::delay::NoDelay;
use subprocess::Exec;
use sys_mount::{unmount, FilesystemType, Mount, UnmountFlags};
fn do_mount_image(src: &str, target: &str) -> Result<()> {
let result = Exec::shell(format!("mount -t ext4 {} {}", src, target))
.stdout(subprocess::NullFile)
.stderr(subprocess::Redirection::Merge)
.join()?;
ensure!(result.success(), "do mount: {} -> {} failed.", src, target);
Mount::builder()
.fstype(FilesystemType::from("ext4"))
.mount(src, target)
.with_context(|| format!("Failed to do mount: {src} -> {target}"))?;
Ok(())
}
@ -20,16 +16,12 @@ pub fn mount_image(src: &str, target: &str) -> Result<()> {
// umount target first.
let _ = umount_dir(target);
let result = retry::retry(NoDelay.take(3), || do_mount_image(src, target));
ensure!(result.is_ok(), "mount: {} -> {} failed.", src, target);
ensure!(result.is_ok(), "Failed to mount {} -> {}", src, target);
Ok(())
}
pub fn umount_dir(src: &str) -> Result<()> {
let result = Exec::shell(format!("umount {}", src))
.stdout(subprocess::NullFile)
.stderr(subprocess::Redirection::Merge)
.join()?;
ensure!(result.success(), "umount: {} failed", src);
unmount(src, UnmountFlags::empty()).with_context(|| format!("Failed to umount {src}"))?;
Ok(())
}
@ -41,17 +33,17 @@ pub fn ensure_clean_dir(dir: &str) -> Result<()> {
Ok(std::fs::create_dir_all(path)?)
}
pub fn getprop(prop: &str) -> Result<String> {
let output = Command::new("getprop")
.arg(prop)
.stdout(Stdio::piped())
.output()?;
let output = String::from_utf8_lossy(&output.stdout);
Ok(output.trim().to_string())
pub fn getprop(prop: &str) -> Option<String> {
android_properties::getprop(prop).value()
}
pub fn is_safe_mode() -> Result<bool> {
Ok(getprop("persist.sys.safemode")?.eq("1") || getprop("ro.sys.safemode")?.eq("1"))
pub fn is_safe_mode() -> bool {
getprop("persist.sys.safemode")
.filter(|prop| prop == "1")
.is_some()
|| getprop("ro.sys.safemode")
.filter(|prop| prop == "1")
.is_some()
}
pub fn get_zip_uncompressed_size(zip_path: &str) -> Result<u64> {