Compare commits

...

3 Commits

Author SHA1 Message Date
dependabot[bot]
2efadb2ccd build(deps): bump the crates group in /userspace/ksuinit with 21 updates
Bumps the crates group in /userspace/ksuinit with 21 updates:

| Package | From | To |
| --- | --- | --- |
| [scroll](https://github.com/m4b/scroll) | `0.12.0` | `0.13.0` |
| [anyhow](https://github.com/dtolnay/anyhow) | `1.0.80` | `1.0.98` |
| [syscalls](https://github.com/jasonwhite/syscalls) | `0.6.15` | `0.6.18` |
| [log](https://github.com/rust-lang/log) | `0.4.21` | `0.4.27` |
| [obfstr](https://github.com/CasualX/obfstr) | `0.4.3` | `0.4.4` |
| [bitflags](https://github.com/bitflags/bitflags) | `2.4.2` | `2.9.1` |
| [errno](https://github.com/lambda-fairy/rust-errno) | `0.3.8` | `0.3.13` |
| [libc](https://github.com/rust-lang/libc) | `0.2.153` | `0.2.174` |
| [proc-macro2](https://github.com/dtolnay/proc-macro2) | `1.0.78` | `1.0.95` |
| [quote](https://github.com/dtolnay/quote) | `1.0.35` | `1.0.40` |
| [scroll_derive](https://github.com/m4b/scroll) | `0.12.0` | `0.12.1` |
| [syn](https://github.com/dtolnay/syn) | `2.0.52` | `2.0.104` |
| [unicode-ident](https://github.com/dtolnay/unicode-ident) | `1.0.12` | `1.0.18` |
| [windows-targets](https://github.com/microsoft/windows-rs) | `0.52.4` | `0.52.6` |
| [windows_aarch64_gnullvm](https://github.com/microsoft/windows-rs) | `0.52.4` | `0.52.6` |
| [windows_aarch64_msvc](https://github.com/microsoft/windows-rs) | `0.52.4` | `0.52.6` |
| [windows_i686_gnu](https://github.com/microsoft/windows-rs) | `0.52.4` | `0.52.6` |
| [windows_i686_msvc](https://github.com/microsoft/windows-rs) | `0.52.4` | `0.52.6` |
| [windows_x86_64_gnu](https://github.com/microsoft/windows-rs) | `0.52.4` | `0.52.6` |
| [windows_x86_64_gnullvm](https://github.com/microsoft/windows-rs) | `0.52.4` | `0.52.6` |
| [windows_x86_64_msvc](https://github.com/microsoft/windows-rs) | `0.52.4` | `0.52.6` |


Updates `scroll` from 0.12.0 to 0.13.0
- [Changelog](https://github.com/m4b/scroll/blob/master/CHANGELOG.md)
- [Commits](https://github.com/m4b/scroll/commits)

Updates `anyhow` from 1.0.80 to 1.0.98
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.80...1.0.98)

Updates `syscalls` from 0.6.15 to 0.6.18
- [Changelog](https://github.com/jasonwhite/syscalls/blob/main/CHANGELOG.md)
- [Commits](https://github.com/jasonwhite/syscalls/compare/0.6.15...0.6.18)

Updates `log` from 0.4.21 to 0.4.27
- [Release notes](https://github.com/rust-lang/log/releases)
- [Changelog](https://github.com/rust-lang/log/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/log/compare/0.4.21...0.4.27)

Updates `obfstr` from 0.4.3 to 0.4.4
- [Commits](https://github.com/CasualX/obfstr/compare/v0.4.3...v0.4.4)

Updates `bitflags` from 2.4.2 to 2.9.1
- [Release notes](https://github.com/bitflags/bitflags/releases)
- [Changelog](https://github.com/bitflags/bitflags/blob/main/CHANGELOG.md)
- [Commits](https://github.com/bitflags/bitflags/compare/2.4.2...2.9.1)

Updates `errno` from 0.3.8 to 0.3.13
- [Release notes](https://github.com/lambda-fairy/rust-errno/releases)
- [Changelog](https://github.com/lambda-fairy/rust-errno/blob/main/CHANGELOG.md)
- [Commits](https://github.com/lambda-fairy/rust-errno/compare/v0.3.8...v0.3.13)

Updates `libc` from 0.2.153 to 0.2.174
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Changelog](https://github.com/rust-lang/libc/blob/0.2.174/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.153...0.2.174)

Updates `proc-macro2` from 1.0.78 to 1.0.95
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.78...1.0.95)

Updates `quote` from 1.0.35 to 1.0.40
- [Release notes](https://github.com/dtolnay/quote/releases)
- [Commits](https://github.com/dtolnay/quote/compare/1.0.35...1.0.40)

Updates `scroll_derive` from 0.12.0 to 0.12.1
- [Changelog](https://github.com/m4b/scroll/blob/master/CHANGELOG.md)
- [Commits](https://github.com/m4b/scroll/commits)

Updates `syn` from 2.0.52 to 2.0.104
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/2.0.52...2.0.104)

Updates `unicode-ident` from 1.0.12 to 1.0.18
- [Release notes](https://github.com/dtolnay/unicode-ident/releases)
- [Commits](https://github.com/dtolnay/unicode-ident/compare/1.0.12...1.0.18)

Updates `windows-targets` from 0.52.4 to 0.52.6
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_aarch64_gnullvm` from 0.52.4 to 0.52.6
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_aarch64_msvc` from 0.52.4 to 0.52.6
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_i686_gnu` from 0.52.4 to 0.52.6
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_i686_msvc` from 0.52.4 to 0.52.6
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_x86_64_gnu` from 0.52.4 to 0.52.6
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_x86_64_gnullvm` from 0.52.4 to 0.52.6
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `windows_x86_64_msvc` from 0.52.4 to 0.52.6
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

---
updated-dependencies:
- dependency-name: scroll
  dependency-version: 0.13.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: crates
- dependency-name: anyhow
  dependency-version: 1.0.98
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: syscalls
  dependency-version: 0.6.18
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: log
  dependency-version: 0.4.27
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: obfstr
  dependency-version: 0.4.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: bitflags
  dependency-version: 2.9.1
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: crates
- dependency-name: errno
  dependency-version: 0.3.13
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: libc
  dependency-version: 0.2.174
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: proc-macro2
  dependency-version: 1.0.95
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: quote
  dependency-version: 1.0.40
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: scroll_derive
  dependency-version: 0.12.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: syn
  dependency-version: 2.0.104
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: unicode-ident
  dependency-version: 1.0.18
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: windows-targets
  dependency-version: 0.52.6
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: windows_aarch64_gnullvm
  dependency-version: 0.52.6
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: windows_aarch64_msvc
  dependency-version: 0.52.6
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: windows_i686_gnu
  dependency-version: 0.52.6
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: windows_i686_msvc
  dependency-version: 0.52.6
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: windows_x86_64_gnu
  dependency-version: 0.52.6
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: windows_x86_64_gnullvm
  dependency-version: 0.52.6
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: windows_x86_64_msvc
  dependency-version: 0.52.6
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-10 04:49:52 +00:00
tiann
edb99a2c1a userspace: implement OSS ksuinit 2025-08-10 10:48:13 +06:00
James McConnell
eaab98b7ec ci(workflows): add artifact caching to build-manager-ci and build-manager-spoofed workflows (#702)
* ci(workflows): add artifact caching to build-manager-ci workflow

Add cache check, save and restore steps to avoid rebuilding artifacts when source files haven't changed. The workflow now checks for cached artifacts first and only rebuilds if cache is invalid or missing.

* ci(workflows): add artifact caching to build-manager-spoofed workflow
Add cache check, save and restore steps to avoid rebuilding artifacts when source files haven't changed. The workflow now checks for cached artifacts first and only rebuilds if cache is invalid or missing.
2025-08-05 09:47:24 +06:00
18 changed files with 1020 additions and 101 deletions

View File

@@ -8,6 +8,16 @@ 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

@@ -19,12 +19,48 @@ on:
workflow_dispatch:
jobs:
check-cache:
runs-on: ubuntu-latest
outputs:
cache-hit: ${{ steps.cache-artifacts.outputs.cache-hit }}
cache-key: ${{ steps.generate-cache-key.outputs.cache-key }}
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Generate cache key from source files
id: generate-cache-key
run: |
# Calculate hash of all files except manager directory
HASH=$(find . -type f \
-not -path "./manager/*" \
-not -path "./.git/*" \
-not -path "./.github/workflows/build-manager-ci.yml" \
-exec sha256sum {} \; | sort | sha256sum | cut -d' ' -f1)
echo "cache-key=artifacts-$HASH" >> $GITHUB_OUTPUT
echo "Generated cache key: artifacts-$HASH"
- name: Check for cached artifacts
id: cache-artifacts
uses: actions/cache@v4
with:
path: |
cached-artifacts/susfsd
cached-artifacts/ksud_overlayfs
cached-artifacts/ksud_magic
key: ${{ steps.generate-cache-key.outputs.cache-key }}
build-lkm:
needs: check-cache
if: needs.check-cache.outputs.cache-hit != 'true'
uses: ./.github/workflows/build-lkm.yml
secrets: inherit
build-susfsd:
needs: build-lkm
needs: [check-cache, build-lkm]
if: needs.check-cache.outputs.cache-hit != 'true'
strategy:
matrix:
include:
@@ -33,8 +69,22 @@ 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: build-susfsd
needs: [check-cache, build-ksuinit]
if: needs.check-cache.outputs.cache-hit != 'true'
strategy:
matrix:
include:
@@ -49,8 +99,50 @@ jobs:
target: ${{ matrix.target }}
os: ${{ matrix.os }}
cache-artifacts:
needs: [check-cache, build-ksud]
if: needs.check-cache.outputs.cache-hit != 'true'
runs-on: ubuntu-latest
steps:
- name: Download susfsd artifacts
uses: actions/download-artifact@v4
with:
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:
pattern: ksud_overlayfs-*
path: cached-artifacts/ksud_overlayfs
merge-multiple: true
- name: Download ksud_magic artifacts
uses: actions/download-artifact@v4
with:
pattern: ksud_magic-*
path: cached-artifacts/ksud_magic
merge-multiple: true
- name: Cache artifacts
uses: actions/cache/save@v4
with:
path: |
cached-artifacts/susfsd
cached-artifacts/ksud_overlayfs
cached-artifacts/ksud_magic
key: ${{ needs.check-cache.outputs.cache-key }}
build-manager:
needs: build-ksud
needs: [check-cache, build-ksud]
if: always() && needs.check-cache.result == 'success' && (needs.check-cache.outputs.cache-hit == 'true' || needs.build-ksud.result == 'success')
runs-on: ubuntu-latest
defaults:
run:
@@ -92,87 +184,122 @@ jobs:
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
# Restore cached artifacts if cache hit
- name: Restore cached artifacts
if: needs.check-cache.outputs.cache-hit == 'true'
uses: actions/cache/restore@v4
with:
path: |
cached-artifacts/susfsd
cached-artifacts/ksud_overlayfs
cached-artifacts/ksud_magic
key: ${{ needs.check-cache.outputs.cache-key }}
# Download fresh artifacts if cache miss
- name: Download susfsd
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4
with:
name: susfsd-linux-android
path: .
- name: Copy susfsd to app jniLibs
run: |
mkdir -p app/src/main/jniLibs/arm64-v8a
cp -f ../arm64-v8a/susfsd ../manager/app/src/main/jniLibs/arm64-v8a/libsusfsd.so
mkdir -p app/src/main/jniLibs/armeabi-v7a
cp -f ../armeabi-v7a/susfsd ../manager/app/src/main/jniLibs/armeabi-v7a/libsusfsd.so
mkdir -p app/src/main/jniLibs/x86_64
cp -f ../x86_64/susfsd ../manager/app/src/main/jniLibs/x86_64/libsusfsd.so
# Download fresh ksud artifacts if cache miss
- name: Download arm64 ksud_overlayfs
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4
with:
name: ksud_overlayfs-aarch64-linux-android
path: ksud_overlayfs
- name: Download arm ksud_overlayfs
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4
with:
name: ksud_overlayfs-armv7-linux-androideabi
path: ksud_overlayfs
- name: Download x86_64 ksud_overlayfs
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4
with:
name: ksud_overlayfs-x86_64-linux-android
path: ksud_overlayfs
- name: Copy ksud_overlayfs to app jniLibs
run: |
mkdir -p app/src/main/jniLibs/arm64-v8a
mkdir -p app/src/main/jniLibs/armeabi-v7a
mkdir -p app/src/main/jniLibs/x86_64
cp -f ../ksud_overlayfs/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_overlayfs.so
cp -f ../ksud_overlayfs/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_overlayfs.so
cp -f ../ksud_overlayfs/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_overlayfs.so
- name: Download arm64 ksud_magic
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4
with:
name: ksud_magic-aarch64-linux-android
path: ksud_magic
- name: Download arm ksud_magic
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4
with:
name: ksud_magic-armv7-linux-androideabi
path: ksud_magic
- name: Download x86_64 ksud_magic
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4
with:
name: ksud_magic-x86_64-linux-android
path: ksud_magic
# Copy artifacts to jniLibs (works for both cached and fresh)
- name: Copy susfsd to app jniLibs
run: |
mkdir -p app/src/main/jniLibs/arm64-v8a
mkdir -p app/src/main/jniLibs/armeabi-v7a
mkdir -p app/src/main/jniLibs/x86_64
if [ "${{ needs.check-cache.outputs.cache-hit }}" == "true" ]; then
# Copy from cached artifacts
cp -f ../cached-artifacts/susfsd/arm64-v8a/susfsd ../manager/app/src/main/jniLibs/arm64-v8a/libsusfsd.so
cp -f ../cached-artifacts/susfsd/armeabi-v7a/susfsd ../manager/app/src/main/jniLibs/armeabi-v7a/libsusfsd.so
cp -f ../cached-artifacts/susfsd/x86_64/susfsd ../manager/app/src/main/jniLibs/x86_64/libsusfsd.so
else
# Copy from fresh artifacts
cp -f ../arm64-v8a/susfsd ../manager/app/src/main/jniLibs/arm64-v8a/libsusfsd.so
cp -f ../armeabi-v7a/susfsd ../manager/app/src/main/jniLibs/armeabi-v7a/libsusfsd.so
cp -f ../x86_64/susfsd ../manager/app/src/main/jniLibs/x86_64/libsusfsd.so
fi
- name: Copy ksud_overlayfs to app jniLibs
run: |
mkdir -p app/src/main/jniLibs/arm64-v8a
mkdir -p app/src/main/jniLibs/armeabi-v7a
mkdir -p app/src/main/jniLibs/x86_64
if [ "${{ needs.check-cache.outputs.cache-hit }}" == "true" ]; then
# Copy from cached artifacts
cp -f ../cached-artifacts/ksud_overlayfs/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_overlayfs.so
cp -f ../cached-artifacts/ksud_overlayfs/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_overlayfs.so
cp -f ../cached-artifacts/ksud_overlayfs/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_overlayfs.so
else
# Copy from fresh artifacts
cp -f ../ksud_overlayfs/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_overlayfs.so
cp -f ../ksud_overlayfs/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_overlayfs.so
cp -f ../ksud_overlayfs/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_overlayfs.so
fi
- name: Copy ksud_magic to app jniLibs
run: |
mkdir -p app/src/main/jniLibs/arm64-v8a
mkdir -p app/src/main/jniLibs/armeabi-v7a
mkdir -p app/src/main/jniLibs/x86_64
cp -f ../ksud_magic/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_magic.so
cp -f ../ksud_magic/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_magic.so
cp -f ../ksud_magic/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_magic.so
if [ "${{ needs.check-cache.outputs.cache-hit }}" == "true" ]; then
# Copy from cached artifacts
cp -f ../cached-artifacts/ksud_magic/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_magic.so
cp -f ../cached-artifacts/ksud_magic/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_magic.so
cp -f ../cached-artifacts/ksud_magic/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_magic.so
else
# Copy from fresh artifacts
cp -f ../ksud_magic/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_magic.so
cp -f ../ksud_magic/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_magic.so
cp -f ../ksud_magic/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_magic.so
fi
- name: Build with Gradle
run: |

View File

@@ -21,12 +21,48 @@ on:
- cron: "0 12 * * *" # 6 PM UTC+6 | 12 PM UTC
jobs:
check-cache:
runs-on: ubuntu-latest
outputs:
cache-hit: ${{ steps.cache-artifacts.outputs.cache-hit }}
cache-key: ${{ steps.generate-cache-key.outputs.cache-key }}
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Generate cache key from source files
id: generate-cache-key
run: |
# Calculate hash of all files except manager directory
HASH=$(find . -type f \
-not -path "./manager/*" \
-not -path "./.git/*" \
-not -path "./.github/workflows/build-manager-spoofed.yml" \
-exec sha256sum {} \; | sort | sha256sum | cut -d' ' -f1)
echo "cache-key=artifacts-spoofed-$HASH" >> $GITHUB_OUTPUT
echo "Generated cache key: artifacts-spoofed-$HASH"
- name: Check for cached artifacts
id: cache-artifacts
uses: actions/cache@v4
with:
path: |
cached-artifacts/susfsd
cached-artifacts/ksud_overlayfs
cached-artifacts/ksud_magic
key: ${{ steps.generate-cache-key.outputs.cache-key }}
build-lkm:
needs: check-cache
if: needs.check-cache.outputs.cache-hit != 'true'
uses: ./.github/workflows/build-lkm.yml
secrets: inherit
build-susfsd:
needs: build-lkm
needs: [check-cache, build-lkm]
if: needs.check-cache.outputs.cache-hit != 'true'
strategy:
matrix:
include:
@@ -35,8 +71,22 @@ 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: build-susfsd
needs: [check-cache, build-ksuinit]
if: needs.check-cache.outputs.cache-hit != 'true'
strategy:
matrix:
include:
@@ -51,8 +101,50 @@ jobs:
target: ${{ matrix.target }}
os: ${{ matrix.os }}
cache-artifacts:
needs: [check-cache, build-ksud]
if: needs.check-cache.outputs.cache-hit != 'true'
runs-on: ubuntu-latest
steps:
- name: Download susfsd artifacts
uses: actions/download-artifact@v4
with:
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:
pattern: ksud_overlayfs-*
path: cached-artifacts/ksud_overlayfs
merge-multiple: true
- name: Download ksud_magic artifacts
uses: actions/download-artifact@v4
with:
pattern: ksud_magic-*
path: cached-artifacts/ksud_magic
merge-multiple: true
- name: Cache artifacts
uses: actions/cache/save@v4
with:
path: |
cached-artifacts/susfsd
cached-artifacts/ksud_overlayfs
cached-artifacts/ksud_magic
key: ${{ needs.check-cache.outputs.cache-key }}
build-manager:
needs: build-ksud
needs: [check-cache, build-ksud]
if: always() && needs.check-cache.result == 'success' && (needs.check-cache.outputs.cache-hit == 'true' || needs.build-ksud.result == 'success')
runs-on: ubuntu-latest
defaults:
run:
@@ -99,75 +191,122 @@ jobs:
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
# Restore cached artifacts if cache hit
- name: Restore cached artifacts
if: needs.check-cache.outputs.cache-hit == 'true'
uses: actions/cache/restore@v4
with:
path: |
cached-artifacts/susfsd
cached-artifacts/ksud_overlayfs
cached-artifacts/ksud_magic
key: ${{ needs.check-cache.outputs.cache-key }}
# Download fresh artifacts if cache miss
- name: Download susfsd
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4
with:
name: susfsd-linux-android
path: .
- name: Copy susfsd to app jniLibs
run: |
mkdir -p app/src/main/jniLibs/arm64-v8a
cp -f ../arm64-v8a/susfsd ../manager/app/src/main/jniLibs/arm64-v8a/libsusfsd.so
mkdir -p app/src/main/jniLibs/armeabi-v7a
cp -f ../armeabi-v7a/susfsd ../manager/app/src/main/jniLibs/armeabi-v7a/libsusfsd.so
mkdir -p app/src/main/jniLibs/x86_64
cp -f ../x86_64/susfsd ../manager/app/src/main/jniLibs/x86_64/libsusfsd.so
# Download fresh ksud artifacts if cache miss
- name: Download arm64 ksud_overlayfs
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4
with:
name: ksud_overlayfs-aarch64-linux-android
path: ksud_overlayfs
- name: Download arm ksud_overlayfs
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4
with:
name: ksud_overlayfs-armv7-linux-androideabi
path: ksud_overlayfs
- name: Download x86_64 ksud_overlayfs
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4
with:
name: ksud_overlayfs-x86_64-linux-android
path: ksud_overlayfs
- name: Copy ksud_overlayfs to app jniLibs
run: |
cp -f ../ksud_overlayfs/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_overlayfs.so
cp -f ../ksud_overlayfs/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_overlayfs.so
cp -f ../ksud_overlayfs/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_overlayfs.so
- name: Download arm64 ksud_magic
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4
with:
name: ksud_magic-aarch64-linux-android
path: ksud_magic
- name: Download arm ksud_magic
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4
with:
name: ksud_magic-armv7-linux-androideabi
path: ksud_magic
- name: Download x86_64 ksud_magic
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4
with:
name: ksud_magic-x86_64-linux-android
path: ksud_magic
# Copy artifacts to jniLibs (works for both cached and fresh)
- name: Copy susfsd to app jniLibs
run: |
mkdir -p app/src/main/jniLibs/arm64-v8a
mkdir -p app/src/main/jniLibs/armeabi-v7a
mkdir -p app/src/main/jniLibs/x86_64
if [ "${{ needs.check-cache.outputs.cache-hit }}" == "true" ]; then
# Copy from cached artifacts
cp -f ../cached-artifacts/susfsd/arm64-v8a/susfsd ../manager/app/src/main/jniLibs/arm64-v8a/libsusfsd.so
cp -f ../cached-artifacts/susfsd/armeabi-v7a/susfsd ../manager/app/src/main/jniLibs/armeabi-v7a/libsusfsd.so
cp -f ../cached-artifacts/susfsd/x86_64/susfsd ../manager/app/src/main/jniLibs/x86_64/libsusfsd.so
else
# Copy from fresh artifacts
cp -f ../arm64-v8a/susfsd ../manager/app/src/main/jniLibs/arm64-v8a/libsusfsd.so
cp -f ../armeabi-v7a/susfsd ../manager/app/src/main/jniLibs/armeabi-v7a/libsusfsd.so
cp -f ../x86_64/susfsd ../manager/app/src/main/jniLibs/x86_64/libsusfsd.so
fi
- name: Copy ksud_overlayfs to app jniLibs
run: |
mkdir -p app/src/main/jniLibs/arm64-v8a
mkdir -p app/src/main/jniLibs/armeabi-v7a
mkdir -p app/src/main/jniLibs/x86_64
if [ "${{ needs.check-cache.outputs.cache-hit }}" == "true" ]; then
# Copy from cached artifacts
cp -f ../cached-artifacts/ksud_overlayfs/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_overlayfs.so
cp -f ../cached-artifacts/ksud_overlayfs/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_overlayfs.so
cp -f ../cached-artifacts/ksud_overlayfs/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_overlayfs.so
else
# Copy from fresh artifacts
cp -f ../ksud_overlayfs/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_overlayfs.so
cp -f ../ksud_overlayfs/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_overlayfs.so
cp -f ../ksud_overlayfs/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_overlayfs.so
fi
- name: Copy ksud_magic to app jniLibs
run: |
cp -f ../ksud_magic/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_magic.so
cp -f ../ksud_magic/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_magic.so
mkdir -p app/src/main/jniLibs/arm64-v8a
mkdir -p app/src/main/jniLibs/armeabi-v7a
mkdir -p app/src/main/jniLibs/x86_64
cp -f ../ksud_magic/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_magic.so
if [ "${{ needs.check-cache.outputs.cache-hit }}" == "true" ]; then
# Copy from cached artifacts
cp -f ../cached-artifacts/ksud_magic/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_magic.so
cp -f ../cached-artifacts/ksud_magic/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_magic.so
cp -f ../cached-artifacts/ksud_magic/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_magic.so
else
# Copy from fresh artifacts
cp -f ../ksud_magic/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_magic.so
cp -f ../ksud_magic/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_magic.so
cp -f ../ksud_magic/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_magic.so
fi
- name: Build with Gradle
run: |

View File

@@ -33,8 +33,20 @@ jobs:
with:
os: ${{ matrix.os }}
build-ksud:
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
strategy:
matrix:
include:

View File

@@ -6,6 +6,7 @@ on:
- next
paths:
- '.github/workflows/clippy.yml'
- 'userspace/ksuinit/**'
- 'userspace/ksud_magic/**'
- 'userspace/ksud_overlayfs/**'
pull_request:
@@ -13,6 +14,7 @@ on:
- next
paths:
- '.github/workflows/clippy.yml'
- 'userspace/ksuinit/**'
- 'userspace/ksud_magic/**'
- 'userspace/ksud_overlayfs/**'
@@ -32,6 +34,11 @@ 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:
@@ -44,6 +51,8 @@ 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,16 +39,17 @@ 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/
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: 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/
- name: Setup Rust
run: |
rustup update stable
rustup target add x86_64-apple-darwin
rustup target add aarch64-apple-darwin
rustup target add x86_64-linux-android
rustup target add aarch64-linux-android
- name: Cache ksud_overlayfs
uses: Swatinem/rust-cache@v2

57
.github/workflows/ksuinit.yml vendored Normal file
View File

@@ -0,0 +1,57 @@
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,6 +6,7 @@ on:
- 'next'
paths:
- '.github/workflows/rustfmt.yml'
- 'userspace/ksuinit/**'
- 'userspace/ksud_magic/**'
- 'userspace/ksud_overlayfs/**'
pull_request:
@@ -13,6 +14,7 @@ on:
- 'next'
paths:
- '.github/workflows/rustfmt.yml'
- 'userspace/ksuinit/**'
- 'userspace/ksud_magic/**'
- 'userspace/ksud_overlayfs/**'
@@ -29,6 +31,11 @@ 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,6 +6,14 @@
# 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,35 +81,6 @@ 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,2 +1,3 @@
**/*.ko
susfsd
susfsd
ksuinit

View File

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

1
userspace/ksuinit/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
target

240
userspace/ksuinit/Cargo.lock generated Normal file
View File

@@ -0,0 +1,240 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "anyhow"
version = "1.0.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
[[package]]
name = "bitflags"
version = "2.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
[[package]]
name = "errno"
version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad"
dependencies = [
"libc",
"windows-sys",
]
[[package]]
name = "goblin"
version = "0.8.0"
source = "git+https://github.com/tiann/goblin#138d40d4c36471cfbb611eb493f0378ee9fc63f5"
dependencies = [
"log",
"plain",
"scroll 0.12.0",
]
[[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 0.13.0",
"syscalls",
]
[[package]]
name = "libc"
version = "0.2.174"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
[[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.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
[[package]]
name = "obfstr"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0d354e9a302760d07e025701d40534f17dd1fe4c4db955b4e3bd2907c63bdee"
[[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.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
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"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1257cd4248b4132760d6524d6dda4e053bc648c9070b960929bf50cfb1e7add"
[[package]]
name = "scroll_derive"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1783eabc414609e28a5ba76aee5ddd52199f7107a0b24c2e9746a1ecc34a683d"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "syn"
version = "2.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "syscalls"
version = "0.6.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43d0e35dc7d73976a53c7e6d7d177ef804a0c0ee774ec77bcc520c2216fd7cbe"
[[package]]
name = "unicode-ident"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[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.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"

View File

@@ -0,0 +1,34 @@
[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.13"
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

@@ -0,0 +1,185 @@
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

@@ -0,0 +1,97 @@
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

@@ -0,0 +1,19 @@
#![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
}