Revert "userspace: implement OSS ksuinit"

This reverts commit edb99a2c1a.
This commit is contained in:
Rifat Azad
2025-08-10 13:48:18 +06:00
parent e0c461322b
commit 1de68a8ed2
18 changed files with 40 additions and 720 deletions

View File

@@ -8,16 +8,6 @@ updates:
actions:
patterns:
- "*"
- package-ecosystem: cargo
directory: userspace/ksuinit
schedule:
interval: daily
allow:
- dependency-type: "all"
groups:
crates:
patterns:
- "*"
- package-ecosystem: cargo
directory: userspace/ksud_magic
schedule:

View File

@@ -69,21 +69,8 @@ jobs:
with:
os: ${{ matrix.os }}
build-ksuinit:
needs: [check-cache, build-susfsd]
if: needs.check-cache.outputs.cache-hit != 'true'
strategy:
matrix:
include:
- target: aarch64-linux-android
os: ubuntu-latest
uses: ./.github/workflows/ksuinit.yml
with:
target: ${{ matrix.target }}
os: ${{ matrix.os }}
build-ksud:
needs: [check-cache, build-ksuinit]
needs: [check-cache, build-susfsd]
if: needs.check-cache.outputs.cache-hit != 'true'
strategy:
matrix:
@@ -110,13 +97,6 @@ jobs:
name: susfsd-linux-android
path: cached-artifacts/susfsd
- name: Download ksuinit artifacts
uses: actions/download-artifact@v4
with:
pattern: ksuinit-aarch64-linux-android
path: cached-artifacts/ksuinit
merge-multiple: true
- name: Download ksud_overlayfs artifacts
uses: actions/download-artifact@v4
with:

View File

@@ -71,21 +71,8 @@ jobs:
with:
os: ${{ matrix.os }}
build-ksuinit:
needs: [check-cache, build-susfsd]
if: needs.check-cache.outputs.cache-hit != 'true'
strategy:
matrix:
include:
- target: aarch64-linux-android
os: ubuntu-latest
uses: ./.github/workflows/ksuinit.yml
with:
target: ${{ matrix.target }}
os: ${{ matrix.os }}
build-ksud:
needs: [check-cache, build-ksuinit]
needs: [check-cache, build-susfsd]
if: needs.check-cache.outputs.cache-hit != 'true'
strategy:
matrix:
@@ -112,13 +99,6 @@ jobs:
name: susfsd-linux-android
path: cached-artifacts/susfsd
- name: Download ksuinit artifacts
uses: actions/download-artifact@v4
with:
pattern: ksuinit-aarch64-linux-android
path: cached-artifacts/ksuinit
merge-multiple: true
- name: Download ksud_overlayfs artifacts
uses: actions/download-artifact@v4
with:

View File

@@ -33,20 +33,8 @@ jobs:
with:
os: ${{ matrix.os }}
build-ksuinit:
needs: build-susfsd
strategy:
matrix:
include:
- target: aarch64-linux-android
os: ubuntu-latest
uses: ./.github/workflows/ksuinit.yml
with:
target: ${{ matrix.target }}
os: ${{ matrix.os }}
build-ksud:
needs: build-ksuinit
needs: build-susfsd
strategy:
matrix:
include:

View File

@@ -6,7 +6,6 @@ on:
- next
paths:
- '.github/workflows/clippy.yml'
- 'userspace/ksuinit/**'
- 'userspace/ksud_magic/**'
- 'userspace/ksud_overlayfs/**'
pull_request:
@@ -14,7 +13,6 @@ on:
- next
paths:
- '.github/workflows/clippy.yml'
- 'userspace/ksuinit/**'
- 'userspace/ksud_magic/**'
- 'userspace/ksud_overlayfs/**'
@@ -34,11 +32,6 @@ jobs:
- name: Setup Cross
run: RUSTFLAGS="" cargo install cross
- name: Cache ksuinit
uses: Swatinem/rust-cache@v2
with:
workspaces: userspace/ksuinit
- name: Cache ksud_overlayfs
uses: Swatinem/rust-cache@v2
with:
@@ -51,8 +44,6 @@ jobs:
- name: Run Clippy
run: |
cross clippy --manifest-path userspace/ksuinit/Cargo.toml --target aarch64-linux-android --release
cross clippy --manifest-path userspace/ksud_magic/Cargo.toml --target aarch64-linux-android --release
cross clippy --manifest-path userspace/ksud_overlayfs/Cargo.toml --target aarch64-linux-android --release

