diff --git a/DMPATCH/Makefile_IBT b/DMPATCH/Makefile_IBT new file mode 100644 index 00000000..31977a2f --- /dev/null +++ b/DMPATCH/Makefile_IBT @@ -0,0 +1,7 @@ + +obj-m += dm_patch_ibt.o + +EXTRA_CFLAGS := -Wall -DVTOY_IBT -fcf-protection=branch -mindirect-branch-register + +dm_patch_ibt-objs := dmpatch.o + diff --git a/DMPATCH/dmpatch.c b/DMPATCH/dmpatch.c index 359c5c3f..e508a062 100644 --- a/DMPATCH/dmpatch.c +++ b/DMPATCH/dmpatch.c @@ -52,7 +52,8 @@ typedef struct ko_param unsigned long sym_put_addr; unsigned long sym_put_size; unsigned long kv_major; - unsigned long padding[2]; + unsigned long ibt; + unsigned long padding[1]; }ko_param; #pragma pack() @@ -91,6 +92,52 @@ static volatile ko_param g_ko_param = #error "unsupported arch" #endif +#ifdef VTOY_IBT +#ifdef CONFIG_X86_64 +/* Using 64-bit values saves one instruction clearing the high half of low */ +#define DECLARE_ARGS(val, low, high) unsigned long low, high +#define EAX_EDX_VAL(val, low, high) ((low) | (high) << 32) +#define EAX_EDX_RET(val, low, high) "=a" (low), "=d" (high) +#else +#define DECLARE_ARGS(val, low, high) unsigned long long val +#define EAX_EDX_VAL(val, low, high) (val) +#define EAX_EDX_RET(val, low, high) "=A" (val) +#endif + +#define EX_TYPE_WRMSR 8 +#define EX_TYPE_RDMSR 9 +#define MSR_IA32_S_CET 0x000006a2 /* kernel mode cet */ +#define CET_ENDBR_EN (1ULL << 2) + +/* Exception table entry */ +#ifdef __ASSEMBLY__ + +#define _ASM_EXTABLE_TYPE(from, to, type) \ + .pushsection "__ex_table","a" ; \ + .balign 4 ; \ + .long (from) - . ; \ + .long (to) - . ; \ + .long type ; \ + .popsection + +#else /* ! __ASSEMBLY__ */ + +#define _ASM_EXTABLE_TYPE(from, to, type) \ + " .pushsection \"__ex_table\",\"a\"\n" \ + " .balign 4\n" \ + " .long (" #from ") - .\n" \ + " .long (" #to ") - .\n" \ + " .long " __stringify(type) " \n" \ + " .popsection\n" + +#endif /* __ASSEMBLY__ */ +#endif /* VTOY_IBT */ + + + + + + #define vdebug(fmt, args...) if(kprintf) kprintf(KERN_ERR fmt, ##args) static unsigned char *g_get_patch[MAX_PATCH] = { NULL }; @@ -166,11 +213,66 @@ static int notrace dmpatch_replace_code return 0; } +#ifdef VTOY_IBT +static __always_inline unsigned long long dmpatch_rdmsr(unsigned int msr) +{ + DECLARE_ARGS(val, low, high); + + asm volatile("1: rdmsr\n" + "2:\n" + _ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_RDMSR) + : EAX_EDX_RET(val, low, high) : "c" (msr)); + + return EAX_EDX_VAL(val, low, high); +} + +static __always_inline void dmpatch_wrmsr(unsigned int msr, u32 low, u32 high) +{ + asm volatile("1: wrmsr\n" + "2:\n" + _ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_WRMSR) + : : "c" (msr), "a"(low), "d" (high) : "memory"); +} + +static u64 dmpatch_ibt_save(void) +{ + u64 msr = 0; + u64 val = 0; + + msr = dmpatch_rdmsr(MSR_IA32_S_CET); + val = msr & ~CET_ENDBR_EN; + dmpatch_wrmsr(MSR_IA32_S_CET, (u32)(val & 0xffffffffULL), (u32)(val >> 32)); + + return msr; +} + +static void dmpatch_ibt_restore(u64 save) +{ + u64 msr; + + msr = dmpatch_rdmsr(MSR_IA32_S_CET); + + msr &= ~CET_ENDBR_EN; + msr |= (save & CET_ENDBR_EN); + + dmpatch_wrmsr(MSR_IA32_S_CET, (u32)(msr & 0xffffffffULL), (u32)(msr >> 32)); +} +#else +static u64 dmpatch_ibt_save(void) { return 0; } +static void dmpatch_ibt_restore(u64 save) { (void)save; } +#endif + static int notrace dmpatch_init(void) { int r = 0; int rc = 0; - + u64 msr = 0; + + if (g_ko_param.ibt == 0x8888) + { + msr = dmpatch_ibt_save(); + } + kprintf = (printk_pf)(g_ko_param.printk_addr); vdebug("dmpatch_init start pagesize=%lu ...\n", g_ko_param.pgsize); @@ -218,6 +320,11 @@ static int notrace dmpatch_init(void) vdebug("######## dm patch success ###########\n"); vdebug("#####################################\n"); + if (g_ko_param.ibt == 0x8888) + { + dmpatch_ibt_restore(msr); + } + out: return rc; @@ -226,6 +333,12 @@ out: static void notrace dmpatch_exit(void) { int i = 0; + u64 msr; + + if (g_ko_param.ibt == 0x8888) + { + msr = dmpatch_ibt_save(); + } for (i = 0; i < MAX_PATCH; i++) { @@ -234,6 +347,11 @@ static void notrace dmpatch_exit(void) } vdebug("dmpatch_exit success\n"); + + if (g_ko_param.ibt == 0x8888) + { + dmpatch_ibt_restore(msr); + } } module_init(dmpatch_init); diff --git a/DMPATCH/ubuntu_build.sh b/DMPATCH/ubuntu_build.sh new file mode 100644 index 00000000..995603bc --- /dev/null +++ b/DMPATCH/ubuntu_build.sh @@ -0,0 +1,65 @@ +#!/bin/bash + +FTPIP=168.0.0.209 +FTPUSR='a:a' + +rm -f dmpatch.c Makefile Makefile_IBT + +for f in dmpatch.c Makefile Makefile_IBT; do + curl -s -u $FTPUSR ftp://$FTPIP/$f -o $f + if [ -f $f ]; then + echo "download $f OK ..." + else + echo "download $f FAILED ..." + exit 1 + fi +done + + + +rm -f *.ko + + +echo "build dm_patch.ko ..." +rm -rf ./aa +mkdir ./aa + +cp -a *.c aa/ +cp -a Makefile aa/ + +cd /home/panda/linux-source-5.13.0 +make modules M=/home/panda/build/aa/ +strip --strip-debug /home/panda/build/aa/dm_patch.ko +cd - + +cp -a aa/dm_patch.ko ./ + + + +echo "build dm_patch_ibt.ko ..." +rm -rf ./aa +mkdir ./aa + +cp -a *.c aa/ +cp -a Makefile_IBT aa/Makefile + +cd /home/panda/linux-source-5.13.0 +make modules M=/home/panda/build/aa/ +strip --strip-debug /home/panda/build/aa/dm_patch_ibt.ko +cd - + +cp -a aa/dm_patch_ibt.ko ./ + +rm -rf ./aa + + +curl -s -T dm_patch.ko -u $FTPUSR ftp://$FTPIP/dm_patch_64.ko || exit 1 +curl -s -T dm_patch_ibt.ko -u $FTPUSR ftp://$FTPIP/dm_patch_ibt_64.ko || exit 1 + + +if [ -f ./dm_patch.ko -a -f ./dm_patch_ibt.ko ]; then + echo -e "\n\n=============== SUCCESS =============\n\n" +else + echo -e "\n\n=============== FAILED ==============\n\n" +fi + diff --git a/IMG/cpio/ventoy/hook/ventoy-hook-lib.sh b/IMG/cpio/ventoy/hook/ventoy-hook-lib.sh index 80765e3a..e8567929 100644 --- a/IMG/cpio/ventoy/hook/ventoy-hook-lib.sh +++ b/IMG/cpio/ventoy/hook/ventoy-hook-lib.sh @@ -223,6 +223,42 @@ ventoy_check_dm_module() { fi } +ventoy_need_proc_ibt() { + vtKv=$($BUSYBOX_PATH/uname -r) + vtMajor=$(echo $vtKv | $AWK -F. '{print $1}') + vtMinor=$(echo $vtKv | $AWK -F. '{print $2}') + + #ibt was supported since linux kernel 5.18 + if [ $vtMajor -lt 5 ]; then + $BUSYBOX_PATH/false; return + elif [ $vtMajor -eq 5 ]; then + if [ $vtMajor -lt 18 ]; then + $BUSYBOX_PATH/false; return + fi + fi + + if $GREP -q ' ibt=off' /proc/cmdline; then + $BUSYBOX_PATH/false; return + fi + + #hardware CPU doesn't support IBT + if $VTOY_PATH/tool/vtoykmod -I; then + : + else + $BUSYBOX_PATH/false; return + fi + + #dot.CONFIG not enabled + if $GREP -q ' ibt_restore$' /proc/kallsyms; then + : + else + $BUSYBOX_PATH/false; return + fi + + $BUSYBOX_PATH/true +} + + ventoy_need_dm_patch() { if [ "$VTOY_LINUX_REMOUNT" != "01" ]; then if $GREP -q 'VTOY_LINUX_REMOUNT=1' /proc/cmdline; then @@ -269,6 +305,16 @@ ventoy_dm_patch() { return fi + if ventoy_need_proc_ibt; then + vtlog "need to proc IBT" + vtKoName=dm_patch_ibt_64.ko + vtIBT='0x8888' + else + vtlog "NO need to proc IBT" + vtIBT='0' + fi + + if [ -f $VTOY_PATH/tool/$vtKoName ]; then vtlog "/ventoy/tool/$vtKoName exist OK" else @@ -364,14 +410,16 @@ ventoy_dm_patch() { return fi + + #step1: modify vermagic/mod crc/relocation vtlog "$VTOY_PATH/tool/vtoykmod -u $VTOY_PATH/tool/$vtKoName $VTOY_PATH/$vtModName $vtDebug" $VTOY_PATH/tool/vtoykmod -u $VTOY_PATH/tool/$vtKoName $VTOY_PATH/$vtModName $vtDebug #step2: fill parameters vtPgsize=$($VTOY_PATH/tool/vtoyksym -p) - vtlog "$VTOY_PATH/tool/vtoykmod -f $VTOY_PATH/tool/$vtKoName $vtPgsize 0x$printk_addr 0x$ro_addr 0x$rw_addr $get_addr $get_size $put_addr $put_size 0x$kprobe_reg_addr 0x$kprobe_unreg_addr $vtKv $vtDebug" - $VTOY_PATH/tool/vtoykmod -f $VTOY_PATH/tool/$vtKoName $vtPgsize 0x$printk_addr 0x$ro_addr 0x$rw_addr $get_addr $get_size $put_addr $put_size 0x$kprobe_reg_addr 0x$kprobe_unreg_addr $vtKv $vtDebug + vtlog "$VTOY_PATH/tool/vtoykmod -f $VTOY_PATH/tool/$vtKoName $vtPgsize 0x$printk_addr 0x$ro_addr 0x$rw_addr $get_addr $get_size $put_addr $put_size 0x$kprobe_reg_addr 0x$kprobe_unreg_addr $vtKv $vtIBT $vtDebug" + $VTOY_PATH/tool/vtoykmod -f $VTOY_PATH/tool/$vtKoName $vtPgsize 0x$printk_addr 0x$ro_addr 0x$rw_addr $get_addr $get_size $put_addr $put_size 0x$kprobe_reg_addr 0x$kprobe_unreg_addr $vtKv $vtIBT $vtDebug $BUSYBOX_PATH/insmod $VTOY_PATH/tool/$vtKoName diff --git a/IMG/cpio_x86/ventoy/tool/dm_patch_64.ko b/IMG/cpio_x86/ventoy/tool/dm_patch_64.ko index b1fc4f1a..48050f6d 100644 Binary files a/IMG/cpio_x86/ventoy/tool/dm_patch_64.ko and b/IMG/cpio_x86/ventoy/tool/dm_patch_64.ko differ diff --git a/IMG/cpio_x86/ventoy/tool/dm_patch_ibt_64.ko b/IMG/cpio_x86/ventoy/tool/dm_patch_ibt_64.ko new file mode 100644 index 00000000..47fb9b29 Binary files /dev/null and b/IMG/cpio_x86/ventoy/tool/dm_patch_ibt_64.ko differ diff --git a/VtoyTool/build.sh b/VtoyTool/build.sh index 8e3e1678..13e056d5 100644 --- a/VtoyTool/build.sh +++ b/VtoyTool/build.sh @@ -2,12 +2,12 @@ rm -f vtoytool/00/* -/opt/diet64/bin/diet -Os gcc -D_FILE_OFFSET_BITS=64 *.c BabyISO/*.c -IBabyISO -Wall -DBUILD_VTOY_TOOL -DUSE_DIET_C -o vtoytool_64 -/opt/diet32/bin/diet -Os gcc -D_FILE_OFFSET_BITS=64 -m32 *.c BabyISO/*.c -IBabyISO -Wall -DBUILD_VTOY_TOOL -DUSE_DIET_C -o vtoytool_32 +/opt/diet64/bin/diet -Os gcc -DVTOY_X86_64 -D_FILE_OFFSET_BITS=64 *.c BabyISO/*.c -IBabyISO -Wall -DBUILD_VTOY_TOOL -DUSE_DIET_C -o vtoytool_64 +/opt/diet32/bin/diet -Os gcc -DVTOY_I386 -D_FILE_OFFSET_BITS=64 -m32 *.c BabyISO/*.c -IBabyISO -Wall -DBUILD_VTOY_TOOL -DUSE_DIET_C -o vtoytool_32 -aarch64-buildroot-linux-uclibc-gcc -Os -static -D_FILE_OFFSET_BITS=64 *.c BabyISO/*.c -IBabyISO -Wall -DBUILD_VTOY_TOOL -o vtoytool_aa64 +aarch64-buildroot-linux-uclibc-gcc -Os -static -DVTOY_AA64 -D_FILE_OFFSET_BITS=64 *.c BabyISO/*.c -IBabyISO -Wall -DBUILD_VTOY_TOOL -o vtoytool_aa64 -mips64el-linux-musl-gcc -mips64r2 -mabi=64 -Os -static -D_FILE_OFFSET_BITS=64 *.c BabyISO/*.c -IBabyISO -Wall -DBUILD_VTOY_TOOL -o vtoytool_m64e +mips64el-linux-musl-gcc -mips64r2 -mabi=64 -Os -static -DVTOY_MIPS64 -D_FILE_OFFSET_BITS=64 *.c BabyISO/*.c -IBabyISO -Wall -DBUILD_VTOY_TOOL -o vtoytool_m64e #gcc -D_FILE_OFFSET_BITS=64 -static -Wall -DBUILD_VTOY_TOOL *.c BabyISO/*.c -IBabyISO -o vtoytool_64 #gcc -D_FILE_OFFSET_BITS=64 -Wall -DBUILD_VTOY_TOOL -m32 *.c BabyISO/*.c -IBabyISO -o vtoytool_32 diff --git a/VtoyTool/vtoykmod.c b/VtoyTool/vtoykmod.c index 5ffd9623..f2142ff0 100644 --- a/VtoyTool/vtoykmod.c +++ b/VtoyTool/vtoykmod.c @@ -24,6 +24,9 @@ #include #include #include +#ifdef VTOY_X86_64 +#include +#endif #define _ull unsigned long long @@ -177,7 +180,8 @@ typedef struct ko_param unsigned long sym_put_addr; unsigned long sym_put_size; unsigned long kv_major; - unsigned long padding[2]; + unsigned long ibt; + unsigned long padding[1]; }ko_param; #pragma pack() @@ -486,6 +490,7 @@ int vtoykmod_fill_param(char **argv) param->reg_kprobe_addr = strtoul(argv[9], NULL, 16); param->unreg_kprobe_addr = strtoul(argv[10], NULL, 16); param->kv_major = (unsigned long)(argv[11][0] - '0'); + param->ibt = strtoul(argv[12], NULL, 16);; debug("pgsize=%lu (%s)\n", param->pgsize, argv[1]); debug("printk_addr=0x%lx (%s)\n", param->printk_addr, argv[2]); @@ -498,6 +503,7 @@ int vtoykmod_fill_param(char **argv) debug("reg_kprobe_addr=0x%lx (%s)\n", param->reg_kprobe_addr, argv[9]); debug("unreg_kprobe_addr=0x%lx (%s)\n", param->unreg_kprobe_addr, argv[10]); debug("kv_major=%lu (%s)\n", param->kv_major, argv[11]); + debug("ibt=0x%lx (%s)\n", param->ibt, argv[11]); break; } @@ -514,6 +520,26 @@ int vtoykmod_fill_param(char **argv) return 0; } +#ifdef VTOY_X86_64 +static int vtoykmod_check_ibt(void) +{ + uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0; + + __cpuid_count(7, 0, eax, ebx, ecx, edx); + + if (edx & (1 << 20)) + { + return 0; + } + return 1; +} +#else +static int vtoykmod_check_ibt(void) +{ + return 1; +} +#endif + int vtoykmod_main(int argc, char **argv) { int i; @@ -535,6 +561,10 @@ int vtoykmod_main(int argc, char **argv) { return vtoykmod_update(argv[2], argv[3]); } + else if (argv[1][0] == '-' && argv[1][1] == 'I') + { + return vtoykmod_check_ibt(); + } return 0; } diff --git a/VtoyTool/vtoytool/00/vtoytool_32 b/VtoyTool/vtoytool/00/vtoytool_32 index e2bca24d..84cc383c 100644 Binary files a/VtoyTool/vtoytool/00/vtoytool_32 and b/VtoyTool/vtoytool/00/vtoytool_32 differ diff --git a/VtoyTool/vtoytool/00/vtoytool_64 b/VtoyTool/vtoytool/00/vtoytool_64 index f9d5cbbe..e0cd79f5 100644 Binary files a/VtoyTool/vtoytool/00/vtoytool_64 and b/VtoyTool/vtoytool/00/vtoytool_64 differ diff --git a/VtoyTool/vtoytool/00/vtoytool_aa64 b/VtoyTool/vtoytool/00/vtoytool_aa64 index fb43c352..c9299604 100644 Binary files a/VtoyTool/vtoytool/00/vtoytool_aa64 and b/VtoyTool/vtoytool/00/vtoytool_aa64 differ diff --git a/VtoyTool/vtoytool/00/vtoytool_m64e b/VtoyTool/vtoytool/00/vtoytool_m64e index 690be305..44b1f991 100644 Binary files a/VtoyTool/vtoytool/00/vtoytool_m64e and b/VtoyTool/vtoytool/00/vtoytool_m64e differ