diff --git a/.gitignore b/.gitignore index 15c459d..e83c90f 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/v0.1.10.tar.gz +SOURCES/v0.3.1.tar.gz diff --git a/.kpatch.metadata b/.kpatch.metadata index d0d6661..ece00c9 100644 --- a/.kpatch.metadata +++ b/.kpatch.metadata @@ -1 +1 @@ -800741ebece68e84d90ab1629c4d134bd7ae0981 SOURCES/v0.1.10.tar.gz +161655be9875b907a6d7a1d2289008810dbccd3d SOURCES/v0.3.1.tar.gz diff --git a/SOURCES/0001-fix-dracut-dependencies.patch b/SOURCES/0001-fix-dracut-dependencies.patch deleted file mode 100644 index c718870..0000000 --- a/SOURCES/0001-fix-dracut-dependencies.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 6cdb5011c59ff19c684428318a028bc0a6bf5ac4 Mon Sep 17 00:00:00 2001 -Message-Id: <6cdb5011c59ff19c684428318a028bc0a6bf5ac4.1417711268.git.jpoimboe@redhat.com> -From: Josh Poimboeuf -Date: Wed, 3 Dec 2014 16:04:04 -0600 -Subject: [PATCH] fix dracut dependencies - -The "kpatch install" command is broken because the kpatch script has -some missing dependencies in the initramfs. Make sure the new -dependencies (readelf and awk) are added to the initramfs. ---- - contrib/module-setup.sh | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/contrib/module-setup.sh b/contrib/module-setup.sh -index 71ec41a..0259b79 100755 ---- a/contrib/module-setup.sh -+++ b/contrib/module-setup.sh -@@ -19,11 +19,11 @@ install() { - # install kpatch script - inst_any -d /usr/sbin/kpatch /usr/local/sbin/kpatch /usr/sbin/kpatch - -- # install insmod (needed by kpatch script) -+ # install kpatch script dependencies - inst_symlink /usr/sbin/insmod -- -- # install dirname (needed by kpatch script) - inst /usr/bin/dirname -+ inst /usr/bin/readelf -+ inst /usr/bin/awk - - # install core module - inst_any -d /usr/lib/modules/$kernel/extra/kpatch/kpatch.ko /usr/local/lib/modules/$kernel/extra/kpatch/kpatch.ko /usr/lib/modules/$kernel/extra/kpatch/kpatch.ko /usr/lib/kpatch/$kernel/kpatch.ko /usr/local/lib/kpatch/$kernel/kpatch.ko --- -1.9.3 - diff --git a/SOURCES/0002-Support-modprobe-style-names-in-kpatch-load.patch b/SOURCES/0002-Support-modprobe-style-names-in-kpatch-load.patch deleted file mode 100644 index cb6373a..0000000 --- a/SOURCES/0002-Support-modprobe-style-names-in-kpatch-load.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 1d63ce84932efda559d6d745930e1b05f446a334 Mon Sep 17 00:00:00 2001 -From: Seth Jennings -Date: Tue, 26 Aug 2014 15:47:07 -0500 -Subject: [PATCH 2/5] Support modprobe style names in kpatch load -To: rhkernel-list@redhat.com - -When the argument is a .ko file, it should be considered a path (i.e. -don't even look for it in the installed DB). When the argument is a -module name, it should be considered a loaded or installed module (and -then in the case of kpatch load we have to do a reverse translation of -all installed modules to see if any of them match). - -Signed-off-by: Seth Jennings ---- - kpatch/kpatch | 25 +++++++++++++++++++++++-- - 1 file changed, 23 insertions(+), 2 deletions(-) - -diff --git a/kpatch/kpatch b/kpatch/kpatch -index 074beeb..1d33641 100755 ---- a/kpatch/kpatch -+++ b/kpatch/kpatch -@@ -73,9 +73,29 @@ __find_module () { - return 1 - } - -+mod_name () { -+ MODNAME="$(basename $1)" -+ MODNAME="${MODNAME%.ko}" -+ MODNAME="${MODNAME//-/_}" -+} -+ - find_module () { - arg="$1" -- __find_module "${arg}" -+ if [[ "$arg" =~ \.ko ]]; then -+ __find_module "$arg" || return 1 -+ mod_name "$MODULE" -+ return -+ else -+ for i in $INSTALLDIR/$(uname -r)/*; do -+ mod_name "$i" -+ if [[ $MODNAME == $arg ]]; then -+ MODULE="$i" -+ return -+ fi -+ done -+ fi -+ -+ return 1 - } - - find_core_module() { -@@ -268,7 +288,8 @@ case "$1" in - [[ -e "$kdir" ]] || continue - for module in $kdir/*; do - [[ -e "$module" ]] || continue -- echo "$(basename $module) ($(basename $kdir))" -+ mod_name "$module" -+ echo "$MODNAME ($(basename $kdir))" - done - done - ;; --- -1.9.3 - diff --git a/SOURCES/0003-Support-modprobe-format-names-in-uninstall.patch b/SOURCES/0003-Support-modprobe-format-names-in-uninstall.patch deleted file mode 100644 index 5918551..0000000 --- a/SOURCES/0003-Support-modprobe-format-names-in-uninstall.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 58134fd4490ebe57840762afef5d095a9a4a9771 Mon Sep 17 00:00:00 2001 -From: Seth Jennings -Date: Wed, 27 Aug 2014 14:30:39 -0500 -Subject: [PATCH 3/5] Support modprobe format names in uninstall -To: rhkernel-list@redhat.com - -Signed-off-by: Seth Jennings ---- - kpatch/kpatch | 18 ++++++++++++++++-- - 1 file changed, 16 insertions(+), 2 deletions(-) - -diff --git a/kpatch/kpatch b/kpatch/kpatch -index 1d33641..1a1b1ac 100755 ---- a/kpatch/kpatch -+++ b/kpatch/kpatch -@@ -264,10 +264,24 @@ case "$1" in - shift - done - -- [[ ! -e $INSTALLDIR/$KVER/"$PATCH" ]] && die "$PATCH is not installed for kernel $KVER" -+ MODULE=$INSTALLDIR/$KVER/"$PATCH" -+ if [[ ! -f "$MODULE" ]]; then -+ mod_name "$PATCH" -+ PATCHNAME=$MODNAME -+ for i in $INSTALLDIR/$KVER/*; do -+ mod_name "$i" -+ if [[ $MODNAME == $PATCHNAME ]]; then -+ MODULE="$i" -+ break -+ fi -+ done -+ fi -+ -+ [[ ! -e $MODULE ]] && die "$PATCH is not installed for kernel $KVER" -+ - - echo "uninstalling $PATCH ($KVER)" -- rm -f $INSTALLDIR/$KVER/"$PATCH" || die "failed to uninstall module $PATCH" -+ rm -f $MODULE || die "failed to uninstall module $PATCH" - if lsinitrd -k $KVER &> /dev/null; then - echo "rebuilding $KVER initramfs" - dracut -f --kver $KVER || die "dracut failed" --- -1.9.3 - diff --git a/SOURCES/0003-re-enable-patch-modules-with-checksum-matching.patch b/SOURCES/0003-re-enable-patch-modules-with-checksum-matching.patch deleted file mode 100644 index 1a3d64b..0000000 --- a/SOURCES/0003-re-enable-patch-modules-with-checksum-matching.patch +++ /dev/null @@ -1,269 +0,0 @@ -From b0058988c7e57627ae64ace40377de6da4fa14b9 Mon Sep 17 00:00:00 2001 -From: Jessica Yu -Date: Thu, 4 Sep 2014 07:38:17 -0700 -Subject: [PATCH 3/3] re-enable patch modules with checksum matching -To: rhkernel-list@redhat.com - -In order to safely re-enable patch modules, add a special -.kpatch.checksum section containing an md5sum of a patch module's -contents. The contents of this section are exported to sysfs via -patch_init and double checked when kpatch load finds that a module of -the same name is already loaded. - -Conflicts: - kpatch-build/kpatch-build ---- - kmod/core/core.c | 19 ++++++++++++------ - kmod/patch/kpatch-patch-hook.c | 45 ++++++++++++++++++++++++++++-------------- - kmod/patch/kpatch.lds | 1 + - kpatch-build/kpatch-build | 5 ++++- - kpatch/kpatch | 32 ++++++++++++++++++++++++++++++ - 5 files changed, 80 insertions(+), 22 deletions(-) - -diff --git a/kmod/core/core.c b/kmod/core/core.c -index 8c1bb37..bb624a9 100644 ---- a/kmod/core/core.c -+++ b/kmod/core/core.c -@@ -811,12 +811,16 @@ int kpatch_register(struct kpatch_module *kpmod, bool replace) - - down(&kpatch_mutex); - -- kpmod->enabled = false; -+ if (kpmod->enabled) { -+ ret = -EINVAL; -+ goto err_up; -+ } -+ - list_add_tail(&kpmod->list, &kpmod_list); - - if (!try_module_get(kpmod->mod)) { - ret = -ENODEV; -- goto err_up; -+ goto err_list; - } - - list_for_each_entry(object, &kpmod->objects, list) { -@@ -932,8 +936,9 @@ err_unlink: - if (kpatch_object_linked(object)) - kpatch_unlink_object(object); - module_put(kpmod->mod); --err_up: -+err_list: - list_del(&kpmod->list); -+err_up: - up(&kpatch_mutex); - return ret; - } -@@ -945,11 +950,13 @@ int kpatch_unregister(struct kpatch_module *kpmod) - struct kpatch_func *func; - int ret, force = 0; - -- if (!kpmod->enabled) -- return -EINVAL; -- - down(&kpatch_mutex); - -+ if (!kpmod->enabled) { -+ ret = -EINVAL; -+ goto out; -+ } -+ - do_for_each_linked_func(kpmod, func) { - func->op = KPATCH_OP_UNPATCH; - if (func->force) -diff --git a/kmod/patch/kpatch-patch-hook.c b/kmod/patch/kpatch-patch-hook.c -index ea68878..1370223 100644 ---- a/kmod/patch/kpatch-patch-hook.c -+++ b/kmod/patch/kpatch-patch-hook.c -@@ -35,6 +35,7 @@ extern struct kpatch_patch_dynrela __kpatch_dynrelas[], __kpatch_dynrelas_end[]; - extern struct kpatch_patch_hook __kpatch_hooks_load[], __kpatch_hooks_load_end[]; - extern struct kpatch_patch_hook __kpatch_hooks_unload[], __kpatch_hooks_unload_end[]; - extern unsigned long __kpatch_force_funcs[], __kpatch_force_funcs_end[]; -+extern char __kpatch_checksum[]; - - static struct kpatch_module kpmod; - static struct kobject *patch_kobj; -@@ -61,29 +62,43 @@ static ssize_t patch_enabled_store(struct kobject *kobj, - int ret; - unsigned long val; - -- /* only disabling is supported */ -- if (!kpmod.enabled) -- return -EINVAL; -- - ret = kstrtoul(buf, 10, &val); - if (ret) - return ret; - - val = !!val; - -- /* only disabling is supported */ - if (val) -- return -EINVAL; -+ ret = kpatch_register(&kpmod, replace); -+ else -+ ret = kpatch_unregister(&kpmod); - -- ret = kpatch_unregister(&kpmod); - if (ret) - return ret; - - return count; - } - -+static ssize_t checksum_show(struct kobject *kobj, -+ struct kobj_attribute *attr, char *buf) -+{ -+ return snprintf(buf, PAGE_SIZE, "%s\n", __kpatch_checksum); -+} -+ - static struct kobj_attribute patch_enabled_attr = - __ATTR(enabled, 0644, patch_enabled_show, patch_enabled_store); -+static struct kobj_attribute checksum_attr = -+ __ATTR(checksum, 0444, checksum_show, NULL); -+ -+static struct attribute *kpatch_attrs[] = { -+ &patch_enabled_attr.attr, -+ &checksum_attr.attr, -+ NULL, -+}; -+ -+static struct attribute_group kpatch_attr_group = { -+ .attrs = kpatch_attrs, -+}; - - static ssize_t func_old_addr_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -@@ -354,14 +369,10 @@ static int __init patch_init(void) - if (!patch_kobj) - return -ENOMEM; - -- ret = sysfs_create_file(patch_kobj, &patch_enabled_attr.attr); -- if (ret) -- goto err_patch; -- - functions_kobj = kobject_create_and_add("functions", patch_kobj); - if (!functions_kobj) { - ret = -ENOMEM; -- goto err_sysfs; -+ goto err_patch; - } - - kpmod.mod = THIS_MODULE; -@@ -383,13 +394,17 @@ static int __init patch_init(void) - if (ret) - goto err_objects; - -+ ret = sysfs_create_group(patch_kobj, &kpatch_attr_group); -+ if (ret) -+ goto err_sysfs; -+ - return 0; - -+err_sysfs: -+ kpatch_unregister(&kpmod); - err_objects: - patch_free_objects(); - kobject_put(functions_kobj); --err_sysfs: -- sysfs_remove_file(patch_kobj, &patch_enabled_attr.attr); - err_patch: - kobject_put(patch_kobj); - return ret; -@@ -401,7 +416,7 @@ static void __exit patch_exit(void) - - patch_free_objects(); - kobject_put(functions_kobj); -- sysfs_remove_file(patch_kobj, &patch_enabled_attr.attr); -+ sysfs_remove_group(patch_kobj, &kpatch_attr_group); - kobject_put(patch_kobj); - } - -diff --git a/kmod/patch/kpatch.lds b/kmod/patch/kpatch.lds -index 105e5e6..49ae8e7 100644 ---- a/kmod/patch/kpatch.lds -+++ b/kmod/patch/kpatch.lds -@@ -2,6 +2,7 @@ __kpatch_funcs = ADDR(.kpatch.funcs); - __kpatch_funcs_end = ADDR(.kpatch.funcs) + SIZEOF(.kpatch.funcs); - __kpatch_dynrelas = ADDR(.kpatch.dynrelas); - __kpatch_dynrelas_end = ADDR(.kpatch.dynrelas) + SIZEOF(.kpatch.dynrelas); -+__kpatch_checksum = ADDR(.kpatch.checksum); - SECTIONS - { - .kpatch.hooks.load : { -diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build -index 91bf5c2..38466f4 100755 ---- a/kpatch-build/kpatch-build -+++ b/kpatch-build/kpatch-build -@@ -343,7 +343,7 @@ else - url="http://us.archive.ubuntu.com/ubuntu/pool/main/l/linux" - extension="bz2" - sublevel="SUBLEVEL = 0" -- taroptions="xvjf" -+ troptions="xvjf" - - elif [[ $DISTRO = debian ]]; then - -@@ -478,6 +478,9 @@ cd "$SRCDIR" - make prepare >> "$LOGFILE" 2>&1 || die - cd "$TEMPDIR/output" - ld -r -o ../patch/output.o $FILES >> "$LOGFILE" 2>&1 || die -+md5sum ../patch/output.o | awk '{printf "%s\0", $1}' > checksum.tmp || die -+objcopy --add-section .kpatch.checksum=checksum.tmp --set-section-flags .kpatch.checksum=alloc,load,contents,readonly ../patch/output.o || die -+rm -f checksum.tmp - cd "$TEMPDIR/patch" - KPATCH_BUILD="$SRCDIR" KPATCH_NAME="$PATCHNAME" KBUILD_EXTRA_SYMBOLS="$SYMVERSFILE" make "O=$OBJDIR" >> "$LOGFILE" 2>&1 || die - -diff --git a/kpatch/kpatch b/kpatch/kpatch -index 0b932a6..0e36dda 100755 ---- a/kpatch/kpatch -+++ b/kpatch/kpatch -@@ -121,6 +121,21 @@ core_module_loaded () { - grep -q "T kpatch_register" /proc/kallsyms - } - -+get_module_name () { -+ echo $(readelf -p .gnu.linkonce.this_module $1 | grep '\[.*\]' | awk '{print $3}') -+} -+ -+verify_module_checksum () { -+ modname=$(get_module_name $1) -+ [[ -z $modname ]] && return 1 -+ -+ checksum=$(readelf -p .kpatch.checksum $1 | grep '\[.*\]' | awk '{print $3}') -+ [[ -z $checksum ]] && return 1 -+ -+ sysfs_checksum=$(cat /sys/kernel/kpatch/patches/${modname}/checksum) -+ [[ $checksum == $sysfs_checksum ]] || return 1 -+} -+ - load_module () { - if ! core_module_loaded; then - if modprobe -q kpatch; then -@@ -131,6 +146,23 @@ load_module () { - insmod "$COREMOD" || die "failed to load core module" - fi - fi -+ -+ modname=$(get_module_name $1) -+ moddir=/sys/kernel/kpatch/patches/$modname -+ if [[ -d $moddir ]] ; then -+ if [[ $(cat "${moddir}/enabled") -eq 0 ]]; then -+ if verify_module_checksum $1; then # same checksum -+ echo "module already loaded, re-enabling" -+ echo 1 > ${moddir}/enabled || die "failed to re-enable module $modname" -+ return -+ else -+ die "error: cannot re-enable patch module $modname, cannot verify checksum match" -+ fi -+ else -+ die "error: module named $modname already loaded and enabled" -+ fi -+ fi -+ - echo "loading patch module: $1" - insmod "$1" "$2" - } --- -1.9.3 - diff --git a/SPECS/kpatch.spec b/SPECS/kpatch.spec index 01dd32b..ad01061 100644 --- a/SPECS/kpatch.spec +++ b/SPECS/kpatch.spec @@ -1,19 +1,15 @@ Name: kpatch -Version: 0.1.10 -Release: 4%{?dist} +Version: 0.3.1 +Release: 1%{?dist} Summary: Dynamic kernel patch manager Group: System Environment/Kernel License: GPLv2 URL: https://github.com/dynup/kpatch Source0: https://github.com/dynup/kpatch/archive/v%{version}.tar.gz -Patch0: 0002-Support-modprobe-style-names-in-kpatch-load.patch -Patch1: 0003-Support-modprobe-format-names-in-uninstall.patch -Patch2: 0003-re-enable-patch-modules-with-checksum-matching.patch -Patch3: 0001-fix-dracut-dependencies.patch #BuildRequires: -Requires: bash kmod dracut binutils +Requires: bash kmod binutils BuildArch: noarch @@ -26,10 +22,6 @@ patch the kernel without rebooting. %prep %setup -q -%patch0 -p1 -%patch1 -p1 -%patch2 -p1 -%patch3 -p1 %build @@ -45,12 +37,14 @@ rm -f %{buildroot}/usr/share/man/man1/kpatch-build.1.gz %files %{_sbindir}/kpatch -%dir %{_usr}/lib/dracut/modules.d/99kpatch -%{_usr}/lib/dracut/modules.d/99kpatch/* +%{_usr}/lib/systemd/system/kpatch.service %doc %{_mandir}/man1/kpatch.1.gz %changelog +* Wed Nov 18 2015 Josh Poimboeuf 0.3.1-1 +- update to 0.3.1 (rhbz#1282508) + * Tue Sep 16 2014 Seth Jennings 0.1.10-4 - fix dracut dependencies (rhbz#1170369)