View File

@@ -39,17 +39,16 @@ jobs:
run: |
cp susfsd-linux-android/arm64-v8a/susfsd ./userspace/ksud_overlayfs/bin/aarch64/
cp susfsd-linux-android/arm64-v8a/susfsd ./userspace/ksud_magic/bin/aarch64/
- name: Import ksuinit Binaries
run: |
cp ksuinit-aarch64-linux-android/aarch64-linux-android/release/ksuinit ./userspace/ksud_overlayfs/bin/aarch64/
cp ksuinit-aarch64-linux-android/aarch64-linux-android/release/ksuinit ./userspace/ksud_magic/bin/aarch64/
cp susfsd-linux-android/armeabi-v7a/susfsd ./userspace/ksud_overlayfs/bin/arm/
cp susfsd-linux-android/armeabi-v7a/susfsd ./userspace/ksud_magic/bin/arm/
cp susfsd-linux-android/x86_64/susfsd ./userspace/ksud_overlayfs/bin/x86_64/
cp susfsd-linux-android/x86_64/susfsd ./userspace/ksud_magic/bin/x86_64/
- name: Setup Rust
run: |
rustup update stable
rustup target add x86_64-linux-android
rustup target add aarch64-linux-android
rustup target add x86_64-apple-darwin
rustup target add aarch64-apple-darwin
- name: Cache ksud_overlayfs
uses: Swatinem/rust-cache@v2

View File

@@ -1,57 +0,0 @@
name: Build ksuinit
on:
workflow_call:
inputs:
target:
required: true
type: string
os:
required: false
type: string
default: ubuntu-latest
pack_lkm:
required: false
type: boolean
default: true
use_cache:
required: false
type: boolean
default: true
jobs:
build:
runs-on: ${{ inputs.os }}
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Rust
run: |
rustup update stable
rustup target add aarch64-linux-android
- name: Set Rust & Android linker
run: |
TOOLCHAIN="$ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64"
if [ ! -d "$TOOLCHAIN" ]; then
echo "Android NDK not found at $ANDROID_NDK"
exit 1
fi
echo "CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=$TOOLCHAIN/bin/aarch64-linux-android21-clang" >> $GITHUB_ENV
- name: Cache ksuinit
uses: Swatinem/rust-cache@v2
with:
workspaces: userspace/ksuinit
cache-targets: false
- name: Build ksuinit
run: |
cargo build --target ${{ inputs.target }} --release --manifest-path ./userspace/ksuinit/Cargo.toml
- name: Upload ksuinit artifact
uses: actions/upload-artifact@v4
with:
name: ksuinit-${{ inputs.target }}
path: userspace/ksuinit/target/**/release/ksuinit

View File

@@ -6,7 +6,6 @@ on:
- 'next'
paths:
- '.github/workflows/rustfmt.yml'
- 'userspace/ksuinit/**'
- 'userspace/ksud_magic/**'
- 'userspace/ksud_overlayfs/**'
pull_request:
@@ -14,7 +13,6 @@ on:
- 'next'
paths:
- '.github/workflows/rustfmt.yml'
- 'userspace/ksuinit/**'
- 'userspace/ksud_magic/**'
- 'userspace/ksud_overlayfs/**'
@@ -31,11 +29,6 @@ jobs:
with:
components: rustfmt
- uses: LoliGothick/rustfmt-check@master
with:
token: ${{ github.token }}
working-directory: userspace/ksuinit
- uses: LoliGothick/rustfmt-check@master
with:
token: ${{ github.token }}

View File

@@ -6,14 +6,6 @@
# For LKM make sure you have imported the androidX-X.X_kernelsu.ko drivers to userspace/ksud_*/bin/aarch64 directory.
export CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER="aarch64-linux-android21-clang"
cross build --target aarch64-linux-android --release --manifest-path ./userspace/ksuinit/Cargo.toml
cp userspace/ksuinit/target/aarch64-linux-android/release/ksuinit userspace/ksud_magic/bin/aarch64/ksuinit
cp userspace/ksuinit/target/aarch64-linux-android/release/ksuinit userspace/ksud_overlayfs/bin/aarch64/ksuinit
cross build --target aarch64-linux-android --release --manifest-path ./userspace/ksud_magic/Cargo.toml
cp userspace/ksud_magic/target/aarch64-linux-android/release/ksud manager/app/src/main/jniLibs/arm64-v8a/libksud_magic.so

View File

