Skip to content
This repository has been archived by the owner on Jul 16, 2024. It is now read-only.

Livepatch backporting from Openeuler-kernel #141

Open
wants to merge 52 commits into
base: linux-5.10.y
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
2ac5206
livepatch/core: Allow implementation without ftrace
May 29, 2021
2538132
livepatch/core: Restrict livepatch patched/unpatched when plant kprobe
May 29, 2021
5267334
livepatch/core: Split livepatch consistency
May 29, 2021
3627ca4
livepatch/core: Supprt load and unload hooks
May 29, 2021
5fab5bb
livepatch/core: Support jump_label
May 29, 2021
607e697
livepatch/arm64: Support livepatch without ftrace
May 29, 2021
bb2fb61
livepatch/arm64: Fix func size less than limit
May 29, 2021
6b8b573
livepatch/arm64: Fix current backtracking in klp_check_calltrace
May 29, 2021
edb391b
livepatch/arm64: check active func in consistency stack checking
May 29, 2021
0ec4bd6
livepatch/core: Add livepatch consistency depends
May 29, 2021
889355b
arm/module: Use plt section indices for relocations
May 29, 2021
88b2c07
livepatch/core: Add support for arm for klp relocation
May 29, 2021
9e359f7
livepatch/arm: Support livepatch without ftrace
libin2015 May 29, 2021
62cbf70
livepatch/arm: Fix current backtracking in klp_check_calltrace
May 29, 2021
d0cabc3
livepatch/arm: Add support for livepatch plt
May 29, 2021
a86eca7
livepatch/arm: Check active func in consistency stack checking
May 29, 2021
12474d8
livepatch/core: Revert module_enable_ro and module_disable_ro
May 29, 2021
8958ee7
livepatch/x86: support livepatch without ftrace
May 29, 2021
ee6ddb6
livepatch/x86: check active func in consistency stack checking
May 29, 2021
48a998d
livepatch/ppc32: Support livepatch without ftrace
libin2015 May 29, 2021
1e1277a
livepatch/ppc32: Add support for longjump
May 29, 2021
e20f0a5
livepatch/ppc32: Fix func size less than limit
May 29, 2021
ec82dac
livepatch/ppc32: Fix current backtracking in klp_check_calltrace
May 29, 2021
006790f
livepatch/ppc32: Check active func in consistency stack checking
May 29, 2021
40c32d1
livepatch/ppc32: Ignore the first frame when checking stack
shaolexi May 29, 2021
2ce1a73
livepatch/ppc64: Implement livepatch without ftrace for ppc64be
May 29, 2021
7bf8706
livepatch/ppc64: Support use func_descr for new_func
May 29, 2021
d9b284c
livepatch/ppc64: Check active func in consistency stack checking
May 29, 2021
3f714e9
livepatch/ppc64: Implement per func_node livepatch trampoline
May 29, 2021
5ee6c47
livepatch/ppc64: Use module_alloc to alloc func_node
May 29, 2021
315f9cb
livepatch/ppc64: Make sure caller function in stack
May 29, 2021
d0e423a
livepatch/ppc64: Ignore the first frame when checking stack
shaolexi May 29, 2021
7846fcf
livepatch/ppc64: Sample testcase fix ppc64
May 29, 2021
f8e6bcd
livepatch/ppc64: Enable livepatch without ftrace
May 29, 2021
520deb6
livepatch/core: Support function force patched/unpatched
May 29, 2021
e8ef67e
livepatch: put memory alloc and free out stop machine
May 31, 2021
2501cec
livepatch: fix unload hook could not be excuted
Jun 23, 2021
a4ab930
livepatch: Add state describe for force
Oct 19, 2021
e4f028c
livepatch: checks only if the replaced instruction is on the stack
Oct 19, 2021
108cf88
livepatch/arm64: only check stack top
Oct 19, 2021
1e9df51
livepatch/arm: only check stack top
Oct 19, 2021
ff00659
livepatch/ppc32: only check stack top
Oct 19, 2021
38aa662
livepatch/ppc64: only check stack top
Oct 19, 2021
5fef18a
livepatch/x86: only check stack top
Oct 19, 2021
fbcdf89
livepatch: move arch_klp_mem_recycle after the return value judgment
Oct 19, 2021
4321455
livepatch: Fix compile warnning
Oct 19, 2021
32b0d02
livepatch: Add klp_{register,unregister}_patch for stop_machine model
Oct 19, 2021
96b009e
livepatch: Adapt livepatch-sample for stop_machine model
Oct 19, 2021
de27655
livepatch: Check whole stack when CONFIG_PREEMPT is set
Nov 15, 2021
cc1ffe4
livepatch: Fix crash when access the global variable in hook
Nov 26, 2021
048eaa3
livepatch/arm: fix incorrect stack detection
Nov 30, 2021
a59ce34
altra: enable CONFIG_LIVEPATCH
bobolmw Jan 24, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
livepatch/arm: Check active func in consistency stack checking
hulk inclusion
category: bugfix
bugzilla: 51923
CVE: NA

