mirror of
https://github.com/dynup/kpatch
synced 2025-01-10 23:29:24 +00:00
kpatch-build: use original vmlinux
There's at least one case in the kernel (ddebug_proc_show) where the compiled instructions are affected by the source file path given to gcc. Which means that compiling the kernel with O= will result in many of the function addresses changing. This causes a mismatch between the locally compiled vmlinux and the original vmlinux, which is very dangerous, since we need the addresses to be correct. The easy fix is just to use the original vmlinux for all the function addresses. Other potential ways to fix it which we might want to consider in the future: - use a combination of the old System.map and the new vmlinux to find the addresses. The function ordering should be the same. For non-duplicate symbols, use System.map. For duplicate symbols, use vmlinux to find what order the symbol comes in. e.g. the 2nd occurrence of foo() in System.map. It adds a little complexity to the lookup code, but seems safe and wouldn't require the kernel debuginfo package. However, this may not help us for patching modules. - do something similar at runtime, i.e. use kallsyms_lookup_name for non-dups and kallsyms_on_each_symbol for dups, and look for the nth occurrence of the symbol (value of n is decided at build time). This has the complexity of the previous option but it's done at runtime rather than build time, so... why? Doing it at build time is better. - compile the kernel in place. This basically means no more caching because recompiling with --function-sections causes everything to be recompiled again. This is bad for kpatch developers' SSDs...
This commit is contained in:
parent
bf4be47e62
commit
5c98ec65a0
@ -31,6 +31,7 @@ Install the dependencies for the "kpatch-build" command:
|
||||
|
||||
sudo yum install rpmdevtools pesign yum-utils
|
||||
sudo yum-builddep kernel
|
||||
sudo debuginfo-install kernel
|
||||
|
||||
# optional, but highly recommended
|
||||
sudo yum install ccache
|
||||
|
@ -88,6 +88,7 @@ usage() {
|
||||
echo " -r, --sourcerpm Specify kernel source RPM" >&2
|
||||
echo " -s, --sourcedir Specify kernel source directory" >&2
|
||||
echo " -c, --config Specify kernel config file" >&2
|
||||
echo " -v, --vmlinux Specify original vmlinux" >&2
|
||||
echo " -d, --debug Keep scratch files in /tmp" >&2
|
||||
}
|
||||
|
||||
@ -119,6 +120,11 @@ while [[ $# -gt 0 ]]; do
|
||||
shift
|
||||
[[ ! -f "$CONFIGFILE" ]] && die "config file $CONFIGFILE not found"
|
||||
;;
|
||||
-v|--vmlinux)
|
||||
VMLINUX=$(readlink -f "$2")
|
||||
shift
|
||||
[[ ! -f "$VMLINUX" ]] && die "vmlinux file $VMLINUX not found"
|
||||
;;
|
||||
-d|--debug)
|
||||
echo "DEBUG mode enabled"
|
||||
DEBUG=1
|
||||
@ -158,6 +164,9 @@ find_dirs || die "can't find supporting tools"
|
||||
|
||||
[[ -e "$SYMVERSFILE" ]] || die "can't find core module Module.symvers"
|
||||
|
||||
[[ -z $VMLINUX ]] && VMLINUX=/usr/lib/debug/lib/modules/${ARCHVERSION}/vmlinux
|
||||
[[ -e "$VMLINUX" ]] || die "kernel-debuginfo not installed"
|
||||
|
||||
if [[ -n "$USERSRCDIR" ]]; then
|
||||
SRCDIR="$CACHEDIR/src"
|
||||
OBJDIR="$CACHEDIR/obj"
|
||||
@ -209,6 +218,7 @@ else
|
||||
elif [[ $ID = ubuntu ]]; then
|
||||
|
||||
echo "Debian/Ubuntu distribution detected"
|
||||
|
||||
cd $TEMPDIR
|
||||
echo "Downloading and unpacking kernel source for $ARCHVERSION"
|
||||
apt-get source linux || die "'apt-get source linux' failed. you may need to run 'apt-get install dpkg-dev'"
|
||||
@ -234,7 +244,6 @@ echo "Building original kernel"
|
||||
make mrproper >> "$LOGFILE" 2>&1 || die
|
||||
make "-j$CPUS" vmlinux "O=$OBJDIR" >> "$LOGFILE" 2>&1 || die
|
||||
cp -LR "$DATADIR/patch" "$TEMPDIR" || die
|
||||
cp "$OBJDIR/vmlinux" "$TEMPDIR" || die
|
||||
|
||||
echo "Building patched kernel"
|
||||
patch -N -p1 < "$APPLIEDPATCHFILE" >> "$LOGFILE" 2>&1 || die
|
||||
@ -286,10 +295,10 @@ make prepare >> "$LOGFILE" 2>&1 || die
|
||||
cd "$TEMPDIR/output"
|
||||
ld -r -o ../patch/output.o $FILES >> "$LOGFILE" 2>&1 || die
|
||||
cd "$TEMPDIR/patch"
|
||||
"$TOOLSDIR"/add-patches-section output.o ../vmlinux >> "$LOGFILE" 2>&1 || die
|
||||
"$TOOLSDIR"/add-patches-section output.o "$VMLINUX" >> "$LOGFILE" 2>&1 || die
|
||||
KPATCH_BUILD="$SRCDIR" KPATCH_NAME="$PATCHNAME" KBUILD_EXTRA_SYMBOLS="$SYMVERSFILE" make "O=$OBJDIR" >> "$LOGFILE" 2>&1 || die
|
||||
$STRIPCMD "kpatch-$PATCHNAME.ko" >> "$LOGFILE" 2>&1 || die
|
||||
"$TOOLSDIR"/link-vmlinux-syms "kpatch-$PATCHNAME.ko" ../vmlinux >> "$LOGFILE" 2>&1 || die
|
||||
"$TOOLSDIR"/link-vmlinux-syms "kpatch-$PATCHNAME.ko" "$VMLINUX" >> "$LOGFILE" 2>&1 || die
|
||||
|
||||
cp -f "$TEMPDIR/patch/kpatch-$PATCHNAME.ko" "$BASE" || die
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user