@@ -81,6 +81,35 @@ import com.rifsxd.ksunext.ui.util.rootAvailable
@Destination<RootGraph>
@Composable
fun InstallScreen(navigator: DestinationsNavigator) {
var showLkmWarning by rememberSaveable { mutableStateOf(true) }
if (showLkmWarning) {
AlertDialog(
onDismissRequest = {
showLkmWarning = false
navigator.popBackStack()
},
title = { Text(
text = stringResource(R.string.warning),
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.SemiBold
) },
text = { Text(stringResource(R.string.lkm_warning_message)) },
confirmButton = {
TextButton(onClick = { showLkmWarning = false }) {
Text(stringResource(R.string.proceed))
}
},
dismissButton = {
TextButton(onClick = {
showLkmWarning = false
navigator.popBackStack()
}) {
Text(stringResource(R.string.cancel))
}
}
)
}
var installMethod by remember {
mutableStateOf<InstallMethod?>(null)

View File

@@ -1,3 +1,2 @@
**/*.ko
susfsd
ksuinit
susfsd

View File

@@ -1,3 +1,2 @@
**/*.ko
susfsd
ksuinit
susfsd

View File

@@ -1 +0,0 @@
target

View File

@@ -1,227 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "anyhow"
version = "1.0.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1"
[[package]]
name = "bitflags"
version = "2.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
[[package]]
name = "errno"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
dependencies = [
"libc",
"windows-sys",
]
[[package]]
name = "goblin"
version = "0.8.0"
source = "git+https://github.com/tiann/goblin#138d40d4c36471cfbb611eb493f0378ee9fc63f5"
dependencies = [
"log",
"plain",
"scroll",
]
[[package]]
name = "kernlog"
version = "0.3.1"
source = "git+https://github.com/tiann/kernlog.rs#ff0b1bd6d5261eae0fa297cec6951fe8d982151a"
dependencies = [
"libc",
"log",
]
[[package]]
name = "ksuinit"
version = "0.1.0"
dependencies = [
"anyhow",
"goblin",
"kernlog",
"log",
"obfstr",
"rustix",
"scroll",
"syscalls",
]
[[package]]
name = "libc"
version = "0.2.153"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]]
name = "linux-raw-sys"
version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
[[package]]
name = "log"
version = "0.4.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
[[package]]
name = "obfstr"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3ba2979b86cc910a6d13837ef97fef0c6b68fa807c5e014d622449db18351dc"
[[package]]
name = "plain"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
[[package]]
name = "proc-macro2"
version = "1.0.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rustix"
version = "0.38.34"
source = "git+https://github.com/Kernel-SU/rustix.git?rev=4a53fbc#4a53fbc7cb7a07cabe87125cc21dbc27db316259"
dependencies = [
"bitflags",
"errno",
"libc",
"linux-raw-sys",
"windows-sys",
]
[[package]]
name = "scroll"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ab8598aa408498679922eff7fa985c25d58a90771bd6be794434c5277eab1a6"
dependencies = [
"scroll_derive",
]
[[package]]
name = "scroll_derive"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f81c2fde025af7e69b1d1420531c8a8811ca898919db177141a85313b1cb932"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "syn"
version = "2.0.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "syscalls"
version = "0.6.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56b389b38331a454883a34fd19f25cbd1510b3510ff7aa28cb8d6de85d888439"
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
[[package]]
name = "windows_i686_gnu"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
[[package]]
name = "windows_i686_msvc"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"

View File

@@ -1,34 +0,0 @@
[package]
name = "ksuinit"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
# for elf parsing
goblin = { git = "https://github.com/tiann/goblin" }
scroll = "0.12"
anyhow = "1"
# If you want to use the following dependencies, please use aarch64-unknown-linux-musl & x86_64-unknown-linux-musl to compile statically
# rustix = { git = "https://github.com/bytecodealliance/rustix", rev = "7b44528", features = ["mount", "fs", "runtime", "system", "process"] }
rustix = { git = "https://github.com/Kernel-SU/rustix.git", rev = "4a53fbc", features = ["mount", "fs", "runtime", "system", "process"] }
syscalls = { version = "0.6", default-features = false, features = [
"aarch64",
"x86_64",
] }
# for kmsg logging
log = "0.4"
kernlog = { git = "https://github.com/tiann/kernlog.rs" }
obfstr = "0.4"
[profile.release]
strip = true
lto = true
opt-level = "z"
panic = "abort"

View File

