Commit c33e4283 authored by Cheng Jian's avatar Cheng Jian Committed by Zheng Zengkai
Browse files

livepatch/core: Allow implementation without ftrace



euler inclusion
category: feature
bugzilla: 51921
CVE: NA

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

support for livepatch without ftrace mode

new config for WO_FTRACE
	CONFIG_LIVEPATCH_WO_FTRACE=y
	CONFIG_LIVEPATCH_STACK=y

Implements livepatch without ftrace by direct jump, we
directly modify the first few instructions(usually one,
but four for long jumps under ARM64) of the old function
as jump instructions by stop_machine, so it will jump to
the first address of the new function when livepatch enable

KERNEL/MODULE
call/bl A---------------old_A------------
                        | jump new_A----+--------|
                        |               |        |
                        |               |        |
                        -----------------        |
                                                 |
                                                 |
                                                 |
livepatch_module-------------                    |
|                           |                    |
|new_A <--------------------+--------------------|
|                           |
|                           |
|---------------------------|
| .plt                      |
| ......PLTS for livepatch  |
-----------------------------

something we need to consider under different architectures:

1. jump instruction
2. partial relocation in new function requires for livepatch.
3. long jumps may be required if the jump address exceeds the
   offset. both for livepatch relocation and livepatch enable.

Signed-off-by: default avatarCheng Jian <cj.chengjian@huawei.com>
Reviewed-by: default avatarLi Bin <huawei.libin@huawei.com>
Signed-off-by: default avatarYang Yingliang <yangyingliang@huawei.com>

Signed-off-by: default avatarWang ShaoBo <bobo.shaobowang@huawei.com>
Signed-off-by: default avatarDong Kai <dongkai11@huawei.com>

Signed-off-by: default avatarYe Weihua <yeweihua4@huawei.com>
Reviewed-by: default avatarYang Jihong <yangjihong1@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parent 81aafb2b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -219,7 +219,7 @@ config PPC
	select HAVE_KPROBES_ON_FTRACE
	select HAVE_KRETPROBES
	select HAVE_LD_DEAD_CODE_DATA_ELIMINATION
	select HAVE_LIVEPATCH			if HAVE_DYNAMIC_FTRACE_WITH_REGS
	select HAVE_LIVEPATCH_FTRACE		if HAVE_DYNAMIC_FTRACE_WITH_REGS
	select HAVE_MOD_ARCH_SPECIFIC
	select HAVE_NMI				if PERF_EVENTS || (PPC64 && PPC_BOOK3S)
	select HAVE_HARDLOCKUP_DETECTOR_ARCH	if PPC64 && PPC_BOOK3S && SMP
+1 −1
Original line number Diff line number Diff line
@@ -165,7 +165,7 @@ config S390
	select HAVE_KPROBES_ON_FTRACE
	select HAVE_KRETPROBES
	select HAVE_KVM
	select HAVE_LIVEPATCH
	select HAVE_LIVEPATCH_FTRACE
	select HAVE_PERF_REGS
	select HAVE_PERF_USER_STACK_DUMP
	select HAVE_MEMBLOCK_PHYS_MAP
+1 −1
Original line number Diff line number Diff line
@@ -198,7 +198,7 @@ config X86
	select HAVE_FUNCTION_ERROR_INJECTION
	select HAVE_KRETPROBES
	select HAVE_KVM
	select HAVE_LIVEPATCH			if X86_64
	select HAVE_LIVEPATCH_FTRACE		if X86_64
	select HAVE_MIXED_BREAKPOINTS_REGS
	select HAVE_MOD_ARCH_SPECIFIC
	select HAVE_MOVE_PMD
+22 −4
Original line number Diff line number Diff line
@@ -75,7 +75,9 @@ struct klp_func {
	unsigned long old_size, new_size;
	bool nop;
	bool patched;
#ifdef CONFIG_LIVEPATCH_FTRACE
	bool transition;
#endif
};

struct klp_object;
@@ -195,6 +197,12 @@ struct klp_patch {

int klp_enable_patch(struct klp_patch *);

int klp_apply_section_relocs(struct module *pmod, Elf_Shdr *sechdrs,
			     const char *shstrtab, const char *strtab,
			     unsigned int symindex, unsigned int secindex,
			     const char *objname);

#ifdef CONFIG_LIVEPATCH_FTRACE
/* Called from the module loader during module coming/going states */
int klp_module_coming(struct module *mod);
void klp_module_going(struct module *mod);
@@ -231,10 +239,20 @@ void klp_shadow_free_all(unsigned long id, klp_shadow_dtor_t dtor);
struct klp_state *klp_get_state(struct klp_patch *patch, unsigned long id);
struct klp_state *klp_get_prev_state(unsigned long id);

int klp_apply_section_relocs(struct module *pmod, Elf_Shdr *sechdrs,
			     const char *shstrtab, const char *strtab,
			     unsigned int symindex, unsigned int secindex,
			     const char *objname);
#else /* !CONFIG_LIVEPATCH_FTRACE */

static inline int klp_module_coming(struct module *mod) { return 0; }
static inline void klp_module_going(struct module *mod) {}
static inline bool klp_patch_pending(struct task_struct *task) { return false; }
static inline void klp_update_patch_state(struct task_struct *task) {}
static inline void klp_copy_process(struct task_struct *child) {}
static inline bool klp_have_reliable_stack(void) { return true; }

#ifndef klp_smp_isb
#define klp_smp_isb()
#endif

#endif /* CONFIG_LIVEPATCH_FTRACE */

#else /* !CONFIG_LIVEPATCH */

+45 −4
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0-only
config HAVE_LIVEPATCH
config HAVE_LIVEPATCH_FTRACE
	bool
	help
	  Arch supports kernel live patching
	  Arch supports kernel live patching based on ftrace

config HAVE_LIVEPATCH_WO_FTRACE
	bool
	help
	  Arch supports kernel live patching without ftrace

if HAVE_LIVEPATCH_FTRACE || HAVE_LIVEPATCH_WO_FTRACE
menu "Enable Livepatch"


config LIVEPATCH
	bool "Kernel Live Patching"
	depends on DYNAMIC_FTRACE_WITH_REGS
	depends on MODULES
	depends on SYSFS
	depends on KALLSYMS_ALL
	depends on HAVE_LIVEPATCH
	depends on HAVE_LIVEPATCH_FTRACE || HAVE_LIVEPATCH_WO_FTRACE
	depends on !TRIM_UNUSED_KSYMS
	depends on DEBUG_INFO
	default n
	help
	  Say Y here if you want to support kernel live patching.
	  This option has no runtime impact until a kernel "patch"
	  module uses the interface provided by this option to register
	  a patch, causing calls to patched functions to be redirected
	  to new function code contained in the patch module.

choice
	prompt "live patching method"
	depends on LIVEPATCH
	help
	  Live patching implementation method configuration.

config LIVEPATCH_FTRACE
	bool "based on ftrace"
	depends on HAVE_LIVEPATCH_FTRACE
	depends on DYNAMIC_FTRACE_WITH_REGS
	help
	  Supports kernel live patching based on ftrace

config LIVEPATCH_WO_FTRACE
	bool "without ftrace"
	depends on HAVE_LIVEPATCH_WO_FTRACE
	help
	  Supports kernel live patching without ftrace

endchoice

config LIVEPATCH_STACK
	bool "Enforcing the patch stacking principle"
	depends on LIVEPATCH_FTRACE || LIVEPATCH_WO_FTRACE
	default y
	help
	  Say N here if you want to remove the patch stacking principle.

endmenu
endif
Loading