adapt kpatch to 6.6 kernel and fix bundle symbols change

This commit is contained in:
caixiaomeng 2024-04-30 19:01:07 +08:00
parent fbe43abb35
commit b3f9ce4d4d
4 changed files with 320 additions and 1 deletions

View File

@ -0,0 +1,241 @@
From 333898fba5408004adba899ce67c85707aa83574 Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Tue, 30 Apr 2024 16:38:03 +0800
Subject: [PATCH] adapt kpatch to 6.6 kernel and fix bundle symbols change
---
kpatch-build/create-diff-object.c | 4 +-
kpatch-build/kpatch-build | 70 ++++++++++++++++++++++++++-----
kpatch-build/kpatch-cc | 3 +-
3 files changed, 64 insertions(+), 13 deletions(-)
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
index d50d745..5de19f4 100644
--- a/kpatch-build/create-diff-object.c
+++ b/kpatch-build/create-diff-object.c
@@ -241,6 +241,7 @@ static void kpatch_bundle_symbols(struct kpatch_elf *kelf)
{
struct symbol *sym;
unsigned int expected_offset;
+ unsigned int directcall_offset = 16;
list_for_each_entry(sym, &kelf->symbols, list) {
if (is_bundleable(sym)) {
@@ -251,7 +252,8 @@ static void kpatch_bundle_symbols(struct kpatch_elf *kelf)
else
expected_offset = 0;
- if (sym->sym.st_value != expected_offset) {
+ if (sym->sym.st_value != expected_offset &&
+ !(getenv("CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS") && sym->sym.st_value == directcall_offset)) {
ERROR("symbol %s at offset %lu within section %s, expected %u",
sym->name, sym->sym.st_value,
sym->sec->name, expected_offset);
diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build
index 5817023..8fbe8da 100755
--- a/kpatch-build/kpatch-build
+++ b/kpatch-build/kpatch-build
@@ -142,7 +142,6 @@ verify_patch_files() {
apply_patches() {
local patch
-
for patch in "${PATCH_LIST[@]}"; do
patch -N -p1 --dry-run < "$patch" 2>&1 | logger || die "$patch file failed to apply"
patch -N -p1 < "$patch" 2>&1 | logger || die "$patch file failed to apply"
@@ -157,12 +156,12 @@ remove_patches() {
for (( ; APPLIED_PATCHES>0; APPLIED_PATCHES-- )); do
idx=$(( APPLIED_PATCHES - 1))
patch="${PATCH_LIST[$idx]}"
- patch -p1 -R -d "$BUILDDIR" < "$patch" &> /dev/null
+ patch -p1 -R -d "$USERSRCDIR" < "$patch" &> /dev/null
done
# If $BUILDDIR was a git repo, make sure git actually sees that
# we've reverted our patch(es).
- [[ -d "$BUILDDIR/.git" ]] && (cd "$BUILDDIR" && git update-index -q --refresh)
+ [[ -d "$USERSRCDIR/.git" ]] && (cd "$USERSRCDIR" && git update-index -q --refresh)
}
cleanup() {
@@ -452,6 +451,8 @@ relpath() {
filedir="$(dirname "$(readlink -f "$file")")"
common="$(readlink -f "$dir")"
+ [[ $filedir == '.' ]] && return
+
if [[ "$filedir" = "$common" ]]; then
basename "$file"
return
@@ -539,6 +540,36 @@ __find_parent_obj_in_dir() {
get_parent_from_parents "${parents[@]}"
}
+
+__find_parent_obj_in_dir_for_oot() {
+ local file="$1"
+ local dir="$2"
+
+ declare -a parents
+
+ while IFS='' read -r parent; do
+ parent="$(cmd_file_to_o_file "$parent")"
+ [[ $parent -ef $dir/$file ]] && continue
+ parents+=("$parent")
+ done < <(grep -El "${file/./\\.}([ \)]|$)" "$dir"/.*.cmd)
+
+ if [ ${#parents[@]} -ne 0 ]; then
+ get_parent_from_parents "${parents[@]}"
+ return
+ fi
+ # if path startswith @, should read from file
+ while IFS='' read -r parent; do
+ parent="${parent#@}"
+ parent= `cat "${parent}"`|| die
+ parent="$(cmd_file_to_o_file "$parent")"
+ [[ $parent -ef $dir/$file ]] && continue
+ parents+=("$parent")
+ done < <(grep -ohE '@.*\.mod' "$dir"/.*.cmd)
+
+ get_parent_from_parents "${parents[@]}"
+}
+
+
find_parent_obj_in_dir() {
local file="$1"
local dir="$2"
@@ -553,6 +584,12 @@ find_parent_obj_in_dir() {
__find_parent_obj_in_dir "$(relpath "$file" "$dir")" "$dir"
[[ -n $PARENT ]] && return
+ __find_parent_obj_in_dir_for_oot "$file" "."
+ [[ -n $PARENT ]] && return
+
+ __find_parent_obj_in_dir_for_oot "$file" "${dir#`pwd`}"
+ [[ -n $PARENT ]] && return
+
# pre-5.19 (and 5.19+ single-object modules):
if [[ $file == $dir* ]]; then
# arch/x86/kernel/smp.o
@@ -561,6 +598,7 @@ find_parent_obj_in_dir() {
# drivers/gpu/drm/amd/amdgpu/../acp/acp_hw.o
__find_parent_obj_in_dir "$dir"/"$(relpath "$file" "$dir")" "$dir"
fi
+
}
find_parent_obj() {
@@ -623,7 +661,7 @@ find_parent_obj() {
find_kobj() {
local file="$1"
- if [[ -n $OOT_MODULE ]]; then
+ if [[ -n $OOT_MODULE && $OOT_MODULE != yes ]]; then
KOBJFILE="$OOT_MODULE"
return
fi
@@ -1142,6 +1180,8 @@ else
KBUILD_EXTRA_SYMBOLS="$SYMVERSFILE"
fi
+grep -q "CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=y" "$CONFIGFILE" && export CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=1
+
# unsupported kernel option checking
[[ -n "$CONFIG_DEBUG_INFO_SPLIT" ]] && die "kernel option 'CONFIG_DEBUG_INFO_SPLIT' not supported"
[[ -n "$CONFIG_GCC_PLUGIN_LATENT_ENTROPY" ]] && die "kernel option 'CONFIG_GCC_PLUGIN_LATENT_ENTROPY' not supported"
@@ -1153,11 +1193,11 @@ fi
# that anyway.
if [[ -n "$CONFIG_DEBUG_INFO_BTF" ]] && [[ -z "$OOT_MODULE" ]] ; then
cp -f "$KERNEL_SRCDIR/scripts/link-vmlinux.sh" "$TEMPDIR/link-vmlinux.sh" || die
- sed -i 's/CONFIG_DEBUG_INFO_BTF/DISABLED_FOR_KPATCH_BUILD/g' "$KERNEL_SRCDIR"/scripts/link-vmlinux.sh || die
+ #sed -i 's/CONFIG_DEBUG_INFO_BTF/DISABLED_FOR_KPATCH_BUILD/g' "$KERNEL_SRCDIR"/scripts/link-vmlinux.sh || die
if [[ -e "$KERNEL_SRCDIR/scripts/Makefile.modfinal" ]]; then
cp -f "$KERNEL_SRCDIR/scripts/Makefile.modfinal" "$TEMPDIR/Makefile.modfinal" || die
- sed -i 's/CONFIG_DEBUG_INFO_BTF_MODULES/DISABLED_FOR_KPATCH_BUILD/g' "$KERNEL_SRCDIR"/scripts/Makefile.modfinal || die
+ #sed -i 's/CONFIG_DEBUG_INFO_BTF_MODULES/DISABLED_FOR_KPATCH_BUILD/g' "$KERNEL_SRCDIR"/scripts/Makefile.modfinal || die
fi
fi
@@ -1179,7 +1219,7 @@ if [[ "$SKIPCOMPILERCHECK" -eq 0 ]]; then
fi
echo "Testing patch file(s)"
-cd "$BUILDDIR" || die
+cd "$USERSRCDIR" || die
verify_patch_files
apply_patches
remove_patches
@@ -1239,11 +1279,12 @@ if [[ "$OOT_MODULE" != "yes" ]]; then
cp -f "$BUILDDIR/Module.symvers" "$TEMPDIR/Module.symvers" || die
fi
+cd "$USERSRCDIR" || die
echo "Building patched source"
apply_patches
mkdir -p "$TEMPDIR/orig" "$TEMPDIR/patched"
export KPATCH_GCC_TEMPDIR="$TEMPDIR"
-export KPATCH_GCC_SRCDIR="$BUILDDIR"
+export KPATCH_GCC_SRCDIR="$USERSRCDIR"
save_env
# $TARGETS used as list, no quotes.
# shellcheck disable=SC2086
@@ -1265,7 +1306,7 @@ if [[ ! -e "$TEMPDIR/changed_objs" ]]; then
die "no changed objects found"
fi
-grep -q vmlinux "$KERNEL_SRCDIR/Module.symvers" || die "truncated $KERNEL_SRCDIR/Module.symvers file"
+[[ -n "$OOT_MODULE" ]] || grep -q vmlinux "$KERNEL_SRCDIR/Module.symvers" || die "truncated $KERNEL_SRCDIR/Module.symvers file"
if [[ -n "$CONFIG_MODVERSIONS" ]] && [[ "$OOT_MODULE" != "yes" ]]; then
trace_off "reading Module.symvers"
@@ -1350,7 +1391,7 @@ for i in $FILES; do
[[ "$i" = usr/initramfs_data.o ]] && continue
mkdir -p "output/$(dirname "$i")"
- cd "$BUILDDIR" || die
+ cd "$USERSRCDIR" || die
find_kobj "$i"
cd "$TEMPDIR" || die
if [[ -e "orig/$i" ]]; then
@@ -1381,6 +1422,7 @@ for i in $FILES; do
KBUILD_MODPOST_WARN=1 make -C "$USERMODBUILDDIR" M="$USERMODBUILDDIR" $USERMODFLAGS "-j$CPUS" $TARGETS 2>&1 | logger || die
fi
cp ${KOBJFILE} ${KOBJFILE_PATH}
+ cd "$USERSRCDIR" || die
apply_patches
cd "$TEMPDIR" || die
@@ -1488,7 +1530,13 @@ for ((idx=0; idx<${#MAKEVARS[@]}; idx++)); do
MAKEVARS[$idx]=${MAKEVARS[$idx]/${KPATCH_CC_PREFIX}/}
done
-export KPATCH_BUILD="$KERNEL_SRCDIR" KPATCH_NAME="$MODNAME" \
+if [[ -z "$OOT_MODULE" ]]; then
+ KPATCH_BUILD="$KERNEL_SRCDIR"
+else
+ KPATCH_BUILD="/lib/modules/$ARCHVERSION/build"
+fi
+
+export KPATCH_BUILD="$KPATCH_BUILD" KPATCH_NAME="$MODNAME" \
KBUILD_EXTRA_SYMBOLS="$KBUILD_EXTRA_SYMBOLS" \
KPATCH_LDFLAGS="$KPATCH_LDFLAGS" \
CROSS_COMPILE="$CROSS_COMPILE"
diff --git a/kpatch-build/kpatch-cc b/kpatch-build/kpatch-cc
index 8f22978..6f14fd1 100755
--- a/kpatch-build/kpatch-cc
+++ b/kpatch-build/kpatch-cc
@@ -53,7 +53,8 @@ if [[ "$TOOLCHAINCMD" =~ ^(.*-)?gcc$ ||
lib/*|\
tools/*|\
.*.o|\
- */.lib_exports.o)
+ */.lib_exports.o|\
+ drivers/net/ethernet/3snic/sssnic/*)
break
;;
*.o)
--
2.33.0

View File

@ -0,0 +1,36 @@
From ecaa5aa05434d47ce529b8cc2a1693a88bd6edb0 Mon Sep 17 00:00:00 2001
From: hubin <hubin73@huawei.com>
Date: Sun, 18 Feb 2024 19:42:53 +0800
Subject: [PATCH] fix function ptr relocation
When option CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS is enabled, each function
is added 5 NOP padding before function entry.
---
kpatch-build/create-diff-object.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
index cf5ff95..d5126f8 100644
--- a/kpatch-build/create-diff-object.c
+++ b/kpatch-build/create-diff-object.c
@@ -3271,10 +3271,15 @@ static int kpatch_is_core_module_symbol(char *name)
static int function_ptr_rela(const struct rela *rela)
{
const struct rela *rela_toc = toc_rela(rela);
+ int entry_offset = 0;
+
+ if (getenv("CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS"))
+ entry_offset = 20;
return (rela_toc && rela_toc->sym->type == STT_FUNC &&
!rela_toc->sym->parent &&
- rela_toc->addend == (int)rela_toc->sym->sym.st_value &&
+ (rela_toc->addend == (int)rela_toc->sym->sym.st_value ||
+ rela_toc->addend == (int)rela_toc->sym->sym.st_value - entry_offset) &&
(rela->type == R_X86_64_32S ||
rela->type == R_PPC64_TOC16_HA ||
rela->type == R_PPC64_TOC16_LO_DS ||
--
2.33.0

View File

@ -0,0 +1,32 @@
From c0a0955cfe04f9cd536f57d0866683fd88894576 Mon Sep 17 00:00:00 2001
From: hubin <hubin73@huawei.com>
Date: Tue, 5 Mar 2024 10:15:59 +0800
Subject: [PATCH] lookup.c: ignore BTF ID when matching locals
BTF info may not be enabled when compiling kernel in compile env,
but exist in vmlinux symtab, which causes
kpatch unable to find matching local symbols
---
kpatch-build/lookup.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/kpatch-build/lookup.c b/kpatch-build/lookup.c
index 458b447..2fe1fd0 100644
--- a/kpatch-build/lookup.c
+++ b/kpatch-build/lookup.c
@@ -107,6 +107,11 @@ static bool locals_match(struct lookup_table *table, int idx,
continue;
if (table_sym->type != STT_FUNC && table_sym->type != STT_OBJECT)
continue;
+ /*
+ * BTF info may not be enabled when compiling kernel, but exists in vmlinux symtab
+ */
+ if (!strncmp(table_sym->name, "__BTF_ID__", 10))
+ continue;
found = 0;
sym = file_sym;
--
2.33.0

View File

@ -1,7 +1,7 @@
Name: kpatch
Epoch: 1
Version: 0.9.9
Release: 3
Release: 4
Summary: A Linux dynamic kernel patching infrastructure
License: GPLv2
@ -53,6 +53,10 @@ Patch0037:0037-add-initial-riscv64-support.patch
Patch0038:0038-Fix-undefined-behavior-problem-when-using-list_forea.patch
Patch0039:0039-build-support-for-building-with-clang.patch
Patch9001:huawei-fix-function-ptr-relocation.patch
Patch9002:huawei-lookup.c-ignore-BTF-ID-when-matching-locals.patch
Patch9003:huawei-adapt-kpatch-to-6.6-kernel-and-fix-bundle-symbols-ch.patch
BuildRequires: gcc elfutils-libelf-devel kernel-devel git
%ifarch ppc64le
BuildRequires: gcc-plugin-devel
@ -115,6 +119,12 @@ popd
%{_mandir}/man1/*.1.gz
%changelog
* Tue Apr 30 2024 caixiaomeng <caixiaomeng2@huawei.com> - 1:0.9.9-4
- Type: bugfix
- CVE:NA
- SUG:NA
- DESC:adapt kpatch to 6.6 kernel and fix bundle symbols change
* Wed Mar 13 2024 luofng <luofeng13@huawei.com> - 1:0.9.9-3
- Type: enhencement
- CVE:NA