--- /dev/null
+
+obj-m += dm_patch_ibt.o
+
+EXTRA_CFLAGS := -Wall -DVTOY_IBT -fcf-protection=branch -mindirect-branch-register
+
+dm_patch_ibt-objs := dmpatch.o
+
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()
#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 };
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);
vdebug("######## dm patch success ###########\n");
vdebug("#####################################\n");
+ if (g_ko_param.ibt == 0x8888)
+ {
+ dmpatch_ibt_restore(msr);
+ }
+
out:
return rc;
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++)
{
}
vdebug("dmpatch_exit success\n");
+
+ if (g_ko_param.ibt == 0x8888)
+ {
+ dmpatch_ibt_restore(msr);
+ }
}
module_init(dmpatch_init);
--- /dev/null
+#!/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
+
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
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
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
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
#include <string.h>
#include <errno.h>
#include <unistd.h>
+#ifdef VTOY_X86_64
+#include <cpuid.h>
+#endif
#define _ull unsigned long long
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()
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]);
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;
}
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;
{
return vtoykmod_update(argv[2], argv[3]);
}
+ else if (argv[1][0] == '-' && argv[1][1] == 'I')
+ {
+ return vtoykmod_check_ibt();
+ }
return 0;
}