diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2cafd86..cbe93d4 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,175 +1,233 @@ -name: check and build +name: Check and Build + +env: + kernel_repository: PixelExperience-Devices/kernel_xiaomi_polaris + kernel_branch: thirteen + device: dipper + clang_version: r487747c + defconfig: | + dipper_defconfig + kernel_patch: | + support-umount-modules-kernel.patch + kernelsu_patch: | + support-umount-modules-kernelsu.patch on: + schedule: + - cron: "50 9,21 * * *" workflow_dispatch: inputs: - pseudo_make: - description: "Pseudo Make" + allow_rebuild: + description: "Allow Rebuild" type: boolean default: false - schedule: - - cron: "50 9,21 * * *" - -env: - kernel_repository: PixelExperience-Devices/kernel_xiaomi_polaris - kernel_branch: thirteen - device: dipper - defconfig: dipper_defconfig - use_aosp_clang: false - clang_version: 15 - jobs: check_kernelsu_update: - name: check kernelsu update + name: Check KernelSU update runs-on: ubuntu-latest steps: - - name: install common package + - name: Check KernelSU version + id: check_kernelsu_version run: | - sudo apt update - sudo apt install -y curl jq - - - name: check kernelsu release - id: check_kernelsu_release - run: | - kernelsu_release=`curl https://api.github.com/repos/tiann/KernelSU/releases/latest | jq -r .tag_name` - local_release=`curl --header 'authorization: Bearer ${{ github.token }}' https://api.github.com/repos/${{ github.repository }}/releases/latest | jq -r .tag_name` - - echo $kernelsu_release - echo $local_release - - echo kernelsu_release=$kernelsu_release >> $GITHUB_OUTPUT - echo local_release=$local_release >> $GITHUB_OUTPUT - + local_version=$(curl -L --header 'authorization: Bearer ${{ github.token }}' https://api.github.com/repos/${{ github.repository }}/releases/latest | jq -r .tag_name) + remote_version=$(curl -L https://api.github.com/repos/tiann/KernelSU/releases/latest | jq -r .tag_name) + echo local_version=$local_version | tee -a $GITHUB_OUTPUT + echo remote_version=$remote_version | tee -a $GITHUB_OUTPUT outputs: - kernelsu_release: ${{ steps.check_kernelsu_release.outputs.kernelsu_release }} - local_release: ${{ steps.check_kernelsu_release.outputs.local_release }} + local_version: ${{ steps.check_kernelsu_version.outputs.local_version }} + remote_version: ${{ steps.check_kernelsu_version.outputs.remote_version }} build: + name: Build kernel needs: check_kernelsu_update - if: needs.check_kernelsu_update.outputs.kernelsu_release != needs.check_kernelsu_update.outputs.local_release + if: inputs.allow_rebuild || needs.check_kernelsu_update.outputs.local_version != needs.check_kernelsu_update.outputs.remote_version runs-on: ubuntu-latest permissions: contents: write steps: - - name: install common package + - name: Set env + run: | + echo kernelsu_remote_version=${{ needs.check_kernelsu_update.outputs.remote_version }} | tee -a $GITHUB_ENV + + if [[ "$clang_version" = "r"* ]] || [[ "$clang_version" = "latest" ]]; then + clang_type=aosp + else + clang_type=vanilla + fi + echo clang_type=$clang_type | tee -a $GITHUB_ENV + + if [[ "$clang_version" = "latest" ]]; then + clang_version=$(curl -L https://android.googlesource.com/kernel/common/+/refs/heads/android-mainline/build.config.constants | grep -Eo 'r[0-9]{6}[a-z]?[0-9]?') + echo clang_version=$clang_version | tee -a $GITHUB_ENV + fi + + - name: Install packages run: | sudo apt update - sudo apt install -y curl zip unzip git make bc binutils-arm-linux-gnueabi binutils-aarch64-linux-gnu + sudo apt install -y \ + binutils-arm-linux-gnueabi \ + binutils-aarch64-linux-gnu - - name: checkout kernel - uses: actions/checkout@v3 + - name: Checkout kernel source + uses: actions/checkout@v4 with: repository: ${{ env.kernel_repository }} ref: ${{ env.kernel_branch }} - - name: get latest kernel commit id - run: | - kernel_commit_id=$(git rev-parse HEAD) - echo kernel_commit_id=$kernel_commit_id >> $GITHUB_ENV + - name: Checkout this repo + uses: actions/checkout@v4 + with: + path: this-repo - - name: "aosp-clang: get aosp clang version" - if: ${{ env.use_aosp_clang == 'true' }} + - name: Get latest kernel commit id run: | - aosp_clang_version=$(curl https://android.googlesource.com/kernel/common/+/refs/heads/android-mainline/build.config.constants | sed -E -n 's .*(r[0-9]{6}[a-z]?[0-9]?).* \1 p') - echo aosp_clang_version=$aosp_clang_version >> $GITHUB_ENV + echo kernel_commit_id=$(git rev-parse HEAD) | tee -a $GITHUB_ENV - - name: "aosp-clang: compiler restore" - id: compiler_restore - if: ${{ env.use_aosp_clang == 'true' }} - uses: actions/cache/restore@v3 - with: - path: compiler - key: compiler-${{ env.aosp_clang_version }} + - name: Merge defconfig + run: | + while read -r line; do + if [ -z "$line" ] || [[ "$line" == "#"* ]]; then + continue + fi + echo "Merging defconfig: $line" + cat arch/arm64/configs/$line >>arch/arm64/configs/merged_defconfig + done <<<"$defconfig" + + - name: Setup KernelSU + run: | + # https://kernelsu.org/zh_CN/guide/how-to-integrate-for-non-gki.html + curl -L https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh | bash -s -- $kernelsu_remote_version + echo 'CONFIG_KPROBES=y' >>arch/arm64/configs/merged_defconfig + echo 'CONFIG_HAVE_KPROBES=y' >>arch/arm64/configs/merged_defconfig + echo 'CONFIG_KPROBE_EVENTS=y' >>arch/arm64/configs/merged_defconfig - - name: "aosp-clang: compiler download" - id: compiler_download - if: ${{ env.use_aosp_clang == 'true' && steps.compiler_restore.outputs.cache-hit != 'true' }} + - name: Apply kernel patch + run: | + while read -r line; do + if [ -z "$line" ] || [[ "$line" == "#"* ]]; then + continue + fi + echo "Applying kernel patch: $line" + git apply "this-repo/$line" + done <<<"$kernel_patch" + + - name: Apply KernelSU patch run: | - curl -o aosp-clang.tar.gz https://android.googlesource.com/platform/prebuilts/clang/host/linux-x86/+archive/refs/heads/master/clang-$aosp_clang_version.tar.gz - mkdir -p compiler/aosp-clang - tar -xf aosp-clang.tar.gz -C compiler/aosp-clang - rm -rf aosp-clang.tar.gz - - - name: "aosp-clang: compiler save" - id: compiler_save - if: ${{ env.use_aosp_clang == 'true' && steps.compiler_download.outcome == 'success' }} - uses: actions/cache/save@v3 + while read -r line; do + if [ -z "$line" ] || [[ "$line" == "#"* ]]; then + continue + fi + echo "Applying KernelSU patch: $line" + git apply -p2 --directory KernelSU/kernel "this-repo/$line" + done <<<"$kernelsu_patch" + + - name: "AOSP-Clang: Restore" + id: aosp_clang_restore + if: env.clang_type == 'aosp' + uses: actions/cache/restore@v4 with: - path: compiler - key: ${{ steps.compiler_restore.outputs.cache-primary-key }} + path: aosp-clang + key: aosp-clang-${{ env.clang_version }} - - name: "aosp-clang: setup" - if: ${{ env.use_aosp_clang == 'true' }} + - name: "AOSP-Clang: Download" + id: aosp_clang_download + if: env.clang_type == 'aosp' && steps.aosp_clang_restore.outputs.cache-hit != 'true' run: | - PATH=$(pwd)/compiler/aosp-clang/bin:$PATH - echo PATH=$PATH >> $GITHUB_ENV + aosp_clang_branch=$( + case "$clang_version" in + r365631c ) echo android11-release;; + r383902 | r416183b) echo master-kernel-build-2021 ;; + r450784e) echo master-kernel-build-2022 ;; + r487747c) echo main-kernel-build-2023 ;; + *) echo main ;; + esac + ) + mkdir -p aosp-clang + curl -L https://android.googlesource.com/platform/prebuilts/clang/host/linux-x86/+archive/refs/heads/$aosp_clang_branch/clang-$clang_version.tar.gz | tar xz -C aosp-clang + + - name: "AOSP-Clang: Save" + id: aosp_clang_save + if: env.clang_type == 'aosp' && steps.aosp_clang_download.outcome == 'success' + uses: actions/cache/save@v4 + with: + path: aosp-clang + key: aosp-clang-${{ env.clang_version }} - - name: "vanilla-clang: setup" - if: ${{ env.use_aosp_clang == 'false' }} + - name: "AOSP-Clang: Setup" + if: env.clang_type == 'aosp' run: | - sudo apt install -y clang-$clang_version lld-$clang_version - - PATH=/usr/lib/llvm-$clang_version/bin:$PATH - echo PATH=$PATH >> $GITHUB_ENV + echo PATH=$(pwd)/aosp-clang/bin:$PATH | tee -a $GITHUB_ENV - - name: setup kernelsu + - name: "Vanilla-Clang: Setup" + if: env.clang_type == 'vanilla' run: | - curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash - - echo 'CONFIG_KPROBES=y' >> arch/arm64/configs/${{ env.defconfig }} - - cd KernelSU - # git checkout main - git checkout ${{ needs.check_kernelsu_update.outputs.kernelsu_release }} + curl -L https://apt.llvm.org/llvm.sh | sudo bash -s -- $clang_version + echo PATH=/usr/lib/llvm-$clang_version/bin:$PATH | tee -a $GITHUB_ENV - name: export flags run: | - flags="O=out ARCH=arm64 LLVM=1 LLVM_IAS=1 CROSS_COMPILE=aarch64-linux-gnu- CROSS_COMPILE_ARM32=arm-linux-gnueabi-" - echo flags=$flags >> $GITHUB_ENV - - - name: make defconfig + echo flags=" \ + O=out \ + ARCH=arm64 \ + LLVM=1 \ + LLVM_IAS=1 \ + CROSS_COMPILE=aarch64-linux-gnu- \ + CROSS_COMPILE_ARM32=arm-linux-gnueabi- + " | tee -a $GITHUB_ENV + + - name: Make defconfig run: | - make $flags ${{ env.defconfig }} + make $flags merged_defconfig - - name: make - if: ${{ !inputs.pseudo_make }} + - name: Make run: | make $flags -j$(nproc --all) - - name: pseudo make - if: ${{ inputs.pseudo_make }} - run: | - mkdir -p out/arch/arm64/boot/ - echo 123 > out/arch/arm64/boot/Image - echo 123 > out/arch/arm64/boot/Image.gz - echo 123 > out/arch/arm64/boot/Image.gz-dtb - - - name: anykernel + - name: AnyKernel3 run: | curl -Lo AnyKernel3.zip https://github.com/osm0sis/AnyKernel3/archive/refs/heads/master.zip unzip AnyKernel3.zip - cd AnyKernel3-master - cat > anykernel.sh <AnyKernel3-master/anykernel.sh < + +```yaml +env: + kernel_repository: PixelExperience-Devices/kernel_xiaomi_polaris + kernel_branch: thirteen + device: dipper + clang_version: r487747c + defconfig: | + dipper_defconfig + kernel_patch: | + support-umount-modules-kernel.patch + kernelsu_patch: | + support-umount-modules-kernelsu.patch +``` + +## 参数 + +### defconfig + +在机器内核仓库的 `arch/arm64/configs` 文件夹能找到机器的 `defconfig` + +--- + +### clang_version + +只能填写以下 AOSP Clang 版本号,可能需要尝试不同的版本号才能成功编译 + +| AOSP Clang | 基于 Clang | 最兼容的内核 | +| ---------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| r365631c | 9 | [4.4](https://android.googlesource.com/kernel/common/+/refs/heads/deprecated/android-4.4-p/build.config.common) [4.9](https://android.googlesource.com/kernel/common/+/refs/heads/deprecated/android-4.9-q/build.config.common) | +| r383902 | 11 | [4.14](https://android.googlesource.com/kernel/common/+/refs/heads/deprecated/android-4.14-stable/build.config.common) | +| r416183b | 12 | [4.19](https://android.googlesource.com/kernel/common/+/refs/heads/android-4.19-stable/build.config.common) [5.4](https://android.googlesource.com/kernel/common/+/refs/heads/android12-5.4/build.config.common) | +| r450784e | 14 | [5.10](https://android.googlesource.com/kernel/common/+/refs/heads/android13-5.10/build.config.constants) | +| r487747c | 17 | [5.15](https://android.googlesource.com/kernel/common/+/refs/heads/android14-5.15/build.config.constants) [6.1](https://android.googlesource.com/kernel/common/+/refs/heads/android14-6.1/build.config.constants) | + +若想使用官方 Clang 编译,则改成填写官方 Clang 版本号,例如 17 + +--- + +### kernel_patch 和 kernelsu_patch + +分别是应用到 `内核` 和 `KernelSU` 的补丁列表 + +补丁详细说明: + +如果 KernelSU 功能正常,**不要** 添加补丁 diff --git a/allow-init-exec-ksud-under-nosuid.patch b/allow-init-exec-ksud-under-nosuid.patch new file mode 100644 index 0000000..24e6bbb --- /dev/null +++ b/allow-init-exec-ksud-under-nosuid.patch @@ -0,0 +1,46 @@ +From 3df9df42a659f489091445d813b8c0477215ae3a Mon Sep 17 00:00:00 2001 +From: F-19-F <58457605+F-19-F@users.noreply.github.com> +Date: Wed, 1 Feb 2023 16:05:34 +0800 +Subject: [PATCH] allow init exec ksud under nosuid + +--- + security/selinux/hooks.c | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c +index 88b14fd6e5fd..d661290357dc 100644 +--- a/security/selinux/hooks.c ++++ b/security/selinux/hooks.c +@@ -2266,9 +2266,12 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm, + const struct task_security_struct *old_tsec, + const struct task_security_struct *new_tsec) + { ++ static u32 ksu_sid; ++ char *secdata; + int nnp = (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS); + int nosuid = !mnt_may_suid(bprm->file->f_path.mnt); +- int rc; ++ int rc,error; ++ u32 seclen; + + if (!nnp && !nosuid) + return 0; /* neither NNP nor nosuid */ +@@ -2276,6 +2279,18 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm, + if (new_tsec->sid == old_tsec->sid) + return 0; /* No change in credentials */ + ++ ++ if(!ksu_sid){ ++ security_secctx_to_secid("u:r:su:s0", strlen("u:r:su:s0"), &ksu_sid); ++ } ++ error = security_secid_to_secctx(old_tsec->sid, &secdata, &seclen); ++ if (!error) { ++ rc = strcmp("u:r:init:s0",secdata); ++ security_release_secctx(secdata, seclen); ++ if(rc == 0 && new_tsec->sid == ksu_sid){ ++ return 0; ++ } ++ } + /* + * The only transitions we permit under NNP or nosuid + * are transitions to bounded SIDs, i.e. SIDs that are diff --git a/support-umount-modules-kernel.patch b/support-umount-modules-kernel.patch new file mode 100644 index 0000000..0d13047 --- /dev/null +++ b/support-umount-modules-kernel.patch @@ -0,0 +1,49 @@ +From b365cf69594bfb47a05b9f279a1dbdc00a065b41 Mon Sep 17 00:00:00 2001 +From: wxt1221 <3264117476@qq.com> +Date: Fri, 20 Oct 2023 16:15:35 +0800 +Subject: [PATCH] support umount moduls + +--- + fs/namespace.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/fs/namespace.c b/fs/namespace.c +index 21fd423b1..6f6a0adf4 100644 +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -797,7 +797,7 @@ static void put_mountpoint(struct mountpoint *mp) + } + } + +-static inline int check_mnt(struct mount *mnt) ++inline int check_mnt(struct mount *mnt) + { + return mnt->mnt_ns == current->nsproxy->mnt_ns; + } +@@ -1170,7 +1170,7 @@ void flush_delayed_mntput_wait(void) + flush_delayed_work(&delayed_mntput_work); + } + +-static void mntput_no_expire(struct mount *mnt) ++void mntput_no_expire(struct mount *mnt) + { + rcu_read_lock(); + if (likely(READ_ONCE(mnt->mnt_ns))) { +@@ -1550,7 +1550,7 @@ static void umount_tree(struct mount *mnt, enum umount_tree_flags how) + + static void shrink_submounts(struct mount *mnt); + +-static int do_umount(struct mount *mnt, int flags) ++int do_umount(struct mount *mnt, int flags) + { + struct super_block *sb = mnt->mnt.mnt_sb; + int retval; +@@ -1689,7 +1689,7 @@ void __detach_mounts(struct dentry *dentry) + /* + * Is the caller allowed to modify his namespace? + */ +-static inline bool may_mount(void) ++inline bool may_mount(void) + { + return ns_capable(current->nsproxy->mnt_ns->user_ns, CAP_SYS_ADMIN); + } diff --git a/support-umount-modules-kernelsu.patch b/support-umount-modules-kernelsu.patch new file mode 100644 index 0000000..5071bb3 --- /dev/null +++ b/support-umount-modules-kernelsu.patch @@ -0,0 +1,79 @@ +From 9e24830ccb575e4981b1715dd3971bf3faf19938 Mon Sep 17 00:00:00 2001 +From: wxt1221 <3264117476@qq.com> +Date: Fri, 26 Jan 2024 10:53:36 +0800 +Subject: [PATCH] support umount modules + +--- + kernel/core_hook.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 52 insertions(+) + +diff --git a/kernel/core_hook.c b/kernel/core_hook.c +index 9c863660dd29..04cea2e89017 100644 +--- a/kernel/core_hook.c ++++ b/kernel/core_hook.c +@@ -29,6 +29,53 @@ + #include "selinux/selinux.h" + #include "uid_observer.h" + #include "kernel_compat.h" ++#include "../../fs/mount.h" ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0) ++ ++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) ++extern inline bool may_mount(void); ++extern inline int check_mnt(struct mount *mnt); ++extern void mntput_no_expire(struct mount *mnt); ++extern int do_umount(struct mount *mnt, int flags); ++static inline bool ksu_path_mounted(const struct path *path) ++ { ++ return path->mnt->mnt_root == path->dentry; ++ } ++ static int ksu_can_umount(const struct path *path, int flags) ++ { ++ struct mount *mnt = real_mount(path->mnt); ++ ++ if (!may_mount()) ++ return -EPERM; ++ if (!ksu_path_mounted(path)) ++ return -EINVAL; ++ if (!check_mnt(mnt)) ++ return -EINVAL; ++ if (mnt->mnt.mnt_flags & MNT_LOCKED) /* Check optimistically */ ++ return -EINVAL; ++ if (flags & MNT_FORCE && !capable(CAP_SYS_ADMIN)) ++ return -EPERM; ++ return 0; ++ } ++ int ksu_path_umount(struct path *path, int flags) ++{ ++ struct mount *mnt = real_mount(path->mnt); ++ int ret; ++ ++ ret = ksu_can_umount(path, flags); ++ if (!ret) ++ ret = do_umount(mnt, flags); ++ ++ /* we mustn't call path_put() as that would clear mnt_expiry_mark */ ++ dput(path->dentry); ++ mntput_no_expire(mnt); ++ return ret; ++} ++#else ++ //not tested ++#endif ++ + + static bool ksu_module_mounted = false; + +@@ -501,6 +548,11 @@ static void ksu_umount_mnt(struct path *path, int flags) + if (err) { + pr_info("umount %s failed: %d\n", path->dentry->d_iname, err); + } ++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) ++ int err = ksu_path_umount(path, flags); ++ if (err) { ++ pr_info("umount %s failed: %d\n", path->dentry->d_iname, err); ++ } + #else + // TODO: umount for non GKI kernel + #endif