@@ -1,185 +0,0 @@
use std::io::{ErrorKind, Write};
use crate::loader::load_module;
use anyhow::Result;
use rustix::fs::{chmodat, symlink, unlink, AtFlags, Mode};
use rustix::{
fd::AsFd,
fs::{access, makedev, mkdir, mknodat, Access, FileType, CWD},
mount::{
fsconfig_create, fsmount, fsopen, move_mount, unmount, FsMountFlags, FsOpenFlags,
MountAttrFlags, MoveMountFlags, UnmountFlags,
},
};
use obfstr::obfstr as s;
struct AutoUmount {
mountpoints: Vec<String>,
}
impl Drop for AutoUmount {
fn drop(&mut self) {
for mountpoint in self.mountpoints.iter().rev() {
if let Err(e) = unmount(mountpoint.as_str(), UnmountFlags::DETACH) {
log::error!("{} {}: {}", s!("Cannot umount"), mountpoint, e)
}
}
}
}
fn prepare_mount() -> AutoUmount {
let mut mountpoints = vec![];
// mount procfs
let result = mkdir("/proc", Mode::from_raw_mode(0o755))
.or_else(|err| match err.kind() {
ErrorKind::AlreadyExists => Ok(()),
_ => Err(err),
})
.and_then(|_| fsopen("proc", FsOpenFlags::FSOPEN_CLOEXEC))
.and_then(|fd| fsconfig_create(fd.as_fd()).map(|_| fd))
.and_then(|fd| {
fsmount(
fd.as_fd(),
FsMountFlags::FSMOUNT_CLOEXEC,
MountAttrFlags::empty(),
)
})
.and_then(|fd| {
move_mount(
fd.as_fd(),
"",
CWD,
"/proc",
MoveMountFlags::MOVE_MOUNT_F_EMPTY_PATH,
)
});
match result {
Ok(_) => mountpoints.push("/proc".to_string()),
Err(e) => log::error!("{} {:?}", s!("Cannot mount procfs: "), e),
}
// mount sysfs
let result = mkdir("/sys", Mode::from_raw_mode(0o755))
.or_else(|err| match err.kind() {
ErrorKind::AlreadyExists => Ok(()),
_ => Err(err),
})
.and_then(|_| fsopen("sysfs", FsOpenFlags::FSOPEN_CLOEXEC))
.and_then(|fd| fsconfig_create(fd.as_fd()).map(|_| fd))
.and_then(|fd| {
fsmount(
fd.as_fd(),
FsMountFlags::FSMOUNT_CLOEXEC,
MountAttrFlags::empty(),
)
})
.and_then(|fd| {
move_mount(
fd.as_fd(),
"",
CWD,
"/sys",
MoveMountFlags::MOVE_MOUNT_F_EMPTY_PATH,
)
});
match result {
Ok(_) => mountpoints.push("/sys".to_string()),
Err(e) => log::error!("{} {:?}", s!("Cannot mount sysfs:"), e),
}
AutoUmount { mountpoints }
}
fn setup_kmsg() {
const KMSG: &str = "/dev/kmsg";
let device = match access(KMSG, Access::EXISTS) {
Ok(_) => KMSG,
Err(_) => {
// try to create it
mknodat(
CWD,
"/kmsg",
FileType::CharacterDevice,
0o666.into(),
makedev(1, 11),
)
.ok();
"/kmsg"
}
};
let _ = kernlog::init_with_device(device);
}
fn unlimit_kmsg() {
// Disable kmsg rate limiting
if let Ok(mut rate) = std::fs::File::options()
.write(true)
.open(s!("/proc/sys/kernel/printk_devkmsg"))
{
writeln!(rate, "on").ok();
}
}
pub fn init() -> Result<()> {
// Setup kernel log first
setup_kmsg();
log::info!("{}", s!("Hello, KernelSU!"));
// mount /proc and /sys to access kernel interface
let _dontdrop = prepare_mount();
// This relies on the fact that we have /proc mounted
unlimit_kmsg();
if has_kernelsu() {
log::info!("{}", s!("KernelSU may be already loaded in kernel, skip!"));
} else {
log::info!("{}", s!("Loading kernelsu.ko.."));
if let Err(e) = load_module(s!("/kernelsu.ko")) {
log::error!("{}: {}", s!("Cannot load kernelsu.ko"), e);
}
}
// And now we should prepare the real init to transfer control to it
unlink("/init")?;
let real_init = match access("/init.real", Access::EXISTS) {
Ok(_) => "init.real",
Err(_) => "/system/bin/init",
};
log::info!("{} {}", s!("init is"), real_init);
symlink(real_init, "/init")?;
chmodat(
CWD,
"/init",
Mode::from_raw_mode(0o755),
AtFlags::SYMLINK_NOFOLLOW,
)?;
Ok(())
}
fn has_kernelsu() -> bool {
use syscalls::{syscall, Sysno};
let mut version = 0;
const CMD_GET_VERSION: i32 = 2;
unsafe {
let _ = syscall!(
Sysno::prctl,
0xDEADBEEF,
CMD_GET_VERSION,
std::ptr::addr_of_mut!(version)
);
}
log::info!("{}: {}", s!("KernelSU version"), version);
version != 0
}