---------------------------

When doing consistency stack checking, if we try to patch a function
which has been patched already. We should check the new function(not
the origin func) that is activeness currently, it's always the first
entry in list func_node->func_stack.

Example :
	module : origin			livepatch v1		livepatch v2
	func   : old func A -[enable]=> new func A' -[enable]=> new func A''
	check  :                A			A'

when we try to patch function A to new function A'' by livepatch v2,
but the func A has already patched to function A' by livepatch v1, so
function A' which provided in livepatch v1 is active in the stack
instead of origin function A. Even if the long jump method is used, we
jump to the new function A' using a call without LR, the origin function
A will not appear in the stack. We must check the active function A' in
consistency stack checking.

Signed-off-by: Cheng Jian <cj.chengjian@huawei.com>
Reviewed-By: Xie XiuQi <xiexiuqi@huawei.com>
Signed-off-by: yangerkun <yangerkun@huawei.com>

Signed-off-by: Dong Kai <dongkai11@huawei.com>

Signed-off-by: Ye Weihua <yeweihua4@huawei.com>
Reviewed-by: Yang Jihong <yangjihong1@huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
  • Loading branch information
Cheng Jian authored and bobolmw committed Jan 16, 2022
commit a86eca7e99e62542da690937015aa1924f23beae
103 changes: 66 additions & 37 deletions arch/arm/kernel/livepatch.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,41 @@
#include <asm/insn.h>
#include <asm/patch.h>

#ifdef CONFIG_ARM_MODULE_PLTS
#define LJMP_INSN_SIZE 3
#endif

#ifdef ARM_INSN_SIZE
#error "ARM_INSN_SIZE have been redefined, please check"
#else
#define ARM_INSN_SIZE 4
#endif

struct klp_func_node {
struct list_head node;
struct list_head func_stack;
void *old_func;
#ifdef CONFIG_ARM_MODULE_PLTS
u32 old_insns[LJMP_INSN_SIZE];
#else
u32 old_insn;
#endif
};

static LIST_HEAD(klp_func_list);

static struct klp_func_node *klp_find_func_node(void *old_func)
{
struct klp_func_node *func_node;

list_for_each_entry(func_node, &klp_func_list, node) {
if (func_node->old_func == old_func)
return func_node;
}

return NULL;
}

#ifdef CONFIG_LIVEPATCH_STOP_MACHINE_CONSISTENCY
struct walk_stackframe_args {
struct klp_patch *patch;
Expand All @@ -53,6 +88,7 @@ static int klp_check_activeness_func(struct stackframe *frame, void *data)
struct walk_stackframe_args *args = data;
struct klp_patch *patch = args->patch;
struct klp_object *obj;
struct klp_func_node *func_node;
struct klp_func *func;
unsigned long func_addr, func_size;
const char *func_name;
Expand All @@ -63,9 +99,37 @@ static int klp_check_activeness_func(struct stackframe *frame, void *data)
for (obj = patch->objs; obj->funcs; obj++) {
for (func = obj->funcs; func->old_name; func++) {
if (args->enable) {
func_addr = (unsigned long)func->old_func;
func_size = func->old_size;
/*
* When enable, checking the currently
* active functions.
*/
func_node = klp_find_func_node(func->old_func);
if (!func_node ||
list_empty(&func_node->func_stack)) {
/*
* No patched on this function
* [ the origin one ]
*/
func_addr = (unsigned long)func->old_func;
func_size = func->old_size;
} else {
/*
* Previously patched function
* [ the active one ]
*/
struct klp_func *prev;

prev = list_first_or_null_rcu(
&func_node->func_stack,
struct klp_func, stack_node);
func_addr = (unsigned long)prev->new_func;
func_size = prev->new_size;
}
} else {
/*
* When disable, check for the function itself
* which to be unpatched.
*/
func_addr = (unsigned long)func->new_func;
func_size = func->new_size;
}
Expand Down Expand Up @@ -130,41 +194,6 @@ int klp_check_calltrace(struct klp_patch *patch, int enable)
}
#endif

#ifdef CONFIG_ARM_MODULE_PLTS
#define LJMP_INSN_SIZE 3
#endif

#ifdef ARM_INSN_SIZE
#error "ARM_INSN_SIZE have been redefined, please check"
#else
#define ARM_INSN_SIZE 4
#endif

struct klp_func_node {
struct list_head node;
struct list_head func_stack;
void *old_func;
#ifdef CONFIG_ARM_MODULE_PLTS
u32 old_insns[LJMP_INSN_SIZE];
#else
u32 old_insn;
#endif
};

static LIST_HEAD(klp_func_list);

static struct klp_func_node *klp_find_func_node(void *old_func)
{
struct klp_func_node *func_node;

list_for_each_entry(func_node, &klp_func_list, node) {
if (func_node->old_func == old_func)
return func_node;
}

return NULL;
}

static inline bool offset_in_range(unsigned long pc, unsigned long addr,
long range)
{
Expand Down