├── .github └── workflows │ └── main.yml ├── README.md └── patches ├── allow-init-exec-ksud-under-nosuid.patch └── backport-path-umount.patch /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Check and Build 2 | 3 | env: 4 | kernel_repository: PixelExperience-Devices/kernel_xiaomi_sdm845 5 | kernel_branch: fourteen 6 | device: dipper 7 | clang_version: r487747c 8 | defconfig: | 9 | dipper_defconfig 10 | kernel_patch: | 11 | backport-path-umount.patch 12 | kernelsu_patch: | 13 | 14 | on: 15 | workflow_dispatch: 16 | inputs: 17 | allow_rebuild: 18 | description: "Allow Rebuild" 19 | type: boolean 20 | default: false 21 | 22 | jobs: 23 | check_kernelsu_update: 24 | name: Check KernelSU update 25 | runs-on: ubuntu-latest 26 | steps: 27 | - name: Check KernelSU version 28 | id: check_kernelsu_version 29 | run: | 30 | local_version=$(curl -L --header 'authorization: Bearer ${{ github.token }}' https://api.github.com/repos/${{ github.repository }}/releases/latest | jq -r .tag_name) 31 | # remote_version=$(curl -L https://api.github.com/repos/tiann/KernelSU/releases/latest | jq -r .tag_name) 32 | remote_version=v0.9.5 33 | echo local_version=$local_version | tee -a $GITHUB_OUTPUT 34 | echo remote_version=$remote_version | tee -a $GITHUB_OUTPUT 35 | outputs: 36 | local_version: ${{ steps.check_kernelsu_version.outputs.local_version }} 37 | remote_version: ${{ steps.check_kernelsu_version.outputs.remote_version }} 38 | 39 | build: 40 | name: Build kernel 41 | needs: check_kernelsu_update 42 | if: inputs.allow_rebuild || needs.check_kernelsu_update.outputs.local_version != needs.check_kernelsu_update.outputs.remote_version 43 | runs-on: ubuntu-latest 44 | permissions: 45 | contents: write 46 | steps: 47 | - name: Set env 48 | run: | 49 | echo kernelsu_remote_version=${{ needs.check_kernelsu_update.outputs.remote_version }} | tee -a $GITHUB_ENV 50 | 51 | if [[ "$clang_version" = "r"* ]] || [[ "$clang_version" = "latest" ]]; then 52 | clang_type=aosp 53 | else 54 | clang_type=vanilla 55 | fi 56 | echo clang_type=$clang_type | tee -a $GITHUB_ENV 57 | 58 | if [[ "$clang_version" = "latest" ]]; then 59 | 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]?') 60 | echo clang_version=$clang_version | tee -a $GITHUB_ENV 61 | fi 62 | 63 | - name: Install packages 64 | run: | 65 | sudo apt update 66 | sudo apt install -y \ 67 | binutils-arm-linux-gnueabi \ 68 | binutils-aarch64-linux-gnu 69 | 70 | - name: Checkout kernel source 71 | uses: actions/checkout@v4 72 | with: 73 | repository: ${{ env.kernel_repository }} 74 | ref: ${{ env.kernel_branch }} 75 | submodules: recursive 76 | 77 | - name: Checkout this repo 78 | uses: actions/checkout@v4 79 | with: 80 | path: this-repo 81 | submodules: recursive 82 | 83 | - name: Get latest kernel commit id 84 | run: | 85 | echo kernel_commit_id=$(git rev-parse HEAD) | tee -a $GITHUB_ENV 86 | 87 | - name: Merge defconfig 88 | run: | 89 | while read -r line; do 90 | if [ -z "$line" ] || [[ "$line" == "#"* ]]; then 91 | continue 92 | fi 93 | echo "Merging defconfig: $line" 94 | cat arch/arm64/configs/$line >>arch/arm64/configs/merged_defconfig 95 | done <<<"$defconfig" 96 | 97 | - name: Setup KernelSU 98 | run: | 99 | # https://kernelsu.org/zh_CN/guide/how-to-integrate-for-non-gki.html 100 | curl -L https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh | bash -s -- $kernelsu_remote_version 101 | echo 'CONFIG_KPROBES=y' >>arch/arm64/configs/merged_defconfig 102 | echo 'CONFIG_HAVE_KPROBES=y' >>arch/arm64/configs/merged_defconfig 103 | echo 'CONFIG_KPROBE_EVENTS=y' >>arch/arm64/configs/merged_defconfig 104 | 105 | - name: Apply kernel patch 106 | run: | 107 | while read -r line; do 108 | if [ -z "$line" ] || [[ "$line" == "#"* ]]; then 109 | continue 110 | fi 111 | echo "Applying kernel patch: $line" 112 | git apply "this-repo/patches/$line" 113 | done <<<"$kernel_patch" 114 | 115 | - name: Apply KernelSU patch 116 | run: | 117 | while read -r line; do 118 | if [ -z "$line" ] || [[ "$line" == "#"* ]]; then 119 | continue 120 | fi 121 | echo "Applying KernelSU patch: $line" 122 | git apply -p2 --directory KernelSU/kernel "this-repo/patches/$line" 123 | done <<<"$kernelsu_patch" 124 | 125 | - name: "AOSP-Clang: Restore" 126 | id: aosp_clang_restore 127 | if: env.clang_type == 'aosp' 128 | uses: actions/cache/restore@v4 129 | with: 130 | path: aosp-clang 131 | key: aosp-clang-${{ env.clang_version }} 132 | 133 | - name: "AOSP-Clang: Download" 134 | id: aosp_clang_download 135 | if: env.clang_type == 'aosp' && steps.aosp_clang_restore.outputs.cache-hit != 'true' 136 | run: | 137 | aosp_clang_branch=$( 138 | case "$clang_version" in 139 | r365631c ) echo android11-release;; 140 | r383902 | r416183b) echo master-kernel-build-2021 ;; 141 | r450784e) echo master-kernel-build-2022 ;; 142 | r487747c) echo main-kernel-build-2023 ;; 143 | *) echo main ;; 144 | esac 145 | ) 146 | mkdir -p aosp-clang 147 | 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 148 | 149 | - name: "AOSP-Clang: Save" 150 | id: aosp_clang_save 151 | if: env.clang_type == 'aosp' && steps.aosp_clang_download.outcome == 'success' 152 | uses: actions/cache/save@v4 153 | with: 154 | path: aosp-clang 155 | key: aosp-clang-${{ env.clang_version }} 156 | 157 | - name: "AOSP-Clang: Setup" 158 | if: env.clang_type == 'aosp' 159 | run: | 160 | echo PATH=$(pwd)/aosp-clang/bin:$PATH | tee -a $GITHUB_ENV 161 | 162 | - name: "Vanilla-Clang: Setup" 163 | if: env.clang_type == 'vanilla' 164 | run: | 165 | curl -L https://apt.llvm.org/llvm.sh | sudo bash -s -- $clang_version 166 | echo PATH=/usr/lib/llvm-$clang_version/bin:$PATH | tee -a $GITHUB_ENV 167 | 168 | - name: export flags 169 | run: | 170 | echo flags=" \ 171 | O=out \ 172 | ARCH=arm64 \ 173 | LLVM=1 \ 174 | LLVM_IAS=1 \ 175 | CROSS_COMPILE=aarch64-linux-gnu- \ 176 | CROSS_COMPILE_ARM32=arm-linux-gnueabi- 177 | " | tee -a $GITHUB_ENV 178 | 179 | - name: Make defconfig 180 | run: | 181 | make $flags merged_defconfig 182 | 183 | - name: Make 184 | run: | 185 | make $flags -j$(nproc --all) 186 | 187 | - name: AnyKernel3 188 | run: | 189 | curl -Lo AnyKernel3.zip https://github.com/osm0sis/AnyKernel3/archive/refs/heads/master.zip 190 | unzip AnyKernel3.zip 191 | 192 | cat >AnyKernel3-master/anykernel.sh < 26 | 27 | ```yaml 28 | env: 29 | kernel_repository: PixelExperience-Devices/kernel_xiaomi_sdm845 30 | kernel_branch: fourteen 31 | device: dipper 32 | clang_version: r487747c 33 | defconfig: | 34 | dipper_defconfig 35 | kernel_patch: | 36 | backport-path-umount.patch 37 | kernelsu_patch: | 38 | ``` 39 | 40 | ## 参数 41 | 42 | ### defconfig 43 | 44 | 在机器内核仓库的 `arch/arm64/configs` 文件夹能找到机器的 `defconfig` 45 | 46 | --- 47 | 48 | ### clang_version 49 | 50 | 只能填写以下 AOSP Clang 版本号,可能需要尝试不同的版本号才能成功编译 51 | 52 | | AOSP Clang | 基于 Clang | 最兼容的内核 | 53 | | ---------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 54 | | 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) | 55 | | r383902 | 11 | [4.14](https://android.googlesource.com/kernel/common/+/refs/heads/deprecated/android-4.14-stable/build.config.common) | 56 | | 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) | 57 | | r450784e | 14 | [5.10](https://android.googlesource.com/kernel/common/+/refs/heads/android13-5.10/build.config.constants) | 58 | | 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) | 59 | 60 | 若想使用官方 Clang 编译,则改成填写官方 Clang 版本号,例如 17 61 | 62 | --- 63 | 64 | ### kernel_patch 和 kernelsu_patch 65 | 66 | 分别是应用到 `内核` 和 `KernelSU` 的补丁文件列表,补丁文件需放在 `patches` 文件夹 67 | 68 | 补丁详细说明: 69 | 70 | 71 | 72 | 73 | 74 | 如果 KernelSU 功能正常,**不要** 添加补丁 75 | -------------------------------------------------------------------------------- /patches/allow-init-exec-ksud-under-nosuid.patch: -------------------------------------------------------------------------------- 1 | From 3df9df42a659f489091445d813b8c0477215ae3a Mon Sep 17 00:00:00 2001 2 | From: F-19-F <58457605+F-19-F@users.noreply.github.com> 3 | Date: Wed, 1 Feb 2023 16:05:34 +0800 4 | Subject: [PATCH] allow init exec ksud under nosuid 5 | 6 | --- 7 | security/selinux/hooks.c | 17 ++++++++++++++++- 8 | 1 file changed, 16 insertions(+), 1 deletion(-) 9 | 10 | diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c 11 | index 88b14fd6e5fd..d661290357dc 100644 12 | --- a/security/selinux/hooks.c 13 | +++ b/security/selinux/hooks.c 14 | @@ -2266,9 +2266,12 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm, 15 | const struct task_security_struct *old_tsec, 16 | const struct task_security_struct *new_tsec) 17 | { 18 | + static u32 ksu_sid; 19 | + char *secdata; 20 | int nnp = (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS); 21 | int nosuid = !mnt_may_suid(bprm->file->f_path.mnt); 22 | - int rc; 23 | + int rc,error; 24 | + u32 seclen; 25 | 26 | if (!nnp && !nosuid) 27 | return 0; /* neither NNP nor nosuid */ 28 | @@ -2276,6 +2279,18 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm, 29 | if (new_tsec->sid == old_tsec->sid) 30 | return 0; /* No change in credentials */ 31 | 32 | + 33 | + if(!ksu_sid){ 34 | + security_secctx_to_secid("u:r:su:s0", strlen("u:r:su:s0"), &ksu_sid); 35 | + } 36 | + error = security_secid_to_secctx(old_tsec->sid, &secdata, &seclen); 37 | + if (!error) { 38 | + rc = strcmp("u:r:init:s0",secdata); 39 | + security_release_secctx(secdata, seclen); 40 | + if(rc == 0 && new_tsec->sid == ksu_sid){ 41 | + return 0; 42 | + } 43 | + } 44 | /* 45 | * The only transitions we permit under NNP or nosuid 46 | * are transitions to bounded SIDs, i.e. SIDs that are 47 | -------------------------------------------------------------------------------- /patches/backport-path-umount.patch: -------------------------------------------------------------------------------- 1 | --- a/fs/namespace.c 2 | +++ b/fs/namespace.c 3 | @@ -1739,6 +1739,39 @@ static inline bool may_mandlock(void) 4 | } 5 | #endif 6 | 7 | +static int can_umount(const struct path *path, int flags) 8 | +{ 9 | + struct mount *mnt = real_mount(path->mnt); 10 | + 11 | + if (flags & ~(MNT_FORCE | MNT_DETACH | MNT_EXPIRE | UMOUNT_NOFOLLOW)) 12 | + return -EINVAL; 13 | + if (!may_mount()) 14 | + return -EPERM; 15 | + if (path->dentry != path->mnt->mnt_root) 16 | + return -EINVAL; 17 | + if (!check_mnt(mnt)) 18 | + return -EINVAL; 19 | + if (mnt->mnt.mnt_flags & MNT_LOCKED) /* Check optimistically */ 20 | + return -EINVAL; 21 | + if (flags & MNT_FORCE && !capable(CAP_SYS_ADMIN)) 22 | + return -EPERM; 23 | + return 0; 24 | +} 25 | + 26 | +int path_umount(struct path *path, int flags) 27 | +{ 28 | + struct mount *mnt = real_mount(path->mnt); 29 | + int ret; 30 | + 31 | + ret = can_umount(path, flags); 32 | + if (!ret) 33 | + ret = do_umount(mnt, flags); 34 | + 35 | + /* we mustn't call path_put() as that would clear mnt_expiry_mark */ 36 | + dput(path->dentry); 37 | + mntput_no_expire(mnt); 38 | + return ret; 39 | +} 40 | /* 41 | * Now umount can handle mount points as well as block devices. 42 | * This is important for filesystems which use unnamed block devices. 43 | --------------------------------------------------------------------------------