View File

@@ -1,97 +0,0 @@
use anyhow::{Context, Result};
use goblin::elf::{section_header, sym::Sym, Elf};
use rustix::{cstr, system::init_module};
use scroll::{ctx::SizeWith, Pwrite};
use std::collections::HashMap;
use std::fs;
use obfstr::obfstr as s;
struct Kptr {
value: String,
}
impl Kptr {
pub fn new() -> Result<Self> {
let value = fs::read_to_string(s!("/proc/sys/kernel/kptr_restrict"))?;
fs::write(s!("/proc/sys/kernel/kptr_restrict"), "1")?;
Ok(Kptr { value })
}
}
impl Drop for Kptr {
fn drop(&mut self) {
let _ = fs::write(s!("/proc/sys/kernel/kptr_restrict"), self.value.as_bytes());
}
}
fn parse_kallsyms() -> Result<HashMap<String, u64>> {
let _dontdrop = Kptr::new()?;
let allsyms = fs::read_to_string(s!("/proc/kallsyms"))?
.lines()
.map(|line| line.split_whitespace())
.filter_map(|mut splits| {
splits
.next()
.and_then(|addr| u64::from_str_radix(addr, 16).ok())
.and_then(|addr| splits.nth(1).map(|symbol| (symbol, addr)))
})
.map(|(symbol, addr)| {
(
symbol
.find("$").or_else(|| symbol.find(".llvm."))
.map_or(symbol, |pos| &symbol[0..pos])
.to_owned(),
addr,
)
})
.collect::<HashMap<_, _>>();
Ok(allsyms)
}
pub fn load_module(path: &str) -> Result<()> {
// check if self is init process(pid == 1)
if !rustix::process::getpid().is_init() {
anyhow::bail!("{}", s!("Invalid process"));
}
let mut buffer =
fs::read(path).with_context(|| format!("{} {}", s!("Cannot read file"), path))?;
let elf = Elf::parse(&buffer)?;
let kernel_symbols =
parse_kallsyms().with_context(|| s!("Cannot parse kallsyms").to_string())?;
let mut modifications = Vec::new();
for (index, mut sym) in elf.syms.iter().enumerate() {
if index == 0 {
continue;
}
if sym.st_shndx != section_header::SHN_UNDEF as usize {
continue;
}
let Some(name) = elf.strtab.get_at(sym.st_name) else {
continue;
};
let offset = elf.syms.offset() + index * Sym::size_with(elf.syms.ctx());
let Some(real_addr) = kernel_symbols.get(name) else {
log::warn!("{}: {}", s!("Cannot found symbol"), &name);
continue;
};
sym.st_shndx = section_header::SHN_ABS as usize;
sym.st_value = *real_addr;
modifications.push((sym, offset));
}
let ctx = *elf.syms.ctx();
for ele in modifications {
buffer.pwrite_with(ele.0, ele.1, ctx)?;
}
init_module(&buffer, cstr!("")).with_context(|| s!("init_module failed.").to_string())?;
Ok(())
}

View File

@@ -1,19 +0,0 @@
#![no_main]
mod init;
mod loader;
use rustix::{cstr, runtime::execve};
/// # Safety
/// This is the entry point of the program
/// We cannot use the main because rust will abort if we don't have std{in/out/err}
/// https://github.com/rust-lang/rust/blob/3071aefdb2821439e2e6f592f41a4d28e40c1e79/library/std/src/sys/unix/mod.rs#L80
/// So we use the C main function and call rust code from there
#[no_mangle]
pub unsafe extern "C" fn main(_argc: i32, argv: *const *const u8, envp: *const *const u8) -> i32 {
let _ = init::init();
unsafe {
execve(cstr!("/init"), argv, envp);
}
0
}