Fix the VTOY_LINUX_REMOUNT option for new linux kernel in intel 11th(and later) gen CPU.

This commit is contained in:
longpanda 2023-03-26 10:45:19 +08:00
parent e743f7c15f
commit b32eda4262
12 changed files with 277 additions and 9 deletions

7
DMPATCH/Makefile_IBT Normal file
View File

@ -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

View File

@ -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);

65
DMPATCH/ubuntu_build.sh Normal file
View File

@ -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

View File

@ -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

Binary file not shown.

View File

@ -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

View File

@ -24,6 +24,9 @@
#include <string.h>
#include <errno.h>
#include <unistd.h>
#ifdef VTOY_X86_64
#include <cpuid.h>
#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;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.