mirror of
https://github.com/dynup/kpatch
synced 2025-04-23 23:45:21 +00:00
fixup review comments
Signed-off-by: Seth Jennings <sjenning@redhat.com>
This commit is contained in:
parent
4835e3edc3
commit
d4e4d14dbe
@ -341,10 +341,8 @@ static int kpatch_apply_patch(void *data)
|
|||||||
list_for_each_entry(object, &kpmod->objects, list) {
|
list_for_each_entry(object, &kpmod->objects, list) {
|
||||||
if (!kpatch_object_linked(object))
|
if (!kpatch_object_linked(object))
|
||||||
continue;
|
continue;
|
||||||
list_for_each_entry(hook, &object->hooks_load, list) {
|
list_for_each_entry(hook, &object->hooks_load, list)
|
||||||
/* TODO: ignoring return code for now */
|
|
||||||
(*hook->hook)();
|
(*hook->hook)();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -380,10 +378,8 @@ static int kpatch_remove_patch(void *data)
|
|||||||
list_for_each_entry(object, &kpmod->objects, list) {
|
list_for_each_entry(object, &kpmod->objects, list) {
|
||||||
if (!kpatch_object_linked(object))
|
if (!kpatch_object_linked(object))
|
||||||
continue;
|
continue;
|
||||||
list_for_each_entry(hook, &object->hooks_unload, list) {
|
list_for_each_entry(hook, &object->hooks_unload, list)
|
||||||
/* TODO: ignoring return code for now */
|
|
||||||
(*hook->hook)();
|
(*hook->hook)();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -745,6 +741,7 @@ static int kpatch_module_notify(struct notifier_block *nb, unsigned long action,
|
|||||||
struct kpatch_module *kpmod;
|
struct kpatch_module *kpmod;
|
||||||
struct kpatch_object *object;
|
struct kpatch_object *object;
|
||||||
struct kpatch_func *func;
|
struct kpatch_func *func;
|
||||||
|
struct kpatch_hook *hook;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
@ -775,6 +772,10 @@ done:
|
|||||||
|
|
||||||
pr_notice("patching newly loaded module '%s'\n", object->name);
|
pr_notice("patching newly loaded module '%s'\n", object->name);
|
||||||
|
|
||||||
|
/* run any user-defined load hooks */
|
||||||
|
list_for_each_entry(hook, &object->hooks_load, list)
|
||||||
|
(*hook->hook)();
|
||||||
|
|
||||||
/* add to the global func hash */
|
/* add to the global func hash */
|
||||||
list_for_each_entry(func, &object->funcs, list)
|
list_for_each_entry(func, &object->funcs, list)
|
||||||
hash_add_rcu(kpatch_func_hash, &func->node, func->old_addr);
|
hash_add_rcu(kpatch_func_hash, &func->node, func->old_addr);
|
||||||
|
@ -59,7 +59,7 @@ struct kpatch_dynrela {
|
|||||||
|
|
||||||
struct kpatch_hook {
|
struct kpatch_hook {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
int (*hook)(void);
|
void (*hook)(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct kpatch_object {
|
struct kpatch_object {
|
||||||
|
54
kmod/patch/kpatch-macros.h
Normal file
54
kmod/patch/kpatch-macros.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#ifndef __KPATCH_MACROS_H_
|
||||||
|
#define __KPATCH_MACROS_H_
|
||||||
|
|
||||||
|
#include <linux/compiler.h>
|
||||||
|
|
||||||
|
typedef void (*kpatch_loadcall_t)(void);
|
||||||
|
typedef void (*kpatch_unloadcall_t)(void);
|
||||||
|
|
||||||
|
struct kpatch_load {
|
||||||
|
kpatch_loadcall_t fn;
|
||||||
|
char *objname; /* filled in by create-diff-object */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct kpatch_unload {
|
||||||
|
kpatch_unloadcall_t fn;
|
||||||
|
char *objname; /* filled in by create-diff-object */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* KPATCH_LOAD_HOOK macro
|
||||||
|
*
|
||||||
|
* The first line only ensures that the hook being registered has the required
|
||||||
|
* function signature. If not, there is compile error on this line.
|
||||||
|
*
|
||||||
|
* The section line declares a struct kpatch_load to be allocated in a new
|
||||||
|
* .kpatch.hook.load section. This kpatch_load_data symbol is later stripped
|
||||||
|
* by create-diff-object so that it can be declared in multiple objects that
|
||||||
|
* are later linked together, avoiding global symbol collision. Since multiple
|
||||||
|
* hooks can be registered, the .kpatch.hook.load section is a table of struct
|
||||||
|
* kpatch_load elements that will be executed in series by the kpatch core
|
||||||
|
* module at load time, assuming the kernel object (module) is currently
|
||||||
|
* loaded; otherwise, the hook is called when module to be patched is loaded
|
||||||
|
* via the module load notifier.
|
||||||
|
*/
|
||||||
|
#define KPATCH_LOAD_HOOK(_fn) \
|
||||||
|
static inline kpatch_loadcall_t __loadtest(void) { return _fn; } \
|
||||||
|
struct kpatch_load kpatch_load_data __section(.kpatch.hooks.load) = { \
|
||||||
|
.fn = _fn, \
|
||||||
|
.objname = NULL \
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* KPATCH_UNLOAD_HOOK
|
||||||
|
*
|
||||||
|
* Same as LOAD hook with s/load/unload/
|
||||||
|
*/
|
||||||
|
#define KPATCH_UNLOAD_HOOK(_fn) \
|
||||||
|
static inline kpatch_unloadcall_t __unloadtest(void) { return _fn; } \
|
||||||
|
struct kpatch_unload kpatch_unload_data __section(.kpatch.hooks.unload) = { \
|
||||||
|
.fn = _fn, \
|
||||||
|
.objname = NULL \
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __KPATCH_HOOKS_H_ */
|
@ -42,7 +42,7 @@ struct kpatch_patch_dynrela {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct kpatch_patch_hook {
|
struct kpatch_patch_hook {
|
||||||
int (*hook)(void);
|
void (*hook)(void);
|
||||||
char *objname;
|
char *objname;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8,6 +8,13 @@ SECTIONS
|
|||||||
__kpatch_hooks_load = . ;
|
__kpatch_hooks_load = . ;
|
||||||
*(.kpatch.hooks.load)
|
*(.kpatch.hooks.load)
|
||||||
__kpatch_hooks_load_end = . ;
|
__kpatch_hooks_load_end = . ;
|
||||||
|
/*
|
||||||
|
* Pad the end of the section with zeros in case the section is empty.
|
||||||
|
* This prevents the kernel from discarding the section at module
|
||||||
|
* load time. __kpatch_hooks_load_end will still point to the end of
|
||||||
|
* the section before the padding. If the .kpatch.hooks.load section
|
||||||
|
* is empty, __kpatch_hooks_load equals __kpatch_hooks_load_end.
|
||||||
|
*/
|
||||||
QUAD(0);
|
QUAD(0);
|
||||||
}
|
}
|
||||||
.kpatch.hooks.unload : {
|
.kpatch.hooks.unload : {
|
||||||
|
@ -1069,7 +1069,6 @@ int is_null_sym(struct symbol *sym)
|
|||||||
|
|
||||||
int is_file_sym(struct symbol *sym)
|
int is_file_sym(struct symbol *sym)
|
||||||
{
|
{
|
||||||
log_debug("here!");
|
|
||||||
return sym->type == STT_FILE;
|
return sym->type == STT_FILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,6 +75,7 @@ cleanup() {
|
|||||||
[[ -e $TEMPDIR/.config ]] && cp -f $TEMPDIR/.config $USERSRCDIR
|
[[ -e $TEMPDIR/.config ]] && cp -f $TEMPDIR/.config $USERSRCDIR
|
||||||
fi
|
fi
|
||||||
[[ "$DEBUG" -eq 0 ]] && rm -rf "$TEMPDIR"
|
[[ "$DEBUG" -eq 0 ]] && rm -rf "$TEMPDIR"
|
||||||
|
unset KCFLAGS
|
||||||
}
|
}
|
||||||
|
|
||||||
clean_cache() {
|
clean_cache() {
|
||||||
@ -341,12 +342,12 @@ echo "Testing patch file"
|
|||||||
cd "$SRCDIR" || die
|
cd "$SRCDIR" || die
|
||||||
patch -N -p1 --dry-run < "$PATCHFILE" || die "source patch file failed to apply"
|
patch -N -p1 --dry-run < "$PATCHFILE" || die "source patch file failed to apply"
|
||||||
cp "$PATCHFILE" "$APPLIEDPATCHFILE" || die
|
cp "$PATCHFILE" "$APPLIEDPATCHFILE" || die
|
||||||
cp "$SCRIPTDIR/kpatch-hooks.h" "$SRCDIR/include/linux"
|
cp -LR "$DATADIR/patch" "$TEMPDIR" || die
|
||||||
|
export KCFLAGS="-I$DATADIR/patch" # for kpatch-macros.h
|
||||||
|
|
||||||
echo "Building original kernel"
|
echo "Building original kernel"
|
||||||
make mrproper >> "$LOGFILE" 2>&1 || die
|
make mrproper >> "$LOGFILE" 2>&1 || die
|
||||||
make "-j$CPUS" $TARGETS "O=$OBJDIR" >> "$LOGFILE" 2>&1 || die
|
make "-j$CPUS" $TARGETS "O=$OBJDIR" >> "$LOGFILE" 2>&1 || die
|
||||||
cp -LR "$DATADIR/patch" "$TEMPDIR" || die
|
|
||||||
|
|
||||||
echo "Building patched kernel"
|
echo "Building patched kernel"
|
||||||
patch -N -p1 < "$APPLIEDPATCHFILE" >> "$LOGFILE" 2>&1 || die
|
patch -N -p1 < "$APPLIEDPATCHFILE" >> "$LOGFILE" 2>&1 || die
|
||||||
@ -377,8 +378,9 @@ rm -rf "$OBJDIR2"
|
|||||||
mkdir -p "$OBJDIR2"
|
mkdir -p "$OBJDIR2"
|
||||||
cp "$OBJDIR/.config" "$OBJDIR2" || die
|
cp "$OBJDIR/.config" "$OBJDIR2" || die
|
||||||
mkdir "$TEMPDIR/patched"
|
mkdir "$TEMPDIR/patched"
|
||||||
|
export KCFLAGS="$KCFLAGS -ffunction-sections -fdata-sections"
|
||||||
for i in $(cat $TEMPDIR/changed_objs); do
|
for i in $(cat $TEMPDIR/changed_objs); do
|
||||||
KCFLAGS="-ffunction-sections -fdata-sections" make "$i" "O=$OBJDIR2" >> "$LOGFILE" 2>&1 || die
|
make "$i" "O=$OBJDIR2" >> "$LOGFILE" 2>&1 || die
|
||||||
mkdir -p "$TEMPDIR/patched/$(dirname $i)"
|
mkdir -p "$TEMPDIR/patched/$(dirname $i)"
|
||||||
cp -f "$OBJDIR2/$i" "$TEMPDIR/patched/$i" || die
|
cp -f "$OBJDIR2/$i" "$TEMPDIR/patched/$i" || die
|
||||||
done
|
done
|
||||||
@ -387,7 +389,7 @@ rm -f "$APPLIEDPATCHFILE"
|
|||||||
mkdir "$TEMPDIR/orig"
|
mkdir "$TEMPDIR/orig"
|
||||||
for i in $(cat $TEMPDIR/changed_objs); do
|
for i in $(cat $TEMPDIR/changed_objs); do
|
||||||
rm -f "$i"
|
rm -f "$i"
|
||||||
KCFLAGS="-ffunction-sections -fdata-sections" make "$i" "O=$OBJDIR2" >> "$LOGFILE" 2>&1 || die
|
make "$i" "O=$OBJDIR2" >> "$LOGFILE" 2>&1 || die
|
||||||
mkdir -p "$TEMPDIR/orig/$(dirname $i)"
|
mkdir -p "$TEMPDIR/orig/$(dirname $i)"
|
||||||
cp -f "$OBJDIR2/$i" "$TEMPDIR/orig/$i" || die
|
cp -f "$OBJDIR2/$i" "$TEMPDIR/orig/$i" || die
|
||||||
done
|
done
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
#ifndef __KPATCH_HOOKS_H_
|
|
||||||
#define __KPATCH_HOOKS_H_
|
|
||||||
|
|
||||||
#include <linux/compiler.h>
|
|
||||||
|
|
||||||
typedef int (*kpatch_loadcall_t)(void);
|
|
||||||
typedef int (*kpatch_unloadcall_t)(void);
|
|
||||||
|
|
||||||
struct kpatch_load {
|
|
||||||
kpatch_loadcall_t fn;
|
|
||||||
char *objname; /* filled in by create-diff-object */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct kpatch_unload {
|
|
||||||
kpatch_unloadcall_t fn;
|
|
||||||
char *objname; /* filled in by create-diff-object */
|
|
||||||
};
|
|
||||||
|
|
||||||
#define kpatch_load_hook(_fn) \
|
|
||||||
static inline kpatch_loadcall_t __loadtest(void) { return _fn; } \
|
|
||||||
struct kpatch_load kpatch_load_data __section(.kpatch.hooks.load) = { \
|
|
||||||
.fn = _fn, \
|
|
||||||
.objname = NULL \
|
|
||||||
};
|
|
||||||
|
|
||||||
#define kpatch_unload_hook(_fn) \
|
|
||||||
static inline kpatch_unloadcall_t __unloadtest(void) { return _fn; } \
|
|
||||||
struct kpatch_unload kpatch_unload_data __section(.kpatch.hooks.unload) = { \
|
|
||||||
.fn = _fn, \
|
|
||||||
.objname = NULL \
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* __KPATCH_HOOKS_H_ */
|
|
Loading…
Reference in New Issue
Block a user