给Android 4.9内核添加KernelSU支持

给Android 4.9内核添加KernelSU支持

KaguraiYoRoy
2024-12-27 / 0 评论 / 769 阅读 / 正在检测是否收录...

前言

KernelSU出来也有一段时间了,官方只支持GKI内核但是给出了非GKI内核的集成方案。咱使用的小米8屏幕指纹版是基于Android4.9内核的,实测直接使用KernelSU的脚本集成会出问题,故记录下折腾过程
特别感谢:Tomsec大佬提供的4.9修复方案

准备材料

  • Android Kernel源码,此处使用的是LineageOS/android_kernel_xiaomi_sdm845
  • 能访问GitHub的网络环境
  • AnyKernel3源码,可参考如下仓库:https://github.com/YoriInstitute/AnyKernel3-equuleus
  • 交叉编译器,可参考如下仓库:https://github.com/YoriInstitute/AnyKernel3-equuleus/blob/13/.github/workflows/build.yml#L21-L23
  • 编译服务器

开整

编译环境配置这里就不叙述了,可以放在ROM编译里制作包的时候直接集成在boot.img里也可以单独编译成AnyKernel3可刷入包,这里使用的是AnyKernel3的方案。

下载内核源码、交叉编译器

git clone https://github.com/KaguraiYoRoy/android_kernel_xiaomi_sdm845 -b lineage-20 sdm845 #内核源码
git clone https://android.googlesource.com/platform/prebuilts/clang/host/linux-x86 --depth=1 -b android-13.0.0_r43 clang #Clang
git clone https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9 -b android-10.0.0_r32 --depth=1 #aarch64的GCC
git clone https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9 -b android-10.0.0_r32 --depth=1 #arm的GCC

不同内核需要的交叉编译器可能不同,请根据你的实际情况修改

修改内核源码

参考如下两个commit:

commit b5853fb7cefdc8a2e160cb73512dc6b51569fa66
Author: OnlyTomInSecond <[email protected]>
Date:   Wed Apr 5 11:05:12 2023 +0800

    kernelsu: allow init exec ksud under nosuid

    Change-Id: I8aa6e6d3cbee1addd5da9bb48b4c08ce91f9db81

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 4abba0e1674d..693f2ac03352 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2320,7 +2320,10 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm,
 {
        int nnp = (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS);
        int nosuid = !mnt_may_suid(bprm->file->f_path.mnt);
-       int rc;
+       int rc, error;
+    static u32 ksu_sid;
+       char *secdata;
+    u32 seclen;

        if (!nnp && !nosuid)
      return 0; /* neither NNP nor nosuid */
@@ -2328,6 +2331,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
commit 8bfe4d4de25650505798cba0a5a20db4b2ab7dd6
Author: OnlyTomInSecond <[email protected]>
Date:   Thu Oct 19 17:55:23 2023 +0800

    Kernelsu: add path_umount implementation.

    Change-Id: I3b0273e9857c51cc3215afab0d2cebe0dff38cfb

diff --git a/fs/namespace.c b/fs/namespace.c
index 21fd423b19cf..219a501337b0 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1711,6 +1711,38 @@ static inline bool may_mandlock(void)
 }
 #endif

+static int can_umount(const struct path *path, int flags)
+{
+       struct mount *mnt = real_mount(path->mnt);
+
+       if (!may_mount())
+     return -EPERM;
+       if (path->dentry != path->mnt->mnt_root)
+     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;
+}
+
+// caller is responsible for flags being sane
+int path_umount(struct path *path, int flags)
+{
+       struct mount *mnt = real_mount(path->mnt);
+       int ret;
+
+       ret = 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;
+}
 /*
  * Now umount can handle mount points as well as block devices.
  * This is important for filesystems which use unnamed block devices.

方案来源:Tomsec

启用kprobe支持

打开你的内核的defconfig文件,添加如下三行:

CONFIG_KPROBES=y
CONFIG_HAVE_KPROBES=y
CONFIG_KPROBE_EVENTS=y

集成KernelSU

此步骤和ksu官网教程一样,在内核根目录执行如下指令:

curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s v0.9.5

编写AnyKernel3脚本

下载下来AnyKernel3,并且按照README修改anykernel.sh,可参考咱的仓库修改:

  • 仓库地址:https://github.com/iYoRoy-AOSP-Institute/AnyKernel3-equuleus/blob/14/anykernel.sh

编译内核

此处建议参考网上教程,不同内核编译参数设置会有所不同
咱将编译过程打包成了shell脚本,可供参考:

#!/bin/bash
ARCH="arm64"
CLANG_DIR="$WORKSPACE/clang/clang-r450784d" #Clang文件夹
CC="$CLANG_DIR/bin/clang"
export PATH="$CLANG_DIR/bin:$PATH"
OUT_DIR="./out"
CLANG_TRIPLE="aarch64-linux-gnu-"
CROSS_COMPILE="$WORKSPACE/aarch64-linux-android-4.9/bin/aarch64-linux-androidkernel-" #aarch64GCC
CROSS_COMPILE_ARM32="$WORKSPACE/arm-linux-androideabi-4.9/bin/arm-linux-androidkernel-" #armGCC
CC_ADDITION_FLAGS="AR=llvm-ar NM=llvm-nm OBJCOPY=llvm-objcopy OBJDUMP=llvm-objdump STRIP=llvm-strip LLVM_IAS=1 LLVM=1 LD=ld.lld"
ANYKERNEL_DIR="$WORKSPACE/AnyKernel3" #编写好的AnyKernel3文件夹所在位置

THREAD=$(nproc --all)

args="-j$THREAD O=$OUT_DIR ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE CROSS_COMPILE_ARM32=$CROSS_COMPILE_ARM32 CC=$CC CLANG_TRIPLE=$CLANG_TRIPLE $CC_ADDITION_FLAGS"

### 编译内核 ###
echo "[+]Args: $args"
echo "[+}Generate .config"
make equuleus_user_defconfig $args #此处equuleus_user_defconfig为equuleus的内核defconfig文件,请替换成你的内核配置文件名
echo "[+]Begin Build"
make $args
### 编译完成 ###

### 制作AnyKernel3 ###
cd $WORKSPACE/sdm845/KernelSU
KSU_VERSION='v0.9.5'
TARGET_KERNEL="Mi8Pro-LineageKernel-KernelSU$KSU_VERSION" #内核文件名
echo "[+]KernelSU Version: $KSU_VERSION"
echo "[+]Target file: $TARGET_KERNEL"
cd $WORKSPACE/AnyKernel3
cp $WORKSPACE/sdm845/out/arch/arm64/boot/Image .
cp $WORKSPACE/sdm845/out/arch/arm64/boot/Image.gz .
cp $WORKSPACE/sdm845/out/arch/arm64/boot/Image.gz-dtb .
OUTPUT_FILE=${TARGET_KERNEL}-$(date +"%y.%m.%d").zip
echo "[+]Output: $OUTPUT_FILE"
zip -r $OUTPUT_FILE *
mv $OUTPUT_FILE $WORKSPACE

刷入

使用twrp之类的recovery即可

使用GitHub Actions自动编译内核

yml编写请参考:https://github.com/iYoRoy-AOSP-Institute/AnyKernel3-equuleus/blob/13/.github/workflows/build.yml

头图下载

3

评论 (0